diff --git a/oldStyle/GetLatest/GetLatestVimScripts.dat b/oldStyle/GetLatest/GetLatestVimScripts.dat deleted file mode 100644 index 913b995..0000000 --- a/oldStyle/GetLatest/GetLatestVimScripts.dat +++ /dev/null @@ -1,12 +0,0 @@ -ScriptID SourceID Filename --------------------------- -910 18164 :AutoInstall: pydoc.vim -2771 16279 :AutoInstall: conque_term.vim -294 19633 :AutoInstall: Align.vim -1066 7618 :AutoInstall: cecutil.vim -642 15781 :AutoInstall: getscript.vim -2324 9247 :AutoInstall: TextFormat -1658 17123 :AutoInstall: NERD_tree.vim -1218 14455 :AutoInstall: NERD_commenter.vim -90 19809 :AutoInstall: vcscommand.vim -2896 11941 :AutoInstall: open_terminal.vim diff --git a/oldStyle/GetLatest/GetLatestVimScripts.dist b/oldStyle/GetLatest/GetLatestVimScripts.dist deleted file mode 100644 index 4745fc8..0000000 --- a/oldStyle/GetLatest/GetLatestVimScripts.dist +++ /dev/null @@ -1,18 +0,0 @@ -ScriptID SourceID Filename --------------------------- -294 1 Align.vim -302 2 AnsiEsc.vim -122 3 astronaut.vim -104 4 blockhl.vim -120 5 decho.vim - 40 6 DrawIt.tar.gz -451 7 EasyAccents.vim -195 8 engspchk.vim -642 9 GetLatestVimScripts.vim -489 10 Manpageview.vim -551 11 Mines.vim -514 12 mrswin.vim -670 13 visincr.vim -628 14 SeeTab.vim -508 15 ZoomWin.vim -877 16 gvcolor.vim diff --git a/oldStyle/disabled_plugins/Align.vim b/oldStyle/disabled_plugins/Align.vim deleted file mode 100644 index 714421e..0000000 --- a/oldStyle/disabled_plugins/Align.vim +++ /dev/null @@ -1,1140 +0,0 @@ -" Align: tool to align multiple fields based on one or more separators -" Author: Charles E. Campbell -" Date: Mar 12, 2013 -" Version: 37 -" GetLatestVimScripts: 294 1 :AutoInstall: Align.vim -" GetLatestVimScripts: 1066 1 :AutoInstall: cecutil.vim -" Copyright: Copyright (C) 1999-2012 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, -" Align.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. -" -" Romans 1:16,17a : For I am not ashamed of the gospel of Christ, for it is {{{1 -" the power of God for salvation for everyone who believes; for the Jew first, -" and also for the Greek. For in it is revealed God's righteousness from -" faith to faith. -"redraw!|call DechoSep()|call inputsave()|call input("Press to continue")|call inputrestore() - -" --------------------------------------------------------------------- -" Load Once: {{{1 -if exists("g:loaded_Align") || &cp - finish -endif -let g:loaded_Align = "v37" -if v:version < 700 - echohl WarningMsg - echo "***warning*** this version of Align needs vim 7.0" - echohl Normal - finish -endif -let s:keepcpo= &cpo -set cpo&vim -"DechoTabOn - -" --------------------------------------------------------------------- -" Debugging Support: {{{1 -"if !exists("g:loaded_Decho") | runtime plugin/Decho.vim | endif - -" --------------------------------------------------------------------- -" Options: {{{1 -if !exists("g:Align_xstrlen") - if exists("g:drawit_xstrlen") - let g:Align_xstrlen= g:drawit_xstrlen - elseif exists("g:netrw_xstrlen") - let g:Align_xstrlen= g:netrw_xstrlen - elseif &enc == "latin1" || !has("multi_byte") - let g:Align_xstrlen= 0 - else - let g:Align_xstrlen= 1 - endif -endif - -" --------------------------------------------------------------------- -" Align#AlignCtrl: enter alignment patterns here {{{1 -" -" Styles = all alignment-break patterns are equivalent -" C cycle through alignment-break pattern(s) -" l left-justified alignment -" r right-justified alignment -" c center alignment -" - skip separator, treat as part of field -" : treat rest of line as field -" + repeat previous [lrc] style -" < left justify separators -" > right justify separators -" | center separators -" -" Builds = s:AlignPat s:AlignCtrl s:AlignPatQty -" C s:AlignPat s:AlignCtrl s:AlignPatQty -" p s:AlignPrePad -" P s:AlignPostPad -" w s:AlignLeadKeep -" W s:AlignLeadKeep -" I s:AlignLeadKeep -" l s:AlignStyle -" r s:AlignStyle -" - s:AlignStyle -" + s:AlignStyle -" : s:AlignStyle -" c s:AlignStyle -" g s:AlignGPat -" v s:AlignVPat -" < s:AlignSep -" > s:AlignSep -" | s:AlignSep -fun! Align#AlignCtrl(...) - -" call Dfunc("Align#AlignCtrl(...) a:0=".a:0) - - " save options that may be changed later - call s:SaveUserOptions() - - " turn ignorecase off - setlocal noic - - " clear visual mode so that old visual-mode selections don't - " get applied to new invocations of Align(). - if v:version < 602 - if !exists("s:Align_gavemsg") - let s:Align_gavemsg= 1 - echomsg "Align needs at least Vim version 6.2 to clear visual-mode selection" - endif - elseif exists("s:dovisclear") -" call Decho("clearing visual mode a:0=".a:0." a:1<".a:1.">") - let clearvmode= visualmode(1) - endif - - " set up a list akin to an argument list - if a:0 > 0 - let A= s:QArgSplitter(a:1) - else - let A=[0] - endif - - if A[0] > 0 - let style = A[1] - - " Check for bad separator patterns (zero-length matches) - " (but zero-length patterns for g/v is ok) - if style !~# '[gv]' - let ipat= 2 - while ipat <= A[0] - if "" =~ A[ipat] - echoerr "(AlignCtrl) separator<".A[ipat]."> matches zero-length string" - call s:RestoreUserOptions() -" call Dret("Align#AlignCtrl") - return - endif - let ipat= ipat + 1 - endwhile - endif - endif -" call Decho("(AlignCtrl) passed bad-separator pattern check (no zero-length matches)") - -" call Decho("(AlignCtrl) A[0]=".A[0]) - if !exists("s:AlignStyle") - let s:AlignStyle= 'l' - endif - if !exists("s:AlignPrePad") - let s:AlignPrePad= 0 - endif - if !exists("s:AlignPostPad") - let s:AlignPostPad= 0 - endif - if !exists("s:AlignLeadKeep") - let s:AlignLeadKeep= 'w' - endif - - if A[0] == 0 - " ---------------------- - " List current selection - " ---------------------- - if !exists("s:AlignPatQty") - let s:AlignPatQty= 0 - endif - echo "AlignCtrl<".s:AlignCtrl."> qty=".s:AlignPatQty." AlignStyle<".s:AlignStyle."> Padding<".s:AlignPrePad."|".s:AlignPostPad."> LeadingWS=".s:AlignLeadKeep." AlignSep=".s:AlignSep -" call Decho("(AlignCtrl) AlignCtrl<".s:AlignCtrl."> qty=".s:AlignPatQty." AlignStyle<".s:AlignStyle."> Padding<".s:AlignPrePad."|".s:AlignPostPad."> LeadingWS=".s:AlignLeadKeep." AlignSep=".s:AlignSep) - if exists("s:AlignGPat") && !exists("s:AlignVPat") - echo "AlignGPat<".s:AlignGPat.">" - elseif !exists("s:AlignGPat") && exists("s:AlignVPat") - echo "AlignVPat<".s:AlignVPat.">" - elseif exists("s:AlignGPat") && exists("s:AlignVPat") - echo "AlignGPat<".s:AlignGPat."> AlignVPat<".s:AlignVPat.">" - endif - let ipat= 1 - while ipat <= s:AlignPatQty - echo "Pat".ipat."<".s:AlignPat_{ipat}.">" -" call Decho("(AlignCtrl) Pat".ipat."<".s:AlignPat_{ipat}.">") - let ipat= ipat + 1 - endwhile - - else - " ---------------------------------- - " Process alignment control settings - " ---------------------------------- -" call Decho("process the alignctrl settings") -" call Decho("style<".style.">") - - if style ==? "default" - " Default: preserve initial leading whitespace, left-justified, - " alignment on '=', one space padding on both sides - if exists("s:AlignCtrlStackQty") - " clear AlignCtrl stack - while s:AlignCtrlStackQty > 0 - call Align#AlignPop() - endwhile - unlet s:AlignCtrlStackQty - endif - " Set AlignCtrl to its default value - call Align#AlignCtrl("Ilp1P1=<",'=') - call Align#AlignCtrl("g") - call Align#AlignCtrl("v") - let s:dovisclear = 1 - call s:RestoreUserOptions() -" call Dret("Align#AlignCtrl") - return - endif - - if style =~# 'm' - " map support: Do an AlignPush now and the next call to Align() - " will do an AlignPop at exit -" call Decho("style case m: do AlignPush") - call Align#AlignPush() - let s:DoAlignPop= 1 - endif - - " = : record a list of alignment patterns that are equivalent - if style =~# "=" || (A[0] >= 2 && style !~# "C" && s:AlignCtrl =~# '=') -" call Decho("style case =: record list of equiv alignment patterns") - let s:AlignCtrl = '=' - if A[0] >= 2 - let s:AlignPatQty= 1 - let s:AlignPat_1 = A[2] - let ipat = 3 - while ipat <= A[0] - let s:AlignPat_1 = s:AlignPat_1.'\|'.A[ipat] - let ipat = ipat + 1 - endwhile - let s:AlignPat_1= '\('.s:AlignPat_1.'\)' -" call Decho("AlignCtrl<".s:AlignCtrl."> AlignPat<".s:AlignPat_1.">") - endif - - "c : cycle through alignment pattern(s) - elseif style =~# 'C' || (A[0] >= 2 && s:AlignCtrl =~# '=') -" call Decho("style case C: cycle through alignment pattern(s)") - let s:AlignCtrl = 'C' - if A[0] >= 2 - let s:AlignPatQty= A[0] - 1 - let ipat = 1 - while ipat < A[0] - let s:AlignPat_{ipat}= A[ipat+1] -" call Decho("AlignCtrl<".s:AlignCtrl."> AlignQty=".s:AlignPatQty." AlignPat_".ipat."<".s:AlignPat_{ipat}.">") - let ipat= ipat + 1 - endwhile - endif - endif - - if style =~# 'p' - let s:AlignPrePad= substitute(style,'^.*p\(\d\+\).*$','\1','') -" call Decho("style case p".s:AlignPrePad.": pre-separator padding") - if s:AlignPrePad == "" - echoerr "(AlignCtrl) 'p' needs to be followed by a numeric argument'" - call s:RestoreUserOptions() -" call Dret("Align#AlignCtrl") - return - endif - endif - - if style =~# 'P' - let s:AlignPostPad= substitute(style,'^.*P\(\d\+\).*$','\1','') -" call Decho("style case P".s:AlignPostPad.": post-separator padding") - if s:AlignPostPad == "" - echoerr "(AlignCtrl) 'P' needs to be followed by a numeric argument'" - call s:RestoreUserOptions() -" call Dret("Align#AlignCtrl") - return - endif - endif - - if style =~# 'w' -" call Decho("style case w: ignore leading whitespace") - let s:AlignLeadKeep= 'w' - elseif style =~# 'W' -" call Decho("style case W: keep leading whitespace") - let s:AlignLeadKeep= 'W' - elseif style =~# 'I' -" call Decho("style case I: retain initial leading whitespace") - let s:AlignLeadKeep= 'I' - endif - - if style =~# 'g' - " first list item is a "g" selector pattern -" call Decho("style case g: global selector pattern") - if A[0] < 2 - if exists("s:AlignVPat") - unlet s:AlignVPat -" call Decho("unlet s:AlignGPat") - endif - else - let s:AlignGPat= A[2] -" call Decho("s:AlignGPat<".s:AlignGPat.">") - endif - elseif style =~# 'v' - " first list item is a "v" selector pattern -" call Decho("style case v: global selector anti-pattern") - if A[0] < 2 - if exists("s:AlignGPat") - unlet s:AlignGPat -" call Decho("unlet s:AlignVPat") - endif - else - let s:AlignVPat= A[2] -" call Decho("s:AlignVPat<".s:AlignVPat.">") - endif - endif - - "[-lrc+:] : set up s:AlignStyle - if style =~# '[-lrc+:*]' -" call Decho("style case [-lrc+:]: field justification") - let s:AlignStyle= substitute(style,'[^-lrc:+*]','','g') -" call Decho("AlignStyle<".s:AlignStyle.">") - endif - - "[<>|] : set up s:AlignSep - if style =~# '[<>|]' -" call Decho("style case [-lrc+:]: separator justification") - let s:AlignSep= substitute(style,'[^<>|]','','g') -" call Decho("AlignSep ".s:AlignSep) - endif - endif - - " sanity - if !exists("s:AlignCtrl") - let s:AlignCtrl= '=' - endif - - " restore options and return - call s:RestoreUserOptions() -" call Dret("Align#AlignCtrl ".s:AlignCtrl.'p'.s:AlignPrePad.'P'.s:AlignPostPad.s:AlignLeadKeep.s:AlignStyle) - return s:AlignCtrl.'p'.s:AlignPrePad.'P'.s:AlignPostPad.s:AlignLeadKeep.s:AlignStyle -endfun - -" --------------------------------------------------------------------- -" s:MakeSpace: returns a string with spacecnt blanks {{{1 -fun! s:MakeSpace(spacecnt) -" call Dfunc("MakeSpace(spacecnt=".a:spacecnt.")") - let str = "" - let spacecnt = a:spacecnt - while spacecnt > 0 - let str = str . " " - let spacecnt = spacecnt - 1 - endwhile -" call Dret("MakeSpace <".str.">") - return str -endfun - -" --------------------------------------------------------------------- -" Align#Align: align selected text based on alignment pattern(s) {{{1 -fun! Align#Align(hasctrl,...) range -" call Dfunc("Align#Align(hasctrl=".a:hasctrl.",...) a:0=".a:0) - - " sanity checks - if string(a:hasctrl) != "0" && string(a:hasctrl) != "1" - echohl Error|echo 'usage: Align#Align(hasctrl<'.a:hasctrl.'> (should be 0 or 1),"separator(s)" (you have '.a:0.') )'|echohl None -" call Dret("Align#Align") - return - endif - if exists("s:AlignStyle") && s:AlignStyle == ":" - echohl Error |echo '(Align#Align) your AlignStyle is ":", which implies "do-no-alignment"!'|echohl None -" call Dret("Align#Align") - return - endif - - " save user options - call s:SaveUserOptions() - - " set up a list akin to an argument list - if a:0 > 0 - let A= s:QArgSplitter(a:1) - else - let A=[0] - endif - - " if :Align! was used, then the first argument is (should be!) an AlignCtrl string - " Note that any alignment control set this way will be temporary. - let hasctrl= a:hasctrl -" call Decho("hasctrl=".hasctrl) - if a:hasctrl && A[0] >= 1 -" call Decho("Align! : using A[1]<".A[1]."> for AlignCtrl") - if A[1] =~ '[gv]' - let hasctrl= hasctrl + 1 - call Align#AlignCtrl('m') - call Align#AlignCtrl(A[1],A[2]) -" call Decho("Align! : also using A[2]<".A[2]."> for AlignCtrl") - elseif A[1] !~ 'm' - call Align#AlignCtrl(A[1]."m") - else - call Align#AlignCtrl(A[1]) - endif - endif - - " Check for bad separator patterns (zero-length matches) - let ipat= 1 + hasctrl - while ipat <= A[0] - if "" =~ A[ipat] - echoerr "(Align) separator<".A[ipat]."> matches zero-length string" - call s:RestoreUserOptions() -" call Dret("Align#Align") - return - endif - let ipat= ipat + 1 - endwhile - - " record current search pattern for subsequent restoration - " (these are all global-only options) - set noic report=10000 nohls - - if A[0] > hasctrl - " Align will accept a list of separator regexps -" call Decho("A[0]=".A[0].": accepting list of separator regexp") - - if s:AlignCtrl =~# "=" - "= : consider all separators to be equivalent -" call Decho("AlignCtrl: record list of equivalent alignment patterns") - let s:AlignCtrl = '=' - let s:AlignPat_1 = A[1 + hasctrl] - let s:AlignPatQty= 1 - let ipat = 2 + hasctrl - while ipat <= A[0] - let s:AlignPat_1 = s:AlignPat_1.'\|'.A[ipat] - let ipat = ipat + 1 - endwhile - let s:AlignPat_1= '\('.s:AlignPat_1.'\)' -" call Decho("AlignCtrl<".s:AlignCtrl."> AlignPat<".s:AlignPat_1.">") - - elseif s:AlignCtrl =~# 'C' - "c : cycle through alignment pattern(s) -" call Decho("AlignCtrl: cycle through alignment pattern(s)") - let s:AlignCtrl = 'C' - let s:AlignPatQty= A[0] - hasctrl - let ipat = 1 - while ipat <= s:AlignPatQty - let s:AlignPat_{ipat}= A[(ipat + hasctrl)] -" call Decho("AlignCtrl<".s:AlignCtrl."> AlignQty=".s:AlignPatQty." AlignPat_".ipat."<".s:AlignPat_{ipat}.">") - let ipat= ipat + 1 - endwhile - endif - endif - - " Initialize so that begline - " is greater than the line's string length -> ragged right. - " Have to be careful about visualmode() -- it returns the last visual - " mode used whether or not it was used currently. - let begcol = virtcol("'<")-1 - let endcol = virtcol("'>")-1 - if begcol > endcol - let begcol = virtcol("'>")-1 - let endcol = virtcol("'<")-1 - endif -" call Decho("begcol=".begcol." endcol=".endcol) - let begline = a:firstline - let endline = a:lastline - if begline > endline - let begline = a:lastline - let endline = a:firstline - endif - - " Expand range to cover align-able lines when the given range is only the current line. - " Look for the first line above the current line that matches the first separator pattern, and - " look for the last line below the current line that matches the first separator pattern. - if begline == endline -" call Decho("case begline == endline") - if !exists("s:AlignPat_{1}") - echohl Error|echo "(Align) no separators specified!"|echohl None - call s:RestoreUserOptions() -" call Dret("Align#Align") - return - endif - let seppat = s:AlignPat_{1} - let begline= search('^\%(\%('.seppat.'\)\@!.\)*$',"bnW") - if begline == 0|let begline= 1|else|let begline= begline + 1|endif - let endline= search('^\%(\%('.seppat.'\)\@!.\)*$',"nW") - if endline == 0|let endline= line("$")|else|let endline= endline - 1|endif -" call Decho("begline=".begline." endline=".endline." curline#".line(".")) - endif -" call Decho("begline=".begline." endline=".endline) - let fieldcnt = 0 - if (begline == line("'>") && endline == line("'<")) || (begline == line("'<") && endline == line("'>")) - let vmode= visualmode() -" call Decho("vmode=".vmode) - if vmode == "\" - let ragged = ( col("'>") > s:Strlen(getline("'>")) || col("'<") > s:Strlen(getline("'<")) ) - else - let ragged= 1 - endif - else - let ragged= 1 - endif - if ragged - let begcol= 0 - endif -" call Decho("lines[".begline.",".endline."] col[".begcol.",".endcol."] ragged=".ragged." AlignCtrl<".s:AlignCtrl.">") - - " record initial whitespace - if s:AlignLeadKeep == 'W' - let wskeep = map(getline(begline,endline),"substitute(v:val,'^\\(\\s*\\).\\{-}$','\\1','')") - endif - - " Align needs these options - setl et - set paste - - " convert selected range of lines to use spaces instead of tabs - " but if first line's initial white spaces are to be retained - " then use 'em - if begcol <= 0 && s:AlignLeadKeep == 'I' - " retain first leading whitespace for all subsequent lines - let bgntxt= substitute(getline(begline),'^\(\s*\).\{-}$','\1','') - - " exception: retain first leading whitespace predicated on g and v patterns - " if such a selected line exists - if exists("s:AlignGPat") - let firstgline= search(s:AlignGPat,"cnW",endline) - if firstgline > 0 - let bgntxt= substitute(getline(firstgline),'^\(\s*\).\{-}$','\1','') - endif - elseif exists("s:AlignVPat") - let firstvline= search(s:AlignVPat,"cnW",endline) - if firstvline > 0 - let bgntxt= substitute('^\%(\%('.getline(firstvline).')\@!\)*$','^\(\s*\).\{-}$','\1','') - endif - endif -" call Decho("retaining 1st leading whitespace: bgntxt<".bgntxt.">") - let &l:et= s:keep_et - endif - exe begline.",".endline."ret" - - " record transformed to spaces leading whitespace - if s:AlignLeadKeep == 'W' - let wsblanks = map(getline(begline,endline),"substitute(v:val,'^\\(\\s*\\).\\{-}$','\\1','')") - endif - - " Execute two passes - " First pass: collect alignment data (max field sizes) - " Second pass: perform alignment - let pass= 1 - while pass <= 2 -" call Decho(" ") -" call Decho("---- Pass ".pass.": ----") - - let curline= begline - while curline <= endline - " Process each line - let txt = getline(curline) -" call Decho(" ") -" call Decho("Pass".pass.": Line ".curline." <".txt.">") - - " AlignGPat support: allows a selector pattern (akin to g/selector/cmd ) - if exists("s:AlignGPat") -" call Decho("Pass".pass.": AlignGPat<".s:AlignGPat.">") - if match(txt,s:AlignGPat) == -1 -" call Decho("Pass".pass.": skipping") - let curline= curline + 1 - continue - endif - endif - - " AlignVPat support: allows a selector pattern (akin to v/selector/cmd ) - if exists("s:AlignVPat") -" call Decho("Pass".pass.": AlignVPat<".s:AlignVPat.">") - if match(txt,s:AlignVPat) != -1 -" call Decho("Pass".pass.": skipping") - let curline= curline + 1 - continue - endif - endif - - " Always skip blank lines - if match(txt,'^\s*$') != -1 -" call Decho("Pass".pass.": skipping") - let curline= curline + 1 - continue - endif - - " Extract visual-block selected text (init bgntxt, endtxt) - let txtlen= s:Strlen(txt) - if begcol > 0 - " Record text to left of selected area - let bgntxt= strpart(txt,0,begcol) -" call Decho("Pass".pass.": record text to left: bgntxt<".bgntxt.">") - elseif s:AlignLeadKeep == 'W' - let bgntxt= substitute(txt,'^\(\s*\).\{-}$','\1','') -" call Decho("Pass".pass.": retaining all leading ws: bgntxt<".bgntxt.">") - elseif s:AlignLeadKeep == 'w' || !exists("bgntxt") - " No beginning text - let bgntxt= "" -" call Decho("Pass".pass.": no beginning text") - endif - if ragged - let endtxt= "" - else - " Elide any text lying outside selected columnar region - let endtxt= strpart(txt,endcol+1,txtlen-endcol) - let txt = strpart(txt,begcol,endcol-begcol+1) - endif -" call Decho(" ") -" call Decho("Pass".pass.": bgntxt<".bgntxt.">") -" call Decho("Pass".pass.": txt<". txt .">") -" call Decho("Pass".pass.": endtxt<".endtxt.">") - if !exists("s:AlignPat_{1}") - echohl Error|echo "(Align) no separators specified!"|echohl None - call s:RestoreUserOptions() -" call Dret("Align#Align") - return - endif - - " Initialize for both passes - let seppat = s:AlignPat_{1} - let ifield = 1 - let ipat = 1 - let bgnfield = 0 - let endfield = 0 - let alignstyle = s:AlignStyle - let doend = 1 - let newtxt = "" - let alignprepad = s:AlignPrePad - let alignpostpad= s:AlignPostPad - let alignsep = s:AlignSep - let alignophold = " " - let alignop = 'l' -" call Decho("Pass".pass.": initial alignstyle<".alignstyle."> seppat<".seppat.">") - - " Process each field on the line - while doend > 0 - - " C-style: cycle through pattern(s) - if s:AlignCtrl == 'C' && doend == 1 - let seppat = s:AlignPat_{ipat} -" call Decho("Pass".pass.": processing field: AlignCtrl=".s:AlignCtrl." ipat=".ipat." seppat<".seppat.">") - let ipat = ipat + 1 - if ipat > s:AlignPatQty - let ipat = 1 - endif - endif - - " cyclic alignment/justification operator handling - let alignophold = alignop - let alignop = strpart(alignstyle,0,1) - if alignop == '+' || doend == 2 - let alignop= alignophold - else - let alignstyle = strpart(alignstyle,1).strpart(alignstyle,0,1) - let alignopnxt = strpart(alignstyle,0,1) - if alignop == ':' - let seppat = '$' - let doend = 2 -" call Decho("Pass".pass.": alignop<:> case: setting seppat<$> doend==2") - endif - endif - - " cyclic separator alignment specification handling - let alignsepop= strpart(alignsep,0,1) - let alignsep = strpart(alignsep,1).alignsepop - - " ------------------------------------------------------ - " mark end-of-field and the subsequent end-of-separator. - " ------------------------------------------------------ - let endfield = match(txt,seppat,bgnfield) - let sepfield = matchend(txt,seppat,bgnfield) - let skipfield= sepfield -" call Decho("Pass".pass.": endfield=match(txt<".txt.">,seppat<".seppat.">,bgnfield=".bgnfield.")=".endfield." alignop=".alignop) - - " Mark eof: Extend field if alignop is '*' and AlignSkip() is true. - if alignop == '*' && exists("g:AlignSkip") && type(g:AlignSkip) == 2 -" call Decho("Pass".pass.": endfield=match(txt<".txt.">,seppat<".seppat.">,bgnfield=".bgnfield.")=".endfield." alignop=".alignop) - " a '*' acts like a '-' while the g:AlignSkip function reference is true except that alignop doesn't advance - while g:AlignSkip(curline,endfield) && endfield != -1 - let endfield = match(txt,seppat,skipfield) - let sepfield = matchend(txt,seppat,skipfield) - let skipfield = sepfield -" call Decho("Pass".pass.": extend field: endfield<".strpart(txt,bgnfield,endfield-bgnfield)."> alignop<".alignop."> alignstyle<".alignstyle.">") - endwhile - let alignop = strpart(alignstyle,0,1) - let alignstyle= strpart(alignstyle,1).strpart(alignstyle,0,1) -" call Decho("Pass".pass.": endfield=match(txt<".txt.">,seppat<".seppat.">,bgnfield=".bgnfield.")=".endfield." alignop=".alignop." (after *)") - endif - - " Mark eof: Extend field if alignop is '-' - while alignop == '-' && endfield != -1 - let endfield = match(txt,seppat,skipfield) - let sepfield = matchend(txt,seppat,skipfield) - let skipfield = sepfield - let alignop = strpart(alignstyle,0,1) - let alignstyle= strpart(alignstyle,1).strpart(alignstyle,0,1) -" call Decho("Pass".pass.": extend field: endfield<".strpart(txt,bgnfield,endfield-bgnfield)."> alignop<".alignop."> alignstyle<".alignstyle.">") - endwhile - let seplen= sepfield - endfield -" call Decho("Pass".pass.": seplen=[sepfield=".sepfield."] - [endfield=".endfield."]=".seplen) - - if endfield != -1 - if pass == 1 - " --------------------------------------------------------------------- - " Pass 1: Update FieldSize to max -" call Decho("Pass".pass.": before lead/trail remove: field<".strpart(txt,bgnfield,endfield-bgnfield).">") - let field = substitute(strpart(txt,bgnfield,endfield-bgnfield),'^\s*\(.\{-}\)\s*$','\1','') - if s:AlignLeadKeep == 'W' - let field = bgntxt.field - let bgntxt= "" - endif - let fieldlen= s:Strlen(field) - if !exists("FieldSize_{ifield}") - let FieldSize_{ifield}= fieldlen -" call Decho("Pass".pass.": set FieldSize_{".ifield."}=".FieldSize_{ifield}." <".field."> (init)") - elseif fieldlen > FieldSize_{ifield} - let FieldSize_{ifield}= fieldlen -" call Decho("Pass".pass.": set FieldSize_{".ifield."}=".FieldSize_{ifield}." <".field."> (fieldlen>FieldSize_".ifield.")") - endif - if !exists("SepSize_{ifield}") - let SepSize_{ifield}= seplen -" call Decho("Pass".pass.": set SepSize_{".ifield."}=".SepSize_{ifield}." <".field."> (init)") - elseif seplen > SepSize_{ifield} - let SepSize_{ifield}= seplen -" call Decho("Pass".pass.": set SepSize_{".ifield."}=".SepSize_{ifield}." <".field."> (seplen>SepSize_".ifield.")") - endif - - else - " --------------------------------------------------------------------- - " Pass 2: Perform Alignment - let prepad = strpart(alignprepad,0,1) - let postpad = strpart(alignpostpad,0,1) - let alignprepad = strpart(alignprepad,1).strpart(alignprepad,0,1) - let alignpostpad = strpart(alignpostpad,1).strpart(alignpostpad,0,1) - let field = substitute(strpart(txt,bgnfield,endfield-bgnfield),'^\s*\(.\{-}\)\s*$','\1','') -" call Decho("Pass".pass.": alignprepad <".alignprepad."> prepad =".prepad) -" call Decho("Pass".pass.": alignpostpad<".alignpostpad."> postpad=".postpad) - if s:AlignLeadKeep == 'W' - let field = bgntxt.field - let bgntxt= "" - endif - if doend == 2 - let prepad = 0 - let postpad= 0 - endif - let fieldlen = s:Strlen(field) - let sep = s:MakeSpace(prepad).strpart(txt,endfield,sepfield-endfield).s:MakeSpace(postpad) -" call Decho("Pass".pass.": sep<".sep."> (after prepad, sepfield-endfield,postpad)") - if seplen < SepSize_{ifield} - if alignsepop == "<" - " left-justify separators - let sep = sep.s:MakeSpace(SepSize_{ifield}-seplen) -" call Decho("Pass".pass.": sep<".sep."> (left-justified)") - elseif alignsepop == ">" - " right-justify separators - let sep = s:MakeSpace(SepSize_{ifield}-seplen).sep -" call Decho("Pass".pass.": sep<".sep."> (right-justified)") - else - " center-justify separators - let sepleft = (SepSize_{ifield} - seplen)/2 - let sepright = SepSize_{ifield} - seplen - sepleft - let sep = s:MakeSpace(sepleft).sep.s:MakeSpace(sepright) -" call Decho("Pass".pass.": sep<".sep."> (center-justified)") - endif - endif - let spaces = FieldSize_{ifield} - fieldlen -" call Decho("Pass".pass.": spaces=[FieldSize_".ifield."=".FieldSize_{ifield}."] - [fieldlen=".fieldlen."]=".spaces) -" call Decho("Pass".pass.": Field #".ifield."<".field."> spaces=".spaces." be[".bgnfield.",".endfield."] pad=".prepad.','.postpad." FS_".ifield."<".FieldSize_{ifield}."> sep<".sep."> ragged=".ragged." doend=".doend." alignop<".alignop.">") - - " Perform alignment according to alignment style justification - if spaces > 0 - if alignop == 'c' - " center the field - let spaceleft = spaces/2 - let spaceright= FieldSize_{ifield} - spaceleft - fieldlen - let newtxt = newtxt.s:MakeSpace(spaceleft).field.s:MakeSpace(spaceright).sep - elseif alignop == 'r' - " right justify the field - let newtxt= newtxt.s:MakeSpace(spaces).field.sep - elseif ragged && doend == 2 - " left justify rightmost field (no trailing blanks needed) - let newtxt= newtxt.field - else - " left justfiy the field - let newtxt= newtxt.field.s:MakeSpace(spaces).sep - endif - elseif ragged && doend == 2 - " field at maximum field size and no trailing blanks needed - let newtxt= newtxt.field - else - " field is at maximum field size already - let newtxt= newtxt.field.sep - endif -" call Decho("Pass".pass.": newtxt<".newtxt.">") - endif " pass 1/2 - - " bgnfield indexes to end of separator at right of current field - " Update field counter - let bgnfield= sepfield - let ifield = ifield + 1 - if doend == 2 - let doend= 0 - endif - " handle end-of-text as end-of-field - elseif doend == 1 - let seppat = '$' - let doend = 2 - else - let doend = 0 - endif " endfield != -1 - endwhile " doend loop (as well as regularly separated fields) - - if pass == 2 - " Write altered line to buffer -" call Decho("Pass".pass.": bgntxt<".bgntxt."> curline=".curline) -" call Decho("Pass".pass.": newtxt<".newtxt.">") -" call Decho("Pass".pass.": endtxt<".endtxt.">") - keepj call setline(curline,bgntxt.newtxt.endtxt) - endif -" call Decho("Pass".pass.": line#".curline."<".getline(".")."> (end-of-while)") - - let curline = curline + 1 - endwhile " curline loop - - let pass= pass + 1 - endwhile " pass loop -" call Decho("end of two pass loop") -" call Decho("ENDWHILE: cursor at (".line(".").",".col(".").") curline#".curline) - - " restore original leading whitespace - if s:AlignLeadKeep == 'W' - let iline= begline - let i = 0 -" call Decho("restore original leading whitespace") - while iline <= endline -" call Decho("exe ".iline."s/^".wsblanks[i]."/".wskeep[i]."/") - exe "keepj ".iline."s/^".wsblanks[i]."/".wskeep[i]."/" - let iline= iline + 1 - let i = i + 1 - endwhile - endif - - if exists("s:DoAlignPop") - " AlignCtrl Map support - call Align#AlignPop() - unlet s:DoAlignPop - endif - - " restore user options and return - call s:RestoreUserOptions() -" call Dret("Align#Align") - return -endfun - -" --------------------------------------------------------------------- -" Align#AlignPush: this command/function pushes an alignment control string onto a stack {{{1 -fun! Align#AlignPush() -" call Dfunc("Align#AlignPush()") - - " initialize the stack - if !exists("s:AlignCtrlStackQty") - let s:AlignCtrlStackQty= 1 - else - let s:AlignCtrlStackQty= s:AlignCtrlStackQty + 1 - endif - - " construct an AlignCtrlStack entry - if !exists("s:AlignSep") - let s:AlignSep= '' - endif - let s:AlignCtrlStack_{s:AlignCtrlStackQty}= s:AlignCtrl.'p'.s:AlignPrePad.'P'.s:AlignPostPad.s:AlignLeadKeep.s:AlignStyle.s:AlignSep -" call Decho("AlignPush: AlignCtrlStack_".s:AlignCtrlStackQty."<".s:AlignCtrlStack_{s:AlignCtrlStackQty}.">") - - " push [GV] patterns onto their own stack - if exists("s:AlignGPat") - let s:AlignGPat_{s:AlignCtrlStackQty}= s:AlignGPat - else - let s:AlignGPat_{s:AlignCtrlStackQty}= "" - endif - if exists("s:AlignVPat") - let s:AlignVPat_{s:AlignCtrlStackQty}= s:AlignVPat - else - let s:AlignVPat_{s:AlignCtrlStackQty}= "" - endif - -" call Dret("Align#AlignPush") -endfun - -" --------------------------------------------------------------------- -" Align#AlignPop: this command/function pops an alignment pattern from a stack {{{1 -" and into the AlignCtrl variables. -fun! Align#AlignPop() -" call Dfunc("Align#AlignPop()") - - " sanity checks - if !exists("s:AlignCtrlStackQty") - echoerr "(AlignPop) AlignPush needs to be used prior to AlignPop" -" call Dret("Align#AlignPop <> : AlignPush needs to have been called first") - return "" - endif - if s:AlignCtrlStackQty <= 0 - unlet s:AlignCtrlStackQty - echoerr "(AlignPop) AlignPush needs to be used prior to AlignPop" -" call Dret("Align#AlignPop <> : AlignPop needs to have been called first") - return "" - endif - - " pop top of AlignCtrlStack and pass value to AlignCtrl - let retval=s:AlignCtrlStack_{s:AlignCtrlStackQty} - unlet s:AlignCtrlStack_{s:AlignCtrlStackQty} - call Align#AlignCtrl(retval) - - " pop G pattern stack - if s:AlignGPat_{s:AlignCtrlStackQty} != "" - call Align#AlignCtrl('g',s:AlignGPat_{s:AlignCtrlStackQty}) - else - call Align#AlignCtrl('g') - endif - unlet s:AlignGPat_{s:AlignCtrlStackQty} - - " pop V pattern stack - if s:AlignVPat_{s:AlignCtrlStackQty} != "" - call Align#AlignCtrl('v',s:AlignVPat_{s:AlignCtrlStackQty}) - else - call Align#AlignCtrl('v') - endif - - unlet s:AlignVPat_{s:AlignCtrlStackQty} - let s:AlignCtrlStackQty= s:AlignCtrlStackQty - 1 - -" call Dret("Align#AlignPop <".retval."> : AlignCtrlStackQty=".s:AlignCtrlStackQty) - return retval -endfun - -" --------------------------------------------------------------------- -" Align#AlignReplaceQuotedSpaces: {{{1 -fun! Align#AlignReplaceQuotedSpaces() -" call Dfunc("Align#AlignReplaceQuotedSpaces()") - - let l:line = getline(line(".")) - let l:linelen = s:Strlen(l:line) - let l:startingPos = 0 - let l:startQuotePos = 0 - let l:endQuotePos = 0 - let l:spacePos = 0 - let l:quoteRe = '\\\@, is needed. {{{1 -" However, doesn't split at all, so this function returns a list -" of arguments which has been: -" * split at whitespace -" * unless inside "..."s. One may escape characters with a backslash inside double quotes. -" along with a leading length-of-list. -" -" Examples: %Align "\"" will align on "s -" %Align " " will align on spaces -" -" The resulting list: qarglist[0] corresponds to a:0 -" qarglist[i] corresponds to a:{i} -fun! s:QArgSplitter(qarg) -" call Dfunc("s:QArgSplitter(qarg<".a:qarg.">)") - - if a:qarg =~ '".*"' - " handle "..." args, which may include whitespace - let qarglist = [] - let args = a:qarg -" call Decho("handle quoted arguments: args<".args.">") - while args != "" - let iarg = 0 - let arglen = strlen(args) -" call Decho(".args[".iarg."]<".args[iarg]."> arglen=".arglen) - " find index to first not-escaped '"' -" call Decho("find index to first not-escaped \"") - while args[iarg] != '"' && iarg < arglen - if args[iarg] == '\' - let args= strpart(args,1) - endif - let iarg= iarg + 1 - endwhile -" call Decho(".args<".args."> iarg=".iarg." arglen=".arglen) - - if iarg > 0 - " handle left of quote or remaining section -" call Decho(".handle left of quote or remaining section") - if args[iarg] == '"' - let qarglist= qarglist + split(strpart(args,0,iarg-1)) - else - let qarglist= qarglist + split(strpart(args,0,iarg)) - endif - let args = strpart(args,iarg) - let arglen = strlen(args) - - elseif iarg < arglen && args[0] == '"' - " handle "quoted" section -" call Decho(".handle quoted section") - let iarg= 1 - while args[iarg] != '"' && iarg < arglen - if args[iarg] == '\' - let args= strpart(args,1) - endif - let iarg= iarg + 1 - endwhile -" call Decho(".args<".args."> iarg=".iarg." arglen=".arglen) - if args[iarg] == '"' - call add(qarglist,strpart(args,1,iarg-1)) - let args= strpart(args,iarg+1) - else - let qarglist = qarglist + split(args) - let args = "" - endif - endif -" call Decho(".qarglist".string(qarglist)." iarg=".iarg." args<".args.">") - endwhile -" call Decho("end of loop (handling quoted arguments)") - - else - " split at all whitespace -" call Decho("split at all whitespace") - let qarglist= split(a:qarg,"[ \t]") - endif - - let qarglistlen= len(qarglist) - let qarglist = insert(qarglist,qarglistlen) -" call Dret("s:QArgSplitter ".string(qarglist)) - return qarglist -endfun - -" --------------------------------------------------------------------- -" s:Strlen: this function returns the length of a string, even if its {{{1 -" using two-byte etc characters. -" Currently, its only used if g:Align_xstrlen is set to a -" nonzero value. 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."> g:Align_xstrlen=".g:Align_xstrlen) - - if type(g:Align_xstrlen) == 1 - " allow user to specify a function to compute the string length - 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: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: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= &l:mod - exe "norm! o\" - call setline(line("."),a:x) - let ret= virtcol("$") - 1 - d - keepj norm! k - let &l:mod= modkeep - - else - " at least give a decent default - if v:version >= 703 - let ret= strdisplaywidth(a:x) - else - let ret= strlen(a:x) - endif - endif -" call Dret("s:Strlen ".ret) - return ret -endfun - -" --------------------------------------------------------------------- -" s:SaveUserOptions: {{{1 -fun! s:SaveUserOptions() -" call Dfunc("s:SaveUserOptions() s:saved_user_options=".(exists("s:saved_user_options")? s:saved_user_options : 'n/a')) - if !exists("s:saved_user_options") - let s:saved_user_options = 1 - let s:keep_search = @/ - let s:keep_et = &l:et - let s:keep_hls = &hls - let s:keep_ic = &ic - let s:keep_paste = &paste - let s:keep_report = &report - else - let s:saved_user_options = s:saved_user_options + 1 - endif -" call Dret("s:SaveUserOptions : s:saved_user_options=".s:saved_user_options) -endfun - -" --------------------------------------------------------------------- -" s:RestoreUserOptions: {{{1 -fun! s:RestoreUserOptions() -" call Dfunc("s:RestoreUserOptions() s:saved_user_options=".(exists("s:saved_user_options")? s:saved_user_options : 'n/a')) - if exists("s:saved_user_options") && s:saved_user_options == 1 - let @/ = s:keep_search - let &l:et = s:keep_et - let &hls = s:keep_hls - let &ic = s:keep_ic - let &paste = s:keep_paste - let &report = s:keep_report - unlet s:keep_search - unlet s:keep_et - unlet s:keep_hls - unlet s:keep_ic - unlet s:keep_paste - unlet s:keep_report - unlet s:saved_user_options - elseif exists("s:saved_user_options") - let s:saved_user_options= s:saved_user_options - 1 - endif -" call Dret("s:RestoreUserOptions : s:saved_user_options=".(exists("s:saved_user_options")? s:saved_user_options : 'n/a')) -endfun - -" --------------------------------------------------------------------- -" Set up default values: {{{1 -"call Decho("-- Begin AlignCtrl Initialization --") -call Align#AlignCtrl("default") -"call Decho("-- End AlignCtrl Initialization --") - -" --------------------------------------------------------------------- -" Restore: {{{1 -let &cpo= s:keepcpo -unlet s:keepcpo -" vim: ts=4 fdm=marker diff --git a/oldStyle/disabled_plugins/AlignMaps.vim b/oldStyle/disabled_plugins/AlignMaps.vim deleted file mode 100644 index 9d20513..0000000 --- a/oldStyle/disabled_plugins/AlignMaps.vim +++ /dev/null @@ -1,401 +0,0 @@ -" AlignMaps.vim : support functions for AlignMaps -" Author: Charles E. Campbell -" Date: Mar 12, 2013 -" Version: 43 -" Copyright: Copyright (C) 1999-2012 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, -" Align.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 -"redraw!|call DechoSep()|call inputsave()|call input("Press to continue")|call inputrestore() -" --------------------------------------------------------------------- -" Load Once: {{{1 -if &cp || exists("g:loaded_AlignMaps") - finish -endif -let g:loaded_AlignMaps= "v43" -let s:keepcpo = &cpo -set cpo&vim -"DechoTabOn - -" ===================================================================== -" Functions: {{{1 - -" --------------------------------------------------------------------- -" AlignMaps#WrapperStart: {{{2 -fun! AlignMaps#WrapperStart(vis) range -" call Dfunc("AlignMaps#WrapperStart(vis=".a:vis.")") - - if a:vis - keepj norm! ' - endif - - if line("'y") == 0 || line("'z") == 0 || !exists("s:alignmaps_wrapcnt") || s:alignmaps_wrapcnt <= 0 -" call Decho("wrapper initialization") - let s:alignmaps_wrapcnt = 1 - let s:alignmaps_keepgd = &gdefault - let s:alignmaps_keepsearch = @/ - let s:alignmaps_keepch = &ch - let s:alignmaps_keepmy = SaveMark("'y") - let s:alignmaps_keepmz = SaveMark("'z") - let s:alignmaps_posn = SaveWinPosn(0) - " set up fencepost blank lines - put ='' - keepj norm! mz'a - put! ='' - ky - let s:alignmaps_zline = line("'z") - exe "keepj 'y,'zs/@/\177/ge" - else -" call Decho("embedded wrapper") - let s:alignmaps_wrapcnt = s:alignmaps_wrapcnt + 1 - keepj norm! 'yjma'zk - endif - - " change some settings to align-standard values - set nogd - set ch=2 - AlignPush - keepj norm! 'zk -" call Dret("AlignMaps#WrapperStart : alignmaps_wrapcnt=".s:alignmaps_wrapcnt." my=".line("'y")." mz=".line("'z")) -endfun - -" --------------------------------------------------------------------- -" AlignMaps#WrapperEnd: {{{2 -fun! AlignMaps#WrapperEnd() range -" call Dfunc("AlignMaps#WrapperEnd() alignmaps_wrapcnt=".s:alignmaps_wrapcnt." my=".line("'y")." mz=".line("'z")) - - " remove trailing white space introduced by whatever in the modification zone - keepj 'y,'zs/ \+$//e - - " restore AlignCtrl settings - AlignPop - - let s:alignmaps_wrapcnt= s:alignmaps_wrapcnt - 1 - if s:alignmaps_wrapcnt <= 0 - " initial wrapper ending - exe "keepj 'y,'zs/\177/@/ge" - - " if the 'z line hasn't moved, then go ahead and restore window position - let zstationary= s:alignmaps_zline == line("'z") - - " remove fencepost blank lines. - " restore 'a - keepj norm! 'yjmakdd'zdd - - " restore original 'y, 'z, and window positioning - call RestoreMark(s:alignmaps_keepmy) - call RestoreMark(s:alignmaps_keepmz) - if zstationary > 0 - call RestoreWinPosn(s:alignmaps_posn) -" call Decho("restored window positioning") - endif - - " restoration of options - let &gd= s:alignmaps_keepgd - let &ch= s:alignmaps_keepch - let @/ = s:alignmaps_keepsearch - - " remove script variables - unlet s:alignmaps_keepch - unlet s:alignmaps_keepsearch - unlet s:alignmaps_keepmy - unlet s:alignmaps_keepmz - unlet s:alignmaps_keepgd - unlet s:alignmaps_posn - endif - -" call Dret("AlignMaps#WrapperEnd : alignmaps_wrapcnt=".s:alignmaps_wrapcnt." my=".line("'y")." mz=".line("'z")) -endfun - -" --------------------------------------------------------------------- -" AlignMaps#MakeMap: make both a normal-mode and a visual mode map for mapname {{{2 -fun! AlignMaps#MakeMap(mapname) - if exists("g:maplocalleader") - let maplead= g:maplocalleader - elseif exists("g:mapleader") - let maplead= g:mapleader - else - let maplead= '\' - endif - exe "nmap ".maplead.a:mapname." AM_".a:mapname - exe "vmap ".maplead.a:mapname.' :call AlignMaps#Vis("'.a:mapname.'")'."" -endfun - -" --------------------------------------------------------------------- -" AlignMaps#StdAlign: some semi-standard align calls {{{2 -fun! AlignMaps#StdAlign(mode) range -" call Dfunc("AlignMaps#StdAlign(mode=".a:mode.")") - if a:mode == 1 - " align on @ -" call Decho("align on @") - AlignCtrl mIp1P1=l @ - 'a,.Align - elseif a:mode == 2 - " align on @, retaining all initial white space on each line -" call Decho("align on @, retaining all initial white space on each line") - AlignCtrl mWp1P1=l @ - 'a,.Align - elseif a:mode == 3 - " like mode 2, but ignore /* */-style comments -" call Decho("like mode 2, but ignore /* */-style comments") - AlignCtrl v ^\s*/[/*] - AlignCtrl mWp1P1=l @ - 'a,.Align - else - echoerr "(AlignMaps) AlignMaps#StdAlign doesn't support mode#".a:mode - endif -" call Dret("AlignMaps#StdAlign") -endfun - -" --------------------------------------------------------------------- -" AlignMaps#CharJoiner: joins lines which end in the given character (spaces {{{2 -" at end are ignored) -fun! AlignMaps#CharJoiner(chr) -" call Dfunc("AlignMaps#CharJoiner(chr=".a:chr.")") - let aline = line("'a") - let rep = line(".") - aline - while rep > 0 - keepj norm! 'a - while match(getline(aline),a:chr . "\s*$") != -1 && rep >= 0 - " while = at end-of-line, delete it and join with next - keepj norm! 'a$ - j! - let rep = rep - 1 - endwhile - " update rep(eat) count - let rep = rep - 1 - if rep <= 0 - " terminate loop if at end-of-block - break - endif - " prepare for next line - keepj norm! jma - let aline = line("'a") - endwhile -" call Dret("AlignMaps#CharJoiner") -endfun - -" --------------------------------------------------------------------- -" AlignMaps#Equals: supports \t= and \T= {{{2 -fun! AlignMaps#Equals() range -" call Dfunc("AlignMaps#Equals()") - keepj 'a,'zs/\s\+\([.*/+\-%|&\~^]\==\)/ \1/e - keepj 'a,'zs@ \+\([.*/+\-%|&\~^]\)=@\1=@ge - keepj 'a,'zs/==/\="\\"/ge - keepj 'a,'zs/\([!<>:]\)=/\=submatch(1)."\"/ge - keepj norm g'zk - AlignCtrl mIp1P1=l = - AlignCtrl g = - keepj 'a,'z-1Align - keepj 'a,'z-1s@\([.*/%|&\~^!=]\)\( \+\)=@\2\1=@ge - keepj 'a,'z-1s@[^+\-]\zs\([+\-]\)\( \+\)=@\2\1=@ge - keepj 'a,'z-1s/\( \+\);/;\1/ge - if &ft == "c" || &ft == "cpp" -" call Decho("exception for ".&ft) - keepj 'a,'z-1v/^\s*\/[*/]/s/\/[*/]/@&@/e - keepj 'a,'z-1v/^\s*\/[*/]/s/\*\//@&/e - if exists("g:mapleader") - exe "keepj norm 'zk" - call AlignMaps#StdAlign(1) - else - exe "keepj norm 'zk" - call AlignMaps#StdAlign(1) - endif - keepj 'y,'zs/^\(\s*\) @/\1/e - endif - keepj 'a,'z-1s/\%x0f/=/ge - keepj 'y,'zs/ @//eg -" call Dret("AlignMaps#Equals") -endfun - -" --------------------------------------------------------------------- -" AlignMaps#Afnc: useful for splitting one-line function beginnings {{{2 -" into one line per argument format -fun! AlignMaps#Afnc() -" call Dfunc("AlignMaps#Afnc()") - - " keep display quiet - let chkeep = &l:ch - let gdkeep = &l:gd - let wwkeep = &l:ww - let vekeep = &l:ve - setlocal ch=2 nogd ve= ww=b,s,<,>,[,] - - " will use marks y,z ; save current values - let mykeep = SaveMark("'y") - let mzkeep = SaveMark("'z") - - " Find beginning of function -- be careful to skip over comments - let cmmntid = synIDtrans(hlID("Comment")) - let stringid = synIDtrans(hlID("String")) - exe "keepj norm! ]]" - while search(")","bW") != 0 -" call Decho("line=".line(".")." col=".col(".")) - let parenid= synIDtrans(synID(line("."),col("."),1)) - if parenid != cmmntid && parenid != stringid - break - endif - endwhile - keepj norm! %my - keepj s/(\s*\(\S\)/(\r \1/e - exe "keepj norm! `y%" - keepj s/)\s*\(\/[*/]\)/)\r\1/e - exe "keepj norm! `y%mz" - keepj 'y,'zs/\s\+$//e - keepj 'y,'zs/^\s\+//e - keepj 'y+1,'zs/^/ / - - " insert newline after every comma only one parenthesis deep - exe "sil! keepj norm! `y\h" - let parens = 1 - let cmmnt = 0 - let cmmntline= -1 - while parens >= 1 - exe 'keepj norm! ma "ay`a ' -" call Decho("parens=".parens." cmmnt=".cmmnt." cmmntline=".cmmntline." line(.)=".line(".")." @a<".@a."> line<".getline(".").">") - if @a == "(" - let parens= parens + 1 - elseif @a == ")" - let parens= parens - 1 - - " comment bypass: /* ... */ or //... - elseif cmmnt == 0 && @a == '/' - let cmmnt= 1 - elseif cmmnt == 1 - if @a == '/' - let cmmnt = 2 " //... - let cmmntline= line(".") - elseif @a == '*' - let cmmnt= 3 " /*... - else - let cmmnt= 0 - endif - elseif cmmnt == 2 && line(".") != cmmntline - let cmmnt = 0 - let cmmntline= -1 - elseif cmmnt == 3 && @a == '*' - let cmmnt= 4 - elseif cmmnt == 4 - if @a == '/' - let cmmnt= 0 " ...*/ - elseif @a != '*' - let cmmnt= 3 - endif - - elseif @a == "," && parens == 1 && cmmnt == 0 - exe "keepj norm! i\\" - endif - endwhile - sil! keepj norm! `y%mz% - sil! keepj 'y,'zg/^\s*$/d - - " perform substitutes to mark fields for Align - sil! keepj 'y+1,'zv/^\//s/^\s\+\(\S\)/ \1/e - sil! keepj 'y+1,'zv/^\//s/\(\S\)\s\+/\1 /eg - sil! keepj 'y+1,'zv/^\//s/\* \+/*/ge - sil! keepj 'y+1,'zv/^\//s/\w\zs\s*\*/ */ge - " func - " ws <- declaration -> <-ptr -> <-var-> <-[array][] -> <-glop-> <-end-> - sil! keepj 'y+1,'zv/^\//s/^\s*\(\(\K\k*\s*\)\+\)\s\+\([(*]*\)\s*\(\K\k*\)\s*\(\(\[.\{-}]\)*\)\s*\(.\{-}\)\=\s*\([,)]\)\s*$/ \1@#\3@\4\5@\7\8/e - sil! keepj 'y+1,'z+1g/^\s*\/[*/]/norm! kJ - sil! keepj 'y+1,'z+1s%/[*/]%@&@%ge - sil! keepj 'y+1,'z+1s%*/%@&%ge - AlignCtrl mIp0P0=l @ - sil! keepj 'y+1,'zAlign - sil! keepj 'y,'zs%@\(/[*/]\)@%\t\1 %e - sil! keepj 'y,'zs%@\*/% */%e - sil! keepj 'y,'zs/@\([,)]\)/\1/ - sil! keepj 'y,'zs/@/ / - AlignCtrl mIlrp0P0= # @ - sil! keepj 'y+1,'zAlign - sil! keepj 'y+1,'zs/#/ / - sil! keepj 'y+1,'zs/@// - sil! keepj 'y+1,'zs/\(\s\+\)\([,)]\)/\2\1/e - - " Restore - call RestoreMark(mykeep) - call RestoreMark(mzkeep) - let &l:ch= chkeep - let &l:gd= gdkeep - let &l:ww= wwkeep - let &l:ve= vekeep - -" call Dret("AlignMaps#Afnc") -endfun - -" --------------------------------------------------------------------- -" AlignMaps#FixMultiDec: converts a type arg,arg,arg; line to multiple lines {{{2 -fun! AlignMaps#FixMultiDec() -" call Dfunc("AlignMaps#FixMultiDec()") - - " save register x - let xkeep = @x - let curline = getline(".") -" call Decho("curline<".curline.">") - - let @x=substitute(curline,'^\(\s*[a-zA-Z_ \t][a-zA-Z0-9<>_ \t]*\)\s\+[(*]*\h.*$','\1','') -" call Decho("@x<".@x.">") - - " transform line - exe 'keepj s/,/;\r'.@x.' /ge' - - "restore register x - let @x= xkeep - -" call Dret("AlignMaps#FixMultiDec : my=".line("'y")." mz=".line("'z")) -endfun - -" --------------------------------------------------------------------- -" AlignMaps#AlignMapsClean: this function removes the AlignMaps plugin {{{2 -fun! AlignMaps#AlignMapsClean() -" call Dfunc("AlignMaps#AlignMapsClean()") - for home in split(&rtp,',') + [''] -" call Decho("considering home<".home.">") - if isdirectory(home) - if filereadable(home."/autoload/AlignMaps.vim") -" call Decho("deleting ".home."/autoload/AlignMaps.vim") - call delete(home."/autoload/AlignMaps.vim") - endif - if filereadable(home."/plugin/AlignMapsPlugin.vim") -" call Decho("deleting ".home."/plugin/AlignMapsPlugin.vim") - call delete(home."/plugin/AlignMapsPlugin.vim") - endif - endif - endfor -" call Dret("AlignMaps#AlignMapsClean") -endfun - -" --------------------------------------------------------------------- -" AlignMaps#Vis: interfaces with visual maps {{{2 -fun! AlignMaps#Vis(plugmap) range -" call Dfunc("AlignMaps#VisCall(plugmap<".a:plugmap.">) ".a:firstline.",".a:lastline) - - let amark= SaveMark("a") - exe a:firstline - ka - exe a:lastline - - if exists("g:maplocalleader") - let maplead= g:maplocalleader - elseif exists("g:mapleader") - let maplead= g:mapleader - else - let maplead= '\' - endif - -" call Decho("exe norm ".maplead.a:plugmap) - exe " norm ".maplead.a:plugmap - - call RestoreMark(amark) -" call Dret("AlignMaps#VisCall") -endfun - -" --------------------------------------------------------------------- -" Restore: {{{1 -let &cpo= s:keepcpo -unlet s:keepcpo -" vim: ts=4 fdm=marker diff --git a/oldStyle/disabled_plugins/NERD_commenter.vim b/oldStyle/disabled_plugins/NERD_commenter.vim deleted file mode 100644 index ef88dd4..0000000 --- a/oldStyle/disabled_plugins/NERD_commenter.vim +++ /dev/null @@ -1,2790 +0,0 @@ -" ============================================================================ -" File: NERD_commenter.vim -" Description: vim global plugin that provides easy code commenting -" Maintainer: Martin Grenfell -" Version: 2.3.0 -" Last Change: 08th December, 2010 -" License: This program is free software. It comes without any warranty, -" to the extent permitted by applicable law. You can redistribute -" it and/or modify it under the terms of the Do What The Fuck You -" Want To Public License, Version 2, as published by Sam Hocevar. -" See http://sam.zoy.org/wtfpl/COPYING for more details. -" -" ============================================================================ - -" Section: script init stuff {{{1 -if exists("loaded_nerd_comments") - finish -endif -if v:version < 700 - echoerr "NERDCommenter: this plugin requires vim >= 7. DOWNLOAD IT! You'll thank me later!" - finish -endif -let loaded_nerd_comments = 1 - -" Function: s:InitVariable() function {{{2 -" This function is used to initialise a given variable to a given value. The -" variable is only initialised if it does not exist prior -" -" Args: -" -var: the name of the var to be initialised -" -value: the value to initialise var to -" -" Returns: -" 1 if the var is set, 0 otherwise -function s:InitVariable(var, value) - if !exists(a:var) - exec 'let ' . a:var . ' = ' . "'" . a:value . "'" - return 1 - endif - return 0 -endfunction - -" Section: space string init{{{2 -" When putting spaces after the left delim and before the right we use -" s:spaceStr for the space char. This way we can make it add anything after -" the left and before the right by modifying this variable -let s:spaceStr = ' ' -let s:lenSpaceStr = strlen(s:spaceStr) - -" Section: variable init calls {{{2 -call s:InitVariable("g:NERDAllowAnyVisualDelims", 1) -call s:InitVariable("g:NERDBlockComIgnoreEmpty", 0) -call s:InitVariable("g:NERDCommentWholeLinesInVMode", 0) -call s:InitVariable("g:NERDCompactSexyComs", 0) -call s:InitVariable("g:NERDCreateDefaultMappings", 1) -call s:InitVariable("g:NERDDefaultNesting", 1) -call s:InitVariable("g:NERDMenuMode", 3) -call s:InitVariable("g:NERDLPlace", "[>") -call s:InitVariable("g:NERDUsePlaceHolders", 1) -call s:InitVariable("g:NERDRemoveAltComs", 1) -call s:InitVariable("g:NERDRemoveExtraSpaces", 1) -call s:InitVariable("g:NERDRPlace", "<]") -call s:InitVariable("g:NERDSpaceDelims", 0) -call s:InitVariable("g:NERDDelimiterRequests", 1) - -let s:NERDFileNameEscape="[]#*$%'\" ?`!&();<>\\" -"vf ;;dA:hcs"'A {j^f(lyi(k$p0f{a A }0f{a 'left':jdd^ - -let s:delimiterMap = { - \ 'aap': { 'left': '#' }, - \ 'abc': { 'left': '%' }, - \ 'acedb': { 'left': '//', 'leftAlt': '/*', 'rightAlt': '*/' }, - \ 'actionscript': { 'left': '//', 'leftAlt': '/*', 'rightAlt': '*/' }, - \ 'ada': { 'left': '--', 'leftAlt': '-- ' }, - \ 'ahdl': { 'left': '--' }, - \ 'ahk': { 'left': ';', 'leftAlt': '/*', 'rightAlt': '*/' }, - \ 'amiga': { 'left': ';' }, - \ 'aml': { 'left': '/*' }, - \ 'ampl': { 'left': '#' }, - \ 'apache': { 'left': '#' }, - \ 'apachestyle': { 'left': '#' }, - \ 'asciidoc': { 'left': '//' }, - \ 'applescript': { 'left': '--', 'leftAlt': '(*', 'rightAlt': '*)' }, - \ 'asm68k': { 'left': ';' }, - \ 'asm': { 'left': ';', 'leftAlt': '#' }, - \ 'asn': { 'left': '--' }, - \ 'aspvbs': { 'left': '''' }, - \ 'asterisk': { 'left': ';' }, - \ 'asy': { 'left': '//' }, - \ 'atlas': { 'left': 'C', 'right': '$' }, - \ 'autohotkey': { 'left': ';' }, - \ 'autoit': { 'left': ';' }, - \ 'ave': { 'left': "'" }, - \ 'awk': { 'left': '#' }, - \ 'basic': { 'left': "'", 'leftAlt': 'REM ' }, - \ 'bbx': { 'left': '%' }, - \ 'bc': { 'left': '#' }, - \ 'bib': { 'left': '%' }, - \ 'bindzone': { 'left': ';' }, - \ 'bst': { 'left': '%' }, - \ 'btm': { 'left': '::' }, - \ 'caos': { 'left': '*' }, - \ 'calibre': { 'left': '//' }, - \ 'catalog': { 'left': '--', 'right': '--' }, - \ 'c': { 'left': '/*','right': '*/', 'leftAlt': '//' }, - \ 'cfg': { 'left': '#' }, - \ 'cg': { 'left': '//', 'leftAlt': '/*', 'rightAlt': '*/' }, - \ 'ch': { 'left': '//', 'leftAlt': '/*', 'rightAlt': '*/' }, - \ 'cl': { 'left': '#' }, - \ 'clean': { 'left': '//', 'leftAlt': '/*', 'rightAlt': '*/' }, - \ 'clipper': { 'left': '//', 'leftAlt': '/*', 'rightAlt': '*/' }, - \ 'clojure': { 'left': ';' }, - \ 'cmake': { 'left': '#' }, - \ 'conkyrc': { 'left': '#' }, - \ 'cpp': { 'left': '//', 'leftAlt': '/*', 'rightAlt': '*/' }, - \ 'crontab': { 'left': '#' }, - \ 'cs': { 'left': '//', 'leftAlt': '/*', 'rightAlt': '*/' }, - \ 'csp': { 'left': '--' }, - \ 'cterm': { 'left': '*' }, - \ 'cucumber': { 'left': '#' }, - \ 'cvs': { 'left': 'CVS:' }, - \ 'd': { 'left': '//', 'leftAlt': '/*', 'rightAlt': '*/' }, - \ 'dcl': { 'left': '$!' }, - \ 'dakota': { 'left': '#' }, - \ 'debcontrol': { 'left': '#' }, - \ 'debsources': { 'left': '#' }, - \ 'def': { 'left': ';' }, - \ 'desktop': { 'left': '#' }, - \ 'dhcpd': { 'left': '#' }, - \ 'diff': { 'left': '#' }, - \ 'django': { 'left': '', 'leftAlt': '{#', 'rightAlt': '#}' }, - \ 'docbk': { 'left': '' }, - \ 'dns': { 'left': ';' }, - \ 'dosbatch': { 'left': 'REM ', 'leftAlt': '::' }, - \ 'dosini': { 'left': ';' }, - \ 'dot': { 'left': '//', 'leftAlt': '/*', 'rightAlt': '*/' }, - \ 'dracula': { 'left': ';' }, - \ 'dsl': { 'left': ';' }, - \ 'dtml': { 'left': '', 'right': '' }, - \ 'dylan': { 'left': '//', 'leftAlt': '/*', 'rightAlt': '*/' }, - \ 'ebuild': { 'left': '#' }, - \ 'ecd': { 'left': '#' }, - \ 'eclass': { 'left': '#' }, - \ 'eiffel': { 'left': '--' }, - \ 'elf': { 'left': "'" }, - \ 'elmfilt': { 'left': '#' }, - \ 'erlang': { 'left': '%' }, - \ 'eruby': { 'left': '<%#', 'right': '%>', 'leftAlt': '' }, - \ 'expect': { 'left': '#' }, - \ 'exports': { 'left': '#' }, - \ 'factor': { 'left': '! ', 'leftAlt': '!# ' }, - \ 'fgl': { 'left': '#' }, - \ 'focexec': { 'left': '-*' }, - \ 'form': { 'left': '*' }, - \ 'foxpro': { 'left': '*' }, - \ 'fstab': { 'left': '#' }, - \ 'fvwm': { 'left': '#' }, - \ 'fx': { 'left': '//', 'leftAlt': '/*', 'rightAlt': '*/' }, - \ 'gams': { 'left': '*' }, - \ 'gdb': { 'left': '#' }, - \ 'gdmo': { 'left': '--' }, - \ 'geek': { 'left': 'GEEK_COMMENT:' }, - \ 'genshi': { 'left': '', 'leftAlt': '{#', 'rightAlt': '#}' }, - \ 'gentoo-conf-d': { 'left': '#' }, - \ 'gentoo-env-d': { 'left': '#' }, - \ 'gentoo-init-d': { 'left': '#' }, - \ 'gentoo-make-conf': { 'left': '#' }, - \ 'gentoo-package-keywords': { 'left': '#' }, - \ 'gentoo-package-mask': { 'left': '#' }, - \ 'gentoo-package-use': { 'left': '#' }, - \ 'gitcommit': { 'left': '#' }, - \ 'gitconfig': { 'left': ';' }, - \ 'gitrebase': { 'left': '#' }, - \ 'gnuplot': { 'left': '#' }, - \ 'groovy': { 'left': '//', 'leftAlt': '/*', 'rightAlt': '*/' }, - \ 'gsp': { 'left': '<%--', 'right': '--%>' }, - \ 'gtkrc': { 'left': '#' }, - \ 'haskell': { 'left': '{-','right': '-}', 'leftAlt': '--' }, - \ 'hb': { 'left': '#' }, - \ 'h': { 'left': '//', 'leftAlt': '/*', 'rightAlt': '*/' }, - \ 'haml': { 'left': '-#', 'leftAlt': '/' }, - \ 'hercules': { 'left': '//', 'leftAlt': '/*', 'rightAlt': '*/' }, - \ 'hog': { 'left': '#' }, - \ 'hostsaccess': { 'left': '#' }, - \ 'htmlcheetah': { 'left': '##' }, - \ 'htmldjango': { 'left': '', 'leftAlt': '{#', 'rightAlt': '#}' }, - \ 'htmlos': { 'left': '#', 'right': '/#' }, - \ 'ia64': { 'left': '#' }, - \ 'icon': { 'left': '#' }, - \ 'idlang': { 'left': ';' }, - \ 'idl': { 'left': '//', 'leftAlt': '/*', 'rightAlt': '*/' }, - \ 'inform': { 'left': '!' }, - \ 'inittab': { 'left': '#' }, - \ 'ishd': { 'left': '//', 'leftAlt': '/*', 'rightAlt': '*/' }, - \ 'iss': { 'left': ';' }, - \ 'ist': { 'left': '%' }, - \ 'java': { 'left': '//', 'leftAlt': '/*', 'rightAlt': '*/' }, - \ 'javacc': { 'left': '//', 'leftAlt': '/*', 'rightAlt': '*/' }, - \ 'javascript': { 'left': '//', 'leftAlt': '/*', 'rightAlt': '*/' }, - \ 'javascript.jquery': { 'left': '//', 'leftAlt': '/*', 'rightAlt': '*/' }, - \ 'jess': { 'left': ';' }, - \ 'jgraph': { 'left': '(*', 'right': '*)' }, - \ 'jproperties': { 'left': '#' }, - \ 'jsp': { 'left': '<%--', 'right': '--%>' }, - \ 'kix': { 'left': ';' }, - \ 'kscript': { 'left': '//', 'leftAlt': '/*', 'rightAlt': '*/' }, - \ 'lace': { 'left': '--' }, - \ 'ldif': { 'left': '#' }, - \ 'lilo': { 'left': '#' }, - \ 'lilypond': { 'left': '%' }, - \ 'liquid': { 'left': '{%', 'right': '%}' }, - \ 'lisp': { 'left': ';', 'leftAlt': '#|', 'rightAlt': '|#' }, - \ 'llvm': { 'left': ';' }, - \ 'lotos': { 'left': '(*', 'right': '*)' }, - \ 'lout': { 'left': '#' }, - \ 'lprolog': { 'left': '%' }, - \ 'lscript': { 'left': "'" }, - \ 'lss': { 'left': '#' }, - \ 'lua': { 'left': '--', 'leftAlt': '--[[', 'rightAlt': ']]' }, - \ 'lynx': { 'left': '#' }, - \ 'lytex': { 'left': '%' }, - \ 'mail': { 'left': '> ' }, - \ 'mako': { 'left': '##' }, - \ 'man': { 'left': '."' }, - \ 'map': { 'left': '%' }, - \ 'maple': { 'left': '#' }, - \ 'markdown': { 'left': '' }, - \ 'masm': { 'left': ';' }, - \ 'mason': { 'left': '<% #', 'right': '%>' }, - \ 'master': { 'left': '$' }, - \ 'matlab': { 'left': '%' }, - \ 'mel': { 'left': '//', 'leftAlt': '/*', 'rightAlt': '*/' }, - \ 'mib': { 'left': '--' }, - \ 'mkd': { 'left': '>' }, - \ 'mma': { 'left': '(*', 'right': '*)' }, - \ 'model': { 'left': '$', 'right': '$' }, - \ 'moduala.': { 'left': '(*', 'right': '*)' }, - \ 'modula2': { 'left': '(*', 'right': '*)' }, - \ 'modula3': { 'left': '(*', 'right': '*)' }, - \ 'monk': { 'left': ';' }, - \ 'mush': { 'left': '#' }, - \ 'named': { 'left': '//', 'leftAlt': '/*', 'rightAlt': '*/' }, - \ 'nasm': { 'left': ';' }, - \ 'nastran': { 'left': '$' }, - \ 'natural': { 'left': '/*' }, - \ 'ncf': { 'left': ';' }, - \ 'newlisp': { 'left': ';' }, - \ 'nroff': { 'left': '\"' }, - \ 'nsis': { 'left': '#' }, - \ 'ntp': { 'left': '#' }, - \ 'objc': { 'left': '//', 'leftAlt': '/*', 'rightAlt': '*/' }, - \ 'objcpp': { 'left': '//', 'leftAlt': '/*', 'rightAlt': '*/' }, - \ 'objj': { 'left': '//', 'leftAlt': '/*', 'rightAlt': '*/' }, - \ 'ocaml': { 'left': '(*', 'right': '*)' }, - \ 'occam': { 'left': '--' }, - \ 'omlet': { 'left': '(*', 'right': '*)' }, - \ 'omnimark': { 'left': ';' }, - \ 'openroad': { 'left': '//' }, - \ 'opl': { 'left': "REM" }, - \ 'ora': { 'left': '#' }, - \ 'ox': { 'left': '//' }, - \ 'pascal': { 'left': '{','right': '}', 'leftAlt': '(*', 'rightAlt': '*)' }, - \ 'patran': { 'left': '$', 'leftAlt': '/*', 'rightAlt': '*/' }, - \ 'pcap': { 'left': '#' }, - \ 'pccts': { 'left': '//', 'leftAlt': '/*', 'rightAlt': '*/' }, - \ 'pdf': { 'left': '%' }, - \ 'pfmain': { 'left': '//' }, - \ 'php': { 'left': '//', 'leftAlt': '/*', 'rightAlt': '*/' }, - \ 'pic': { 'left': ';' }, - \ 'pike': { 'left': '//', 'leftAlt': '/*', 'rightAlt': '*/' }, - \ 'pilrc': { 'left': '//', 'leftAlt': '/*', 'rightAlt': '*/' }, - \ 'pine': { 'left': '#' }, - \ 'plm': { 'left': '//', 'leftAlt': '/*', 'rightAlt': '*/' }, - \ 'plsql': { 'left': '--', 'leftAlt': '/*', 'rightAlt': '*/' }, - \ 'po': { 'left': '#' }, - \ 'postscr': { 'left': '%' }, - \ 'pov': { 'left': '//', 'leftAlt': '/*', 'rightAlt': '*/' }, - \ 'povini': { 'left': ';' }, - \ 'ppd': { 'left': '%' }, - \ 'ppwiz': { 'left': ';;' }, - \ 'processing': { 'left': '//', 'leftAlt': '/*', 'rightAlt': '*/' }, - \ 'prolog': { 'left': '%', 'leftAlt': '/*', 'rightAlt': '*/' }, - \ 'ps1': { 'left': '#' }, - \ 'psf': { 'left': '#' }, - \ 'ptcap': { 'left': '#' }, - \ 'python': { 'left': '#' }, - \ 'radiance': { 'left': '#' }, - \ 'ratpoison': { 'left': '#' }, - \ 'r': { 'left': '#' }, - \ 'rc': { 'left': '//', 'leftAlt': '/*', 'rightAlt': '*/' }, - \ 'rebol': { 'left': ';' }, - \ 'registry': { 'left': ';' }, - \ 'remind': { 'left': '#' }, - \ 'resolv': { 'left': '#' }, - \ 'rgb': { 'left': '!' }, - \ 'rib': { 'left': '#' }, - \ 'robots': { 'left': '#' }, - \ 'sa': { 'left': '--' }, - \ 'samba': { 'left': ';', 'leftAlt': '#' }, - \ 'sass': { 'left': '//', 'leftAlt': '/*' }, - \ 'sather': { 'left': '--' }, - \ 'scala': { 'left': '//', 'leftAlt': '/*', 'rightAlt': '*/' }, - \ 'scilab': { 'left': '//' }, - \ 'scsh': { 'left': ';' }, - \ 'sed': { 'left': '#' }, - \ 'sgmldecl': { 'left': '--', 'right': '--' }, - \ 'sgmllnx': { 'left': '' }, - \ 'sicad': { 'left': '*' }, - \ 'simula': { 'left': '%', 'leftAlt': '--' }, - \ 'sinda': { 'left': '$' }, - \ 'skill': { 'left': ';' }, - \ 'slang': { 'left': '%' }, - \ 'slice': { 'left': '//', 'leftAlt': '/*', 'rightAlt': '*/' }, - \ 'slrnrc': { 'left': '%' }, - \ 'sm': { 'left': '#' }, - \ 'smarty': { 'left': '{*', 'right': '*}' }, - \ 'smil': { 'left': '' }, - \ 'smith': { 'left': ';' }, - \ 'sml': { 'left': '(*', 'right': '*)' }, - \ 'snnsnet': { 'left': '#' }, - \ 'snnspat': { 'left': '#' }, - \ 'snnsres': { 'left': '#' }, - \ 'snobol4': { 'left': '*' }, - \ 'spec': { 'left': '#' }, - \ 'specman': { 'left': '//' }, - \ 'spectre': { 'left': '//', 'leftAlt': '*' }, - \ 'spice': { 'left': '$' }, - \ 'sql': { 'left': '--' }, - \ 'sqlforms': { 'left': '--' }, - \ 'sqlj': { 'left': '--' }, - \ 'sqr': { 'left': '!' }, - \ 'squid': { 'left': '#' }, - \ 'st': { 'left': '"' }, - \ 'stp': { 'left': '--' }, - \ 'systemverilog': { 'left': '//', 'leftAlt': '/*', 'rightAlt': '*/' }, - \ 'tads': { 'left': '//', 'leftAlt': '/*', 'rightAlt': '*/' }, - \ 'tags': { 'left': ';' }, - \ 'tak': { 'left': '$' }, - \ 'tasm': { 'left': ';' }, - \ 'tcl': { 'left': '#' }, - \ 'texinfo': { 'left': "@c " }, - \ 'texmf': { 'left': '%' }, - \ 'tf': { 'left': ';' }, - \ 'tidy': { 'left': '#' }, - \ 'tli': { 'left': '#' }, - \ 'tmux': { 'left': '#' }, - \ 'trasys': { 'left': "$" }, - \ 'tsalt': { 'left': '//', 'leftAlt': '/*', 'rightAlt': '*/' }, - \ 'tsscl': { 'left': '#' }, - \ 'tssgm': { 'left': "comment = '", 'right': "'" }, - \ 'txt2tags': { 'left': '%' }, - \ 'uc': { 'left': '//', 'leftAlt': '/*', 'rightAlt': '*/' }, - \ 'uil': { 'left': '!' }, - \ 'vb': { 'left': "'" }, - \ 'velocity': { 'left': "##", 'right': "", 'leftAlt': '#*', 'rightAlt': '*#' }, - \ 'vera': { 'left': '/*','right': '*/', 'leftAlt': '//' }, - \ 'verilog': { 'left': '//', 'leftAlt': '/*', 'rightAlt': '*/' }, - \ 'verilog_systemverilog': { 'left': '//', 'leftAlt': '/*', 'rightAlt': '*/' }, - \ 'vgrindefs': { 'left': '#' }, - \ 'vhdl': { 'left': '--' }, - \ 'vimperator': { 'left': '"' }, - \ 'virata': { 'left': '%' }, - \ 'vrml': { 'left': '#' }, - \ 'vsejcl': { 'left': '/*' }, - \ 'webmacro': { 'left': '##' }, - \ 'wget': { 'left': '#' }, - \ 'Wikipedia': { 'left': '' }, - \ 'winbatch': { 'left': ';' }, - \ 'wml': { 'left': '#' }, - \ 'wvdial': { 'left': ';' }, - \ 'xdefaults': { 'left': '!' }, - \ 'xkb': { 'left': '//' }, - \ 'xmath': { 'left': '#' }, - \ 'xpm2': { 'left': '!' }, - \ 'xquery': { 'left': '(:', 'right': ':)' }, - \ 'z8a': { 'left': ';' } - \ } - -" Section: Comment mapping functions, autocommands and commands {{{1 -" ============================================================================ -" Section: Comment enabler autocommands {{{2 -" ============================================================================ - -augroup commentEnablers - - "if the user enters a buffer or reads a buffer then we gotta set up - "the comment delimiters for that new filetype - autocmd BufEnter,BufRead * :call s:SetUpForNewFiletype(&filetype, 0) - - "if the filetype of a buffer changes, force the script to reset the - "delims for the buffer - autocmd Filetype * :call s:SetUpForNewFiletype(&filetype, 1) -augroup END - - -" Function: s:SetUpForNewFiletype(filetype) function {{{2 -" This function is responsible for setting up buffer scoped variables for the -" given filetype. -" -" Args: -" -filetype: the filetype to set delimiters for -" -forceReset: 1 if the delimiters should be reset if they have already be -" set for this buffer. -" -function s:SetUpForNewFiletype(filetype, forceReset) - let b:NERDSexyComMarker = '' - - if has_key(s:delimiterMap, a:filetype) - let b:NERDCommenterDelims = s:delimiterMap[a:filetype] - for i in ['left', 'leftAlt', 'right', 'rightAlt'] - if !has_key(b:NERDCommenterDelims, i) - let b:NERDCommenterDelims[i] = '' - endif - endfor - else - let b:NERDCommenterDelims = s:CreateDelimMapFromCms() - endif - -endfunction - -function s:CreateDelimMapFromCms() - return { - \ 'left': substitute(&commentstring, '\([^ \t]*\)\s*%s.*', '\1', ''), - \ 'right': substitute(&commentstring, '.*%s\s*\(.*\)', '\1', 'g'), - \ 'leftAlt': '', - \ 'rightAlt': '' } -endfunction - -" Function: s:SwitchToAlternativeDelimiters(printMsgs) function {{{2 -" This function is used to swap the delimiters that are being used to the -" alternative delimiters for that filetype. For example, if a c++ file is -" being edited and // comments are being used, after this function is called -" /**/ comments will be used. -" -" Args: -" -printMsgs: if this is 1 then a message is echoed to the user telling them -" if this function changed the delimiters or not -function s:SwitchToAlternativeDelimiters(printMsgs) - "if both of the alternative delimiters are empty then there is no - "alternative comment style so bail out - if b:NERDCommenterDelims['leftAlt'] == '' && b:NERDCommenterDelims['rightAlt'] == '' - if a:printMsgs - call s:NerdEcho("Cannot use alternative delimiters, none are specified", 0) - endif - return 0 - endif - - "save the current delimiters - let tempLeft = s:Left() - let tempRight = s:Right() - - "swap current delimiters for alternative - let b:NERDCommenterDelims['left'] = b:NERDCommenterDelims['leftAlt'] - let b:NERDCommenterDelims['right'] = b:NERDCommenterDelims['rightAlt'] - - "set the previously current delimiters to be the new alternative ones - let b:NERDCommenterDelims['leftAlt'] = tempLeft - let b:NERDCommenterDelims['rightAlt'] = tempRight - - "tell the user what comment delimiters they are now using - if a:printMsgs - call s:NerdEcho("Now using " . s:Left() . " " . s:Right() . " to delimit comments", 1) - endif - - return 1 -endfunction - -" Section: Comment delimiter add/removal functions {{{1 -" ============================================================================ -" Function: s:AppendCommentToLine(){{{2 -" This function appends comment delimiters at the EOL and places the cursor in -" position to start typing the comment -function s:AppendCommentToLine() - let left = s:Left({'space': 1}) - let right = s:Right({'space': 1}) - - " get the len of the right delim - let lenRight = strlen(right) - - let isLineEmpty = strlen(getline(".")) == 0 - let insOrApp = (isLineEmpty==1 ? 'i' : 'A') - - "stick the delimiters down at the end of the line. We have to format the - "comment with spaces as appropriate - execute ":normal! " . insOrApp . (isLineEmpty ? '' : ' ') . left . right . " " - - " if there is a right delimiter then we gotta move the cursor left - " by the len of the right delimiter so we insert between the delimiters - if lenRight > 0 - let leftMoveAmount = lenRight - execute ":normal! " . leftMoveAmount . "h" - endif - startinsert -endfunction - -" Function: s:CommentBlock(top, bottom, lSide, rSide, forceNested ) {{{2 -" This function is used to comment out a region of code. This region is -" specified as a bounding box by arguments to the function. -" -" Args: -" -top: the line number for the top line of code in the region -" -bottom: the line number for the bottom line of code in the region -" -lSide: the column number for the left most column in the region -" -rSide: the column number for the right most column in the region -" -forceNested: a flag indicating whether comments should be nested -function s:CommentBlock(top, bottom, lSide, rSide, forceNested ) - " we need to create local copies of these arguments so we can modify them - let top = a:top - let bottom = a:bottom - let lSide = a:lSide - let rSide = a:rSide - - "if the top or bottom line starts with tabs we have to adjust the left and - "right boundaries so that they are set as though the tabs were spaces - let topline = getline(top) - let bottomline = getline(bottom) - if s:HasLeadingTabs(topline, bottomline) - - "find out how many tabs are in the top line and adjust the left - "boundary accordingly - let numTabs = s:NumberOfLeadingTabs(topline) - if lSide < numTabs - let lSide = &ts * lSide - else - let lSide = (lSide - numTabs) + (&ts * numTabs) - endif - - "find out how many tabs are in the bottom line and adjust the right - "boundary accordingly - let numTabs = s:NumberOfLeadingTabs(bottomline) - let rSide = (rSide - numTabs) + (&ts * numTabs) - endif - - "we must check that bottom IS actually below top, if it is not then we - "swap top and bottom. Similarly for left and right. - if bottom < top - let temp = top - let top = bottom - let bottom = top - endif - if rSide < lSide - let temp = lSide - let lSide = rSide - let rSide = temp - endif - - "if the current delimiters arent multipart then we will switch to the - "alternative delims (if THEY are) as the comment will be better and more - "accurate with multipart delims - let switchedDelims = 0 - if !s:Multipart() && g:NERDAllowAnyVisualDelims && s:AltMultipart() - let switchedDelims = 1 - call s:SwitchToAlternativeDelimiters(0) - endif - - "start the commenting from the top and keep commenting till we reach the - "bottom - let currentLine=top - while currentLine <= bottom - - "check if we are allowed to comment this line - if s:CanCommentLine(a:forceNested, currentLine) - - "convert the leading tabs into spaces - let theLine = getline(currentLine) - let lineHasLeadTabs = s:HasLeadingTabs(theLine) - if lineHasLeadTabs - let theLine = s:ConvertLeadingTabsToSpaces(theLine) - endif - - "dont comment lines that begin after the right boundary of the - "block unless the user has specified to do so - if theLine !~ '^ \{' . rSide . '\}' || !g:NERDBlockComIgnoreEmpty - - "attempt to place the cursor in on the left of the boundary box, - "then check if we were successful, if not then we cant comment this - "line - call setline(currentLine, theLine) - if s:CanPlaceCursor(currentLine, lSide) - - let leftSpaced = s:Left({'space': 1}) - let rightSpaced = s:Right({'space': 1}) - - "stick the left delimiter down - let theLine = strpart(theLine, 0, lSide-1) . leftSpaced . strpart(theLine, lSide-1) - - if s:Multipart() - "stick the right delimiter down - let theLine = strpart(theLine, 0, rSide+strlen(leftSpaced)) . rightSpaced . strpart(theLine, rSide+strlen(leftSpaced)) - - let firstLeftDelim = s:FindDelimiterIndex(s:Left(), theLine) - let lastRightDelim = s:LastIndexOfDelim(s:Right(), theLine) - - if firstLeftDelim != -1 && lastRightDelim != -1 - let searchStr = strpart(theLine, 0, lastRightDelim) - let searchStr = strpart(searchStr, firstLeftDelim+strlen(s:Left())) - - "replace the outter most delims in searchStr with - "place-holders - let theLineWithPlaceHolders = s:ReplaceDelims(s:Left(), s:Right(), g:NERDLPlace, g:NERDRPlace, searchStr) - - "add the right delimiter onto the line - let theLine = strpart(theLine, 0, firstLeftDelim+strlen(s:Left())) . theLineWithPlaceHolders . strpart(theLine, lastRightDelim) - endif - endif - endif - endif - - "restore tabs if needed - if lineHasLeadTabs - let theLine = s:ConvertLeadingSpacesToTabs(theLine) - endif - - call setline(currentLine, theLine) - endif - - let currentLine = currentLine + 1 - endwhile - - "if we switched delims then we gotta go back to what they were before - if switchedDelims == 1 - call s:SwitchToAlternativeDelimiters(0) - endif -endfunction - -" Function: s:CommentLines(forceNested, alignLeft, alignRight, firstLine, lastLine) {{{2 -" This function comments a range of lines. -" -" Args: -" -forceNested: a flag indicating whether the called is requesting the comment -" to be nested if need be -" -align: should be "left" or "both" or "none" -" -firstLine/lastLine: the top and bottom lines to comment -function s:CommentLines(forceNested, align, firstLine, lastLine) - " we need to get the left and right indexes of the leftmost char in the - " block of of lines and the right most char so that we can do alignment of - " the delimiters if the user has specified - let leftAlignIndx = s:LeftMostIndx(a:forceNested, 0, a:firstLine, a:lastLine) - let rightAlignIndx = s:RightMostIndx(a:forceNested, 0, a:firstLine, a:lastLine) - - " gotta add the length of the left delimiter onto the rightAlignIndx cos - " we'll be adding a left delim to the line - let rightAlignIndx = rightAlignIndx + strlen(s:Left({'space': 1})) - - " now we actually comment the lines. Do it line by line - let currentLine = a:firstLine - while currentLine <= a:lastLine - - " get the next line, check commentability and convert spaces to tabs - let theLine = getline(currentLine) - let lineHasLeadingTabs = s:HasLeadingTabs(theLine) - let theLine = s:ConvertLeadingTabsToSpaces(theLine) - if s:CanCommentLine(a:forceNested, currentLine) - "if the user has specified forceNesting then we check to see if we - "need to switch delimiters for place-holders - if a:forceNested && g:NERDUsePlaceHolders - let theLine = s:SwapOutterMultiPartDelimsForPlaceHolders(theLine) - endif - - " find out if the line is commented using normal delims and/or - " alternate ones - let isCommented = s:IsCommented(s:Left(), s:Right(), theLine) || s:IsCommented(s:Left({'alt': 1}), s:Right({'alt': 1}), theLine) - - " check if we can comment this line - if !isCommented || g:NERDUsePlaceHolders || s:Multipart() - if a:align == "left" || a:align == "both" - let theLine = s:AddLeftDelimAligned(s:Left({'space': 1}), theLine, leftAlignIndx) - else - let theLine = s:AddLeftDelim(s:Left({'space': 1}), theLine) - endif - if a:align == "both" - let theLine = s:AddRightDelimAligned(s:Right({'space': 1}), theLine, rightAlignIndx) - else - let theLine = s:AddRightDelim(s:Right({'space': 1}), theLine) - endif - endif - endif - - " restore leading tabs if appropriate - if lineHasLeadingTabs - let theLine = s:ConvertLeadingSpacesToTabs(theLine) - endif - - " we are done with this line - call setline(currentLine, theLine) - let currentLine = currentLine + 1 - endwhile - -endfunction - -" Function: s:CommentLinesMinimal(firstLine, lastLine) {{{2 -" This function comments a range of lines in a minimal style. I -" -" Args: -" -firstLine/lastLine: the top and bottom lines to comment -function s:CommentLinesMinimal(firstLine, lastLine) - "check that minimal comments can be done on this filetype - if !s:HasMultipartDelims() - throw 'NERDCommenter.Delimiters exception: Minimal comments can only be used for filetypes that have multipart delimiters' - endif - - "if we need to use place holders for the comment, make sure they are - "enabled for this filetype - if !g:NERDUsePlaceHolders && s:DoesBlockHaveMultipartDelim(a:firstLine, a:lastLine) - throw 'NERDCommenter.Settings exception: Place holders are required but disabled.' - endif - - "get the left and right delims to smack on - let left = s:GetSexyComLeft(g:NERDSpaceDelims,0) - let right = s:GetSexyComRight(g:NERDSpaceDelims,0) - - "make sure all multipart delims on the lines are replaced with - "placeholders to prevent illegal syntax - let currentLine = a:firstLine - while(currentLine <= a:lastLine) - let theLine = getline(currentLine) - let theLine = s:ReplaceDelims(left, right, g:NERDLPlace, g:NERDRPlace, theLine) - call setline(currentLine, theLine) - let currentLine = currentLine + 1 - endwhile - - "add the delim to the top line - let theLine = getline(a:firstLine) - let lineHasLeadingTabs = s:HasLeadingTabs(theLine) - let theLine = s:ConvertLeadingTabsToSpaces(theLine) - let theLine = s:AddLeftDelim(left, theLine) - if lineHasLeadingTabs - let theLine = s:ConvertLeadingSpacesToTabs(theLine) - endif - call setline(a:firstLine, theLine) - - "add the delim to the bottom line - let theLine = getline(a:lastLine) - let lineHasLeadingTabs = s:HasLeadingTabs(theLine) - let theLine = s:ConvertLeadingTabsToSpaces(theLine) - let theLine = s:AddRightDelim(right, theLine) - if lineHasLeadingTabs - let theLine = s:ConvertLeadingSpacesToTabs(theLine) - endif - call setline(a:lastLine, theLine) -endfunction - -" Function: s:CommentLinesSexy(topline, bottomline) function {{{2 -" This function is used to comment lines in the 'Sexy' style. eg in c: -" /* -" * This is a sexy comment -" */ -" Args: -" -topline: the line num of the top line in the sexy comment -" -bottomline: the line num of the bottom line in the sexy comment -function s:CommentLinesSexy(topline, bottomline) - let left = s:GetSexyComLeft(0, 0) - let right = s:GetSexyComRight(0, 0) - - "check if we can do a sexy comment with the available delimiters - if left == -1 || right == -1 - throw 'NERDCommenter.Delimiters exception: cannot perform sexy comments with available delimiters.' - endif - - "make sure the lines arent already commented sexually - if !s:CanSexyCommentLines(a:topline, a:bottomline) - throw 'NERDCommenter.Nesting exception: cannot nest sexy comments' - endif - - - let sexyComMarker = s:GetSexyComMarker(0,0) - let sexyComMarkerSpaced = s:GetSexyComMarker(1,0) - - - " we jam the comment as far to the right as possible - let leftAlignIndx = s:LeftMostIndx(1, 1, a:topline, a:bottomline) - - "check if we should use the compact style i.e that the left/right - "delimiters should appear on the first and last lines of the code and not - "on separate lines above/below the first/last lines of code - if g:NERDCompactSexyComs - let spaceString = (g:NERDSpaceDelims ? s:spaceStr : '') - - "comment the top line - let theLine = getline(a:topline) - let lineHasTabs = s:HasLeadingTabs(theLine) - if lineHasTabs - let theLine = s:ConvertLeadingTabsToSpaces(theLine) - endif - let theLine = s:SwapOutterMultiPartDelimsForPlaceHolders(theLine) - let theLine = s:AddLeftDelimAligned(left . spaceString, theLine, leftAlignIndx) - if lineHasTabs - let theLine = s:ConvertLeadingSpacesToTabs(theLine) - endif - call setline(a:topline, theLine) - - "comment the bottom line - if a:bottomline != a:topline - let theLine = getline(a:bottomline) - let lineHasTabs = s:HasLeadingTabs(theLine) - if lineHasTabs - let theLine = s:ConvertLeadingTabsToSpaces(theLine) - endif - let theLine = s:SwapOutterMultiPartDelimsForPlaceHolders(theLine) - endif - let theLine = s:AddRightDelim(spaceString . right, theLine) - if lineHasTabs - let theLine = s:ConvertLeadingSpacesToTabs(theLine) - endif - call setline(a:bottomline, theLine) - else - - " add the left delimiter one line above the lines that are to be commented - call cursor(a:topline, 1) - execute 'normal! O' - let theLine = repeat(' ', leftAlignIndx) . left - - " Make sure tabs are respected - if !&expandtab - let theLine = s:ConvertLeadingSpacesToTabs(theLine) - endif - call setline(a:topline, theLine) - - " add the right delimiter after bottom line (we have to add 1 cos we moved - " the lines down when we added the left delim - call cursor(a:bottomline+1, 1) - execute 'normal! o' - let theLine = repeat(' ', leftAlignIndx) . repeat(' ', strlen(left)-strlen(sexyComMarker)) . right - - " Make sure tabs are respected - if !&expandtab - let theLine = s:ConvertLeadingSpacesToTabs(theLine) - endif - call setline(a:bottomline+2, theLine) - - endif - - " go thru each line adding the sexyComMarker marker to the start of each - " line in the appropriate place to align them with the comment delims - let currentLine = a:topline+1 - while currentLine <= a:bottomline + !g:NERDCompactSexyComs - " get the line and convert the tabs to spaces - let theLine = getline(currentLine) - let lineHasTabs = s:HasLeadingTabs(theLine) - if lineHasTabs - let theLine = s:ConvertLeadingTabsToSpaces(theLine) - endif - - let theLine = s:SwapOutterMultiPartDelimsForPlaceHolders(theLine) - - " add the sexyComMarker - let theLine = repeat(' ', leftAlignIndx) . repeat(' ', strlen(left)-strlen(sexyComMarker)) . sexyComMarkerSpaced . strpart(theLine, leftAlignIndx) - - if lineHasTabs - let theLine = s:ConvertLeadingSpacesToTabs(theLine) - endif - - - " set the line and move onto the next one - call setline(currentLine, theLine) - let currentLine = currentLine + 1 - endwhile - -endfunction - -" Function: s:CommentLinesToggle(forceNested, firstLine, lastLine) {{{2 -" Applies "toggle" commenting to the given range of lines -" -" Args: -" -forceNested: a flag indicating whether the called is requesting the comment -" to be nested if need be -" -firstLine/lastLine: the top and bottom lines to comment -function s:CommentLinesToggle(forceNested, firstLine, lastLine) - let currentLine = a:firstLine - while currentLine <= a:lastLine - - " get the next line, check commentability and convert spaces to tabs - let theLine = getline(currentLine) - let lineHasLeadingTabs = s:HasLeadingTabs(theLine) - let theLine = s:ConvertLeadingTabsToSpaces(theLine) - if s:CanToggleCommentLine(a:forceNested, currentLine) - - "if the user has specified forceNesting then we check to see if we - "need to switch delimiters for place-holders - if g:NERDUsePlaceHolders - let theLine = s:SwapOutterMultiPartDelimsForPlaceHolders(theLine) - endif - - let theLine = s:AddLeftDelim(s:Left({'space': 1}), theLine) - let theLine = s:AddRightDelim(s:Right({'space': 1}), theLine) - endif - - " restore leading tabs if appropriate - if lineHasLeadingTabs - let theLine = s:ConvertLeadingSpacesToTabs(theLine) - endif - - " we are done with this line - call setline(currentLine, theLine) - let currentLine = currentLine + 1 - endwhile - -endfunction - -" Function: s:CommentRegion(topline, topCol, bottomLine, bottomCol) function {{{2 -" This function comments chunks of text selected in visual mode. -" It will comment exactly the text that they have selected. -" Args: -" -topLine: the line num of the top line in the sexy comment -" -topCol: top left col for this comment -" -bottomline: the line num of the bottom line in the sexy comment -" -bottomCol: the bottom right col for this comment -" -forceNested: whether the caller wants comments to be nested if the -" line(s) are already commented -function s:CommentRegion(topLine, topCol, bottomLine, bottomCol, forceNested) - - "switch delims (if we can) if the current set isnt multipart - let switchedDelims = 0 - if !s:Multipart() && s:AltMultipart() && !g:NERDAllowAnyVisualDelims - let switchedDelims = 1 - call s:SwitchToAlternativeDelimiters(0) - endif - - "if there is only one line in the comment then just do it - if a:topLine == a:bottomLine - call s:CommentBlock(a:topLine, a:bottomLine, a:topCol, a:bottomCol, a:forceNested) - - "there are multiple lines in the comment - else - "comment the top line - call s:CommentBlock(a:topLine, a:topLine, a:topCol, strlen(getline(a:topLine)), a:forceNested) - - "comment out all the lines in the middle of the comment - let topOfRange = a:topLine+1 - let bottomOfRange = a:bottomLine-1 - if topOfRange <= bottomOfRange - call s:CommentLines(a:forceNested, "none", topOfRange, bottomOfRange) - endif - - "comment the bottom line - let bottom = getline(a:bottomLine) - let numLeadingSpacesTabs = strlen(substitute(bottom, '^\([ \t]*\).*$', '\1', '')) - call s:CommentBlock(a:bottomLine, a:bottomLine, numLeadingSpacesTabs+1, a:bottomCol, a:forceNested) - - endif - - "stick the cursor back on the char it was on before the comment - call cursor(a:topLine, a:topCol + strlen(s:Left()) + g:NERDSpaceDelims) - - "if we switched delims then we gotta go back to what they were before - if switchedDelims == 1 - call s:SwitchToAlternativeDelimiters(0) - endif - -endfunction - -" Function: s:InvertComment(firstLine, lastLine) function {{{2 -" Inverts the comments on the lines between and including the given line -" numbers i.e all commented lines are uncommented and vice versa -" Args: -" -firstLine: the top of the range of lines to be inverted -" -lastLine: the bottom of the range of lines to be inverted -function s:InvertComment(firstLine, lastLine) - - " go thru all lines in the given range - let currentLine = a:firstLine - while currentLine <= a:lastLine - let theLine = getline(currentLine) - - let sexyComBounds = s:FindBoundingLinesOfSexyCom(currentLine) - - " if the line is commented normally, uncomment it - if s:IsCommentedFromStartOfLine(s:Left(), theLine) || s:IsCommentedFromStartOfLine(s:Left({'alt': 1}), theLine) - call s:UncommentLines(currentLine, currentLine) - let currentLine = currentLine + 1 - - " check if the line is commented sexually - elseif !empty(sexyComBounds) - let numLinesBeforeSexyComRemoved = s:NumLinesInBuf() - call s:UncommentLinesSexy(sexyComBounds[0], sexyComBounds[1]) - - "move to the line after last line of the sexy comment - let numLinesAfterSexyComRemoved = s:NumLinesInBuf() - let currentLine = sexyComBounds[1] - (numLinesBeforeSexyComRemoved - numLinesAfterSexyComRemoved) + 1 - - " the line isnt commented - else - call s:CommentLinesToggle(1, currentLine, currentLine) - let currentLine = currentLine + 1 - endif - - endwhile -endfunction - -" Function: NERDComment(isVisual, type) function {{{2 -" This function is a Wrapper for the main commenting functions -" -" Args: -" -isVisual: a flag indicating whether the comment is requested in visual -" mode or not -" -type: the type of commenting requested. Can be 'sexy', 'invert', -" 'minimal', 'toggle', 'alignLeft', 'alignBoth', 'norm', -" 'nested', 'toEOL', 'append', 'insert', 'uncomment', 'yank' -function! NERDComment(isVisual, type) range - " we want case sensitivity when commenting - let oldIgnoreCase = &ignorecase - set noignorecase - - if !exists("g:did_load_ftplugin") || g:did_load_ftplugin != 1 - call s:NerdEcho("filetype plugins should be enabled. See :help NERDComInstallation and :help :filetype-plugin-on", 0) - endif - - if a:isVisual - let firstLine = line("'<") - let lastLine = line("'>") - let firstCol = col("'<") - let lastCol = col("'>") - (&selection == 'exclusive' ? 1 : 0) - else - let firstLine = a:firstline - let lastLine = a:lastline - endif - - let countWasGiven = (a:isVisual == 0 && firstLine != lastLine) - - let forceNested = (a:type == 'nested' || g:NERDDefaultNesting) - - if a:type == 'norm' || a:type == 'nested' - if a:isVisual && visualmode() == "" - call s:CommentBlock(firstLine, lastLine, firstCol, lastCol, forceNested) - elseif a:isVisual && visualmode() == "v" && (g:NERDCommentWholeLinesInVMode==0 || (g:NERDCommentWholeLinesInVMode==2 && s:HasMultipartDelims())) - call s:CommentRegion(firstLine, firstCol, lastLine, lastCol, forceNested) - else - call s:CommentLines(forceNested, "none", firstLine, lastLine) - endif - - elseif a:type == 'alignLeft' || a:type == 'alignBoth' - let align = "none" - if a:type == "alignLeft" - let align = "left" - elseif a:type == "alignBoth" - let align = "both" - endif - call s:CommentLines(forceNested, align, firstLine, lastLine) - - elseif a:type == 'invert' - call s:InvertComment(firstLine, lastLine) - - elseif a:type == 'sexy' - try - call s:CommentLinesSexy(firstLine, lastLine) - catch /NERDCommenter.Delimiters/ - call s:CommentLines(forceNested, "none", firstLine, lastLine) - catch /NERDCommenter.Nesting/ - call s:NerdEcho("Sexy comment aborted. Nested sexy cannot be nested", 0) - endtry - - elseif a:type == 'toggle' - let theLine = getline(firstLine) - - if s:IsInSexyComment(firstLine) || s:IsCommentedFromStartOfLine(s:Left(), theLine) || s:IsCommentedFromStartOfLine(s:Left({'alt': 1}), theLine) - call s:UncommentLines(firstLine, lastLine) - else - call s:CommentLinesToggle(forceNested, firstLine, lastLine) - endif - - elseif a:type == 'minimal' - try - call s:CommentLinesMinimal(firstLine, lastLine) - catch /NERDCommenter.Delimiters/ - call s:NerdEcho("Minimal comments can only be used for filetypes that have multipart delimiters.", 0) - catch /NERDCommenter.Settings/ - call s:NerdEcho("Place holders are required but disabled.", 0) - endtry - - elseif a:type == 'toEOL' - call s:SaveScreenState() - call s:CommentBlock(firstLine, firstLine, col("."), col("$")-1, 1) - call s:RestoreScreenState() - - elseif a:type == 'append' - call s:AppendCommentToLine() - - elseif a:type == 'insert' - call s:PlaceDelimitersAndInsBetween() - - elseif a:type == 'uncomment' - call s:UncommentLines(firstLine, lastLine) - - elseif a:type == 'yank' - if a:isVisual - normal! gvy - elseif countWasGiven - execute firstLine .','. lastLine .'yank' - else - normal! yy - endif - execute firstLine .','. lastLine .'call NERDComment('. a:isVisual .', "norm")' - endif - - let &ignorecase = oldIgnoreCase -endfunction - -" Function: s:PlaceDelimitersAndInsBetween() function {{{2 -" This is function is called to place comment delimiters down and place the -" cursor between them -function s:PlaceDelimitersAndInsBetween() - " get the left and right delimiters without any escape chars in them - let left = s:Left({'space': 1}) - let right = s:Right({'space': 1}) - - let theLine = getline(".") - let lineHasLeadTabs = s:HasLeadingTabs(theLine) || (theLine =~ '^ *$' && !&expandtab) - - "convert tabs to spaces and adjust the cursors column to take this into - "account - let untabbedCol = s:UntabbedCol(theLine, col(".")) - call setline(line("."), s:ConvertLeadingTabsToSpaces(theLine)) - call cursor(line("."), untabbedCol) - - " get the len of the right delim - let lenRight = strlen(right) - - let isDelimOnEOL = col(".") >= strlen(getline(".")) - - " if the cursor is in the first col then we gotta insert rather than - " append the comment delimiters here - let insOrApp = (col(".")==1 ? 'i' : 'a') - - " place the delimiters down. We do it differently depending on whether - " there is a left AND right delimiter - if lenRight > 0 - execute ":normal! " . insOrApp . left . right - execute ":normal! " . lenRight . "h" - else - execute ":normal! " . insOrApp . left - - " if we are tacking the delim on the EOL then we gotta add a space - " after it cos when we go out of insert mode the cursor will move back - " one and the user wont be in position to type the comment. - if isDelimOnEOL - execute 'normal! a ' - endif - endif - normal! l - - "if needed convert spaces back to tabs and adjust the cursors col - "accordingly - if lineHasLeadTabs - let tabbedCol = s:TabbedCol(getline("."), col(".")) - call setline(line("."), s:ConvertLeadingSpacesToTabs(getline("."))) - call cursor(line("."), tabbedCol) - endif - - startinsert -endfunction - -" Function: s:RemoveDelimiters(left, right, line) {{{2 -" this function is called to remove the first left comment delimiter and the -" last right delimiter of the given line. -" -" The args left and right must be strings. If there is no right delimiter (as -" is the case for e.g vim file comments) them the arg right should be "" -" -" Args: -" -left: the left comment delimiter -" -right: the right comment delimiter -" -line: the line to remove the delimiters from -function s:RemoveDelimiters(left, right, line) - - let l:left = a:left - let l:right = a:right - let lenLeft = strlen(left) - let lenRight = strlen(right) - - let delimsSpaced = (g:NERDSpaceDelims || g:NERDRemoveExtraSpaces) - - let line = a:line - - "look for the left delimiter, if we find it, remove it. - let leftIndx = s:FindDelimiterIndex(a:left, line) - if leftIndx != -1 - let line = strpart(line, 0, leftIndx) . strpart(line, leftIndx+lenLeft) - - "if the user has specified that there is a space after the left delim - "then check for the space and remove it if it is there - if delimsSpaced && strpart(line, leftIndx, s:lenSpaceStr) == s:spaceStr - let line = strpart(line, 0, leftIndx) . strpart(line, leftIndx+s:lenSpaceStr) - endif - endif - - "look for the right delimiter, if we find it, remove it - let rightIndx = s:FindDelimiterIndex(a:right, line) - if rightIndx != -1 - let line = strpart(line, 0, rightIndx) . strpart(line, rightIndx+lenRight) - - "if the user has specified that there is a space before the right delim - "then check for the space and remove it if it is there - if delimsSpaced && strpart(line, rightIndx-s:lenSpaceStr, s:lenSpaceStr) == s:spaceStr && s:Multipart() - let line = strpart(line, 0, rightIndx-s:lenSpaceStr) . strpart(line, rightIndx) - endif - endif - - return line -endfunction - -" Function: s:UncommentLines(topLine, bottomLine) {{{2 -" This function uncomments the given lines -" -" Args: -" topLine: the top line of the visual selection to uncomment -" bottomLine: the bottom line of the visual selection to uncomment -function s:UncommentLines(topLine, bottomLine) - "make local copies of a:firstline and a:lastline and, if need be, swap - "them around if the top line is below the bottom - let l:firstline = a:topLine - let l:lastline = a:bottomLine - if firstline > lastline - let firstline = lastline - let lastline = a:topLine - endif - - "go thru each line uncommenting each line removing sexy comments - let currentLine = firstline - while currentLine <= lastline - - "check the current line to see if it is part of a sexy comment - let sexyComBounds = s:FindBoundingLinesOfSexyCom(currentLine) - if !empty(sexyComBounds) - - "we need to store the num lines in the buf before the comment is - "removed so we know how many lines were removed when the sexy com - "was removed - let numLinesBeforeSexyComRemoved = s:NumLinesInBuf() - - call s:UncommentLinesSexy(sexyComBounds[0], sexyComBounds[1]) - - "move to the line after last line of the sexy comment - let numLinesAfterSexyComRemoved = s:NumLinesInBuf() - let numLinesRemoved = numLinesBeforeSexyComRemoved - numLinesAfterSexyComRemoved - let currentLine = sexyComBounds[1] - numLinesRemoved + 1 - let lastline = lastline - numLinesRemoved - - "no sexy com was detected so uncomment the line as normal - else - call s:UncommentLinesNormal(currentLine, currentLine) - let currentLine = currentLine + 1 - endif - endwhile - -endfunction - -" Function: s:UncommentLinesSexy(topline, bottomline) {{{2 -" This function removes all the comment characters associated with the sexy -" comment spanning the given lines -" Args: -" -topline/bottomline: the top/bottom lines of the sexy comment -function s:UncommentLinesSexy(topline, bottomline) - let left = s:GetSexyComLeft(0,1) - let right = s:GetSexyComRight(0,1) - - - "check if it is even possible for sexy comments to exist with the - "available delimiters - if left == -1 || right == -1 - throw 'NERDCommenter.Delimiters exception: cannot uncomment sexy comments with available delimiters.' - endif - - let leftUnEsc = s:GetSexyComLeft(0,0) - let rightUnEsc = s:GetSexyComRight(0,0) - - let sexyComMarker = s:GetSexyComMarker(0, 1) - let sexyComMarkerUnEsc = s:GetSexyComMarker(0, 0) - - "the markerOffset is how far right we need to move the sexyComMarker to - "line it up with the end of the left delim - let markerOffset = strlen(leftUnEsc)-strlen(sexyComMarkerUnEsc) - - " go thru the intermediate lines of the sexy comment and remove the - " sexy comment markers (eg the '*'s on the start of line in a c sexy - " comment) - let currentLine = a:topline+1 - while currentLine < a:bottomline - let theLine = getline(currentLine) - - " remove the sexy comment marker from the line. We also remove the - " space after it if there is one and if appropriate options are set - let sexyComMarkerIndx = stridx(theLine, sexyComMarkerUnEsc) - if strpart(theLine, sexyComMarkerIndx+strlen(sexyComMarkerUnEsc), s:lenSpaceStr) == s:spaceStr && g:NERDSpaceDelims - let theLine = strpart(theLine, 0, sexyComMarkerIndx - markerOffset) . strpart(theLine, sexyComMarkerIndx+strlen(sexyComMarkerUnEsc)+s:lenSpaceStr) - else - let theLine = strpart(theLine, 0, sexyComMarkerIndx - markerOffset) . strpart(theLine, sexyComMarkerIndx+strlen(sexyComMarkerUnEsc)) - endif - - let theLine = s:SwapOutterPlaceHoldersForMultiPartDelims(theLine) - - let theLine = s:ConvertLeadingWhiteSpace(theLine) - - " move onto the next line - call setline(currentLine, theLine) - let currentLine = currentLine + 1 - endwhile - - " gotta make a copy of a:bottomline cos we modify the position of the - " last line it if we remove the topline - let bottomline = a:bottomline - - " get the first line so we can remove the left delim from it - let theLine = getline(a:topline) - - " if the first line contains only the left delim then just delete it - if theLine =~ '^[ \t]*' . left . '[ \t]*$' && !g:NERDCompactSexyComs - call cursor(a:topline, 1) - normal! dd - let bottomline = bottomline - 1 - - " topline contains more than just the left delim - else - - " remove the delim. If there is a space after it - " then remove this too if appropriate - let delimIndx = stridx(theLine, leftUnEsc) - if strpart(theLine, delimIndx+strlen(leftUnEsc), s:lenSpaceStr) == s:spaceStr && g:NERDSpaceDelims - let theLine = strpart(theLine, 0, delimIndx) . strpart(theLine, delimIndx+strlen(leftUnEsc)+s:lenSpaceStr) - else - let theLine = strpart(theLine, 0, delimIndx) . strpart(theLine, delimIndx+strlen(leftUnEsc)) - endif - let theLine = s:SwapOutterPlaceHoldersForMultiPartDelims(theLine) - call setline(a:topline, theLine) - endif - - " get the last line so we can remove the right delim - let theLine = getline(bottomline) - - " if the bottomline contains only the right delim then just delete it - if theLine =~ '^[ \t]*' . right . '[ \t]*$' - call cursor(bottomline, 1) - normal! dd - - " the last line contains more than the right delim - else - " remove the right delim. If there is a space after it and - " if the appropriate options are set then remove this too. - let delimIndx = s:LastIndexOfDelim(rightUnEsc, theLine) - if strpart(theLine, delimIndx+strlen(leftUnEsc), s:lenSpaceStr) == s:spaceStr && g:NERDSpaceDelims - let theLine = strpart(theLine, 0, delimIndx) . strpart(theLine, delimIndx+strlen(rightUnEsc)+s:lenSpaceStr) - else - let theLine = strpart(theLine, 0, delimIndx) . strpart(theLine, delimIndx+strlen(rightUnEsc)) - endif - - " if the last line also starts with a sexy comment marker then we - " remove this as well - if theLine =~ '^[ \t]*' . sexyComMarker - - " remove the sexyComMarker. If there is a space after it then - " remove that too - let sexyComMarkerIndx = stridx(theLine, sexyComMarkerUnEsc) - if strpart(theLine, sexyComMarkerIndx+strlen(sexyComMarkerUnEsc), s:lenSpaceStr) == s:spaceStr && g:NERDSpaceDelims - let theLine = strpart(theLine, 0, sexyComMarkerIndx - markerOffset ) . strpart(theLine, sexyComMarkerIndx+strlen(sexyComMarkerUnEsc)+s:lenSpaceStr) - else - let theLine = strpart(theLine, 0, sexyComMarkerIndx - markerOffset ) . strpart(theLine, sexyComMarkerIndx+strlen(sexyComMarkerUnEsc)) - endif - endif - - let theLine = s:SwapOutterPlaceHoldersForMultiPartDelims(theLine) - call setline(bottomline, theLine) - endif -endfunction - -" Function: s:UncommentLineNormal(line) {{{2 -" uncomments the given line and returns the result -" Args: -" -line: the line to uncomment -function s:UncommentLineNormal(line) - let line = a:line - - "get the comment status on the line so we know how it is commented - let lineCommentStatus = s:IsCommentedOuttermost(s:Left(), s:Right(), s:Left({'alt': 1}), s:Right({'alt': 1}), line) - - "it is commented with s:Left() and s:Right() so remove these delims - if lineCommentStatus == 1 - let line = s:RemoveDelimiters(s:Left(), s:Right(), line) - - "it is commented with s:Left({'alt': 1}) and s:Right({'alt': 1}) so remove these delims - elseif lineCommentStatus == 2 && g:NERDRemoveAltComs - let line = s:RemoveDelimiters(s:Left({'alt': 1}), s:Right({'alt': 1}), line) - - "it is not properly commented with any delims so we check if it has - "any random left or right delims on it and remove the outtermost ones - else - "get the positions of all delim types on the line - let indxLeft = s:FindDelimiterIndex(s:Left(), line) - let indxLeftAlt = s:FindDelimiterIndex(s:Left({'alt': 1}), line) - let indxRight = s:FindDelimiterIndex(s:Right(), line) - let indxRightAlt = s:FindDelimiterIndex(s:Right({'alt': 1}), line) - - "remove the outter most left comment delim - if indxLeft != -1 && (indxLeft < indxLeftAlt || indxLeftAlt == -1) - let line = s:RemoveDelimiters(s:Left(), '', line) - elseif indxLeftAlt != -1 - let line = s:RemoveDelimiters(s:Left({'alt': 1}), '', line) - endif - - "remove the outter most right comment delim - if indxRight != -1 && (indxRight < indxRightAlt || indxRightAlt == -1) - let line = s:RemoveDelimiters('', s:Right(), line) - elseif indxRightAlt != -1 - let line = s:RemoveDelimiters('', s:Right({'alt': 1}), line) - endif - endif - - - let indxLeft = s:FindDelimiterIndex(s:Left(), line) - let indxLeftAlt = s:FindDelimiterIndex(s:Left({'alt': 1}), line) - let indxLeftPlace = s:FindDelimiterIndex(g:NERDLPlace, line) - - let indxRightPlace = s:FindDelimiterIndex(g:NERDRPlace, line) - let indxRightAlt = s:FindDelimiterIndex(s:Right({'alt': 1}), line) - let indxRightPlace = s:FindDelimiterIndex(g:NERDRPlace, line) - - let right = s:Right() - let left = s:Left() - if !s:Multipart() - let right = s:Right({'alt': 1}) - let left = s:Left({'alt': 1}) - endif - - - "if there are place-holders on the line then we check to see if they are - "the outtermost delimiters on the line. If so then we replace them with - "real delimiters - if indxLeftPlace != -1 - if (indxLeftPlace < indxLeft || indxLeft==-1) && (indxLeftPlace < indxLeftAlt || indxLeftAlt==-1) - let line = s:ReplaceDelims(g:NERDLPlace, g:NERDRPlace, left, right, line) - endif - elseif indxRightPlace != -1 - if (indxRightPlace < indxLeft || indxLeft==-1) && (indxLeftPlace < indxLeftAlt || indxLeftAlt==-1) - let line = s:ReplaceDelims(g:NERDLPlace, g:NERDRPlace, left, right, line) - endif - - endif - - let line = s:ConvertLeadingWhiteSpace(line) - - return line -endfunction - -" Function: s:UncommentLinesNormal(topline, bottomline) {{{2 -" This function is called to uncomment lines that arent a sexy comment -" Args: -" -topline/bottomline: the top/bottom line numbers of the comment -function s:UncommentLinesNormal(topline, bottomline) - let currentLine = a:topline - while currentLine <= a:bottomline - let line = getline(currentLine) - call setline(currentLine, s:UncommentLineNormal(line)) - let currentLine = currentLine + 1 - endwhile -endfunction - - -" Section: Other helper functions {{{1 -" ============================================================================ - -" Function: s:AddLeftDelim(delim, theLine) {{{2 -" Args: -function s:AddLeftDelim(delim, theLine) - return substitute(a:theLine, '^\([ \t]*\)', '\1' . a:delim, '') -endfunction - -" Function: s:AddLeftDelimAligned(delim, theLine) {{{2 -" Args: -function s:AddLeftDelimAligned(delim, theLine, alignIndx) - - "if the line is not long enough then bung some extra spaces on the front - "so we can align the delim properly - let theLine = a:theLine - if strlen(theLine) < a:alignIndx - let theLine = repeat(' ', a:alignIndx - strlen(theLine)) - endif - - return strpart(theLine, 0, a:alignIndx) . a:delim . strpart(theLine, a:alignIndx) -endfunction - -" Function: s:AddRightDelim(delim, theLine) {{{2 -" Args: -function s:AddRightDelim(delim, theLine) - if a:delim == '' - return a:theLine - else - return substitute(a:theLine, '$', a:delim, '') - endif -endfunction - -" Function: s:AddRightDelimAligned(delim, theLine, alignIndx) {{{2 -" Args: -function s:AddRightDelimAligned(delim, theLine, alignIndx) - if a:delim == "" - return a:theLine - else - - " when we align the right delim we are just adding spaces - " so we get a string containing the needed spaces (it - " could be empty) - let extraSpaces = '' - let extraSpaces = repeat(' ', a:alignIndx-strlen(a:theLine)) - - " add the right delim - return substitute(a:theLine, '$', extraSpaces . a:delim, '') - endif -endfunction - -" Function: s:AltMultipart() {{{2 -" returns 1 if the alternative delims are multipart -function s:AltMultipart() - return b:NERDCommenterDelims['rightAlt'] != '' -endfunction - -" Function: s:CanCommentLine(forceNested, line) {{{2 -"This function is used to determine whether the given line can be commented. -"It returns 1 if it can be and 0 otherwise -" -" Args: -" -forceNested: a flag indicating whether the caller wants comments to be nested -" if the current line is already commented -" -lineNum: the line num of the line to check for commentability -function s:CanCommentLine(forceNested, lineNum) - let theLine = getline(a:lineNum) - - " make sure we don't comment lines that are just spaces or tabs or empty. - if theLine =~ "^[ \t]*$" - return 0 - endif - - "if the line is part of a sexy comment then just flag it... - if s:IsInSexyComment(a:lineNum) - return 0 - endif - - let isCommented = s:IsCommentedNormOrSexy(a:lineNum) - - "if the line isnt commented return true - if !isCommented - return 1 - endif - - "if the line is commented but nesting is allowed then return true - if a:forceNested && (!s:Multipart() || g:NERDUsePlaceHolders) - return 1 - endif - - return 0 -endfunction - -" Function: s:CanPlaceCursor(line, col) {{{2 -" returns 1 if the cursor can be placed exactly in the given position -function s:CanPlaceCursor(line, col) - let c = col(".") - let l = line(".") - call cursor(a:line, a:col) - let success = (line(".") == a:line && col(".") == a:col) - call cursor(l,c) - return success -endfunction - -" Function: s:CanSexyCommentLines(topline, bottomline) {{{2 -" Return: 1 if the given lines can be commented sexually, 0 otherwise -function s:CanSexyCommentLines(topline, bottomline) - " see if the selected regions have any sexy comments - let currentLine = a:topline - while(currentLine <= a:bottomline) - if s:IsInSexyComment(currentLine) - return 0 - endif - let currentLine = currentLine + 1 - endwhile - return 1 -endfunction -" Function: s:CanToggleCommentLine(forceNested, line) {{{2 -"This function is used to determine whether the given line can be toggle commented. -"It returns 1 if it can be and 0 otherwise -" -" Args: -" -lineNum: the line num of the line to check for commentability -function s:CanToggleCommentLine(forceNested, lineNum) - let theLine = getline(a:lineNum) - if (s:IsCommentedFromStartOfLine(s:Left(), theLine) || s:IsCommentedFromStartOfLine(s:Left({'alt': 1}), theLine)) && !a:forceNested - return 0 - endif - - " make sure we don't comment lines that are just spaces or tabs or empty. - if theLine =~ "^[ \t]*$" - return 0 - endif - - "if the line is part of a sexy comment then just flag it... - if s:IsInSexyComment(a:lineNum) - return 0 - endif - - return 1 -endfunction - -" Function: s:ConvertLeadingSpacesToTabs(line) {{{2 -" This function takes a line and converts all leading tabs on that line into -" spaces -" -" Args: -" -line: the line whose leading tabs will be converted -function s:ConvertLeadingSpacesToTabs(line) - let toReturn = a:line - while toReturn =~ '^\t*' . s:TabSpace() . '\(.*\)$' - let toReturn = substitute(toReturn, '^\(\t*\)' . s:TabSpace() . '\(.*\)$' , '\1\t\2' , "") - endwhile - - return toReturn -endfunction - - -" Function: s:ConvertLeadingTabsToSpaces(line) {{{2 -" This function takes a line and converts all leading spaces on that line into -" tabs -" -" Args: -" -line: the line whose leading spaces will be converted -function s:ConvertLeadingTabsToSpaces(line) - let toReturn = a:line - while toReturn =~ '^\( *\)\t' - let toReturn = substitute(toReturn, '^\( *\)\t', '\1' . s:TabSpace() , "") - endwhile - - return toReturn -endfunction - -" Function: s:ConvertLeadingWhiteSpace(line) {{{2 -" Converts the leading white space to tabs/spaces depending on &ts -" -" Args: -" -line: the line to convert -function s:ConvertLeadingWhiteSpace(line) - let toReturn = a:line - while toReturn =~ '^ *\t' - let toReturn = substitute(toReturn, '^ *\zs\t\ze', s:TabSpace(), "g") - endwhile - - if !&expandtab - let toReturn = s:ConvertLeadingSpacesToTabs(toReturn) - endif - - return toReturn -endfunction - - -" Function: s:CountNonESCedOccurances(str, searchstr, escChar) {{{2 -" This function counts the number of substrings contained in another string. -" These substrings are only counted if they are not escaped with escChar -" Args: -" -str: the string to look for searchstr in -" -searchstr: the substring to search for in str -" -escChar: the escape character which, when preceding an instance of -" searchstr, will cause it not to be counted -function s:CountNonESCedOccurances(str, searchstr, escChar) - "get the index of the first occurrence of searchstr - let indx = stridx(a:str, a:searchstr) - - "if there is an instance of searchstr in str process it - if indx != -1 - "get the remainder of str after this instance of searchstr is removed - let lensearchstr = strlen(a:searchstr) - let strLeft = strpart(a:str, indx+lensearchstr) - - "if this instance of searchstr is not escaped, add one to the count - "and recurse. If it is escaped, just recurse - if !s:IsEscaped(a:str, indx, a:escChar) - return 1 + s:CountNonESCedOccurances(strLeft, a:searchstr, a:escChar) - else - return s:CountNonESCedOccurances(strLeft, a:searchstr, a:escChar) - endif - endif -endfunction -" Function: s:DoesBlockHaveDelim(delim, top, bottom) {{{2 -" Returns 1 if the given block of lines has a delimiter (a:delim) in it -" Args: -" -delim: the comment delimiter to check the block for -" -top: the top line number of the block -" -bottom: the bottom line number of the block -function s:DoesBlockHaveDelim(delim, top, bottom) - let currentLine = a:top - while currentLine < a:bottom - let theline = getline(currentLine) - if s:FindDelimiterIndex(a:delim, theline) != -1 - return 1 - endif - let currentLine = currentLine + 1 - endwhile - return 0 -endfunction - -" Function: s:DoesBlockHaveMultipartDelim(top, bottom) {{{2 -" Returns 1 if the given block has a >= 1 multipart delimiter in it -" Args: -" -top: the top line number of the block -" -bottom: the bottom line number of the block -function s:DoesBlockHaveMultipartDelim(top, bottom) - if s:HasMultipartDelims() - if s:Multipart() - return s:DoesBlockHaveDelim(s:Left(), a:top, a:bottom) || s:DoesBlockHaveDelim(s:Right(), a:top, a:bottom) - else - return s:DoesBlockHaveDelim(s:Left({'alt': 1}), a:top, a:bottom) || s:DoesBlockHaveDelim(s:Right({'alt': 1}), a:top, a:bottom) - endif - endif - return 0 -endfunction - - -" Function: s:Esc(str) {{{2 -" Escapes all the tricky chars in the given string -function s:Esc(str) - let charsToEsc = '*/\."&$+' - return escape(a:str, charsToEsc) -endfunction - -" Function: s:FindDelimiterIndex(delimiter, line) {{{2 -" This function is used to get the string index of the input comment delimiter -" on the input line. If no valid comment delimiter is found in the line then -" -1 is returned -" Args: -" -delimiter: the delimiter we are looking to find the index of -" -line: the line we are looking for delimiter on -function s:FindDelimiterIndex(delimiter, line) - - "make sure the delimiter isnt empty otherwise we go into an infinite loop. - if a:delimiter == "" - return -1 - endif - - - let l:delimiter = a:delimiter - let lenDel = strlen(l:delimiter) - - "get the index of the first occurrence of the delimiter - let delIndx = stridx(a:line, l:delimiter) - - "keep looping thru the line till we either find a real comment delimiter - "or run off the EOL - while delIndx != -1 - - "if we are not off the EOL get the str before the possible delimiter - "in question and check if it really is a delimiter. If it is, return - "its position - if delIndx != -1 - if s:IsDelimValid(l:delimiter, delIndx, a:line) - return delIndx - endif - endif - - "we have not yet found a real comment delimiter so move past the - "current one we are lookin at - let restOfLine = strpart(a:line, delIndx + lenDel) - let distToNextDelim = stridx(restOfLine , l:delimiter) - - "if distToNextDelim is -1 then there is no more potential delimiters - "on the line so set delIndx to -1. Otherwise, move along the line by - "distToNextDelim - if distToNextDelim == -1 - let delIndx = -1 - else - let delIndx = delIndx + lenDel + distToNextDelim - endif - endwhile - - "there is no comment delimiter on this line - return -1 -endfunction - -" Function: s:FindBoundingLinesOfSexyCom(lineNum) {{{2 -" This function takes in a line number and tests whether this line number is -" the top/bottom/middle line of a sexy comment. If it is then the top/bottom -" lines of the sexy comment are returned -" Args: -" -lineNum: the line number that is to be tested whether it is the -" top/bottom/middle line of a sexy com -" Returns: -" A string that has the top/bottom lines of the sexy comment encoded in it. -" The format is 'topline,bottomline'. If a:lineNum turns out not to be the -" top/bottom/middle of a sexy comment then -1 is returned -function s:FindBoundingLinesOfSexyCom(lineNum) - - "find which delimiters to look for as the start/end delims of the comment - let left = '' - let right = '' - if s:Multipart() - let left = s:Left({'esc': 1}) - let right = s:Right({'esc': 1}) - elseif s:AltMultipart() - let left = s:Left({'alt': 1, 'esc': 1}) - let right = s:Right({'alt': 1, 'esc': 1}) - else - return [] - endif - - let sexyComMarker = s:GetSexyComMarker(0, 1) - - "initialise the top/bottom line numbers of the sexy comment to -1 - let top = -1 - let bottom = -1 - - let currentLine = a:lineNum - while top == -1 || bottom == -1 - let theLine = getline(currentLine) - - "check if the current line is the top of the sexy comment - if currentLine <= a:lineNum && theLine =~ '^[ \t]*' . left && theLine !~ '.*' . right && currentLine < s:NumLinesInBuf() - let top = currentLine - let currentLine = a:lineNum - - "check if the current line is the bottom of the sexy comment - elseif theLine =~ '^[ \t]*' . right && theLine !~ '.*' . left && currentLine > 1 - let bottom = currentLine - - "the right delimiter is on the same line as the last sexyComMarker - elseif theLine =~ '^[ \t]*' . sexyComMarker . '.*' . right - let bottom = currentLine - - "we have not found the top or bottom line so we assume currentLine is an - "intermediate line and look to prove otherwise - else - - "if the line doesnt start with a sexyComMarker then it is not a sexy - "comment - if theLine !~ '^[ \t]*' . sexyComMarker - return [] - endif - - endif - - "if top is -1 then we havent found the top yet so keep looking up - if top == -1 - let currentLine = currentLine - 1 - "if we have found the top line then go down looking for the bottom - else - let currentLine = currentLine + 1 - endif - - endwhile - - return [top, bottom] -endfunction - - -" Function: s:GetSexyComMarker() {{{2 -" Returns the sexy comment marker for the current filetype. -" -" C style sexy comments are assumed if possible. If not then the sexy comment -" marker is the last char of the delimiter pair that has both left and right -" delims and has the longest left delim -" -" Args: -" -space: specifies whether the marker is to have a space string after it -" (the space string will only be added if NERDSpaceDelims is set) -" -esc: specifies whether the tricky chars in the marker are to be ESCed -function s:GetSexyComMarker(space, esc) - let sexyComMarker = b:NERDSexyComMarker - - "if there is no hardcoded marker then we find one - if sexyComMarker == '' - - "if the filetype has c style comments then use standard c sexy - "comments - if s:HasCStyleComments() - let sexyComMarker = '*' - else - "find a comment marker by getting the longest available left delim - "(that has a corresponding right delim) and taking the last char - let lenLeft = strlen(s:Left()) - let lenLeftAlt = strlen(s:Left({'alt': 1})) - let left = '' - let right = '' - if s:Multipart() && lenLeft >= lenLeftAlt - let left = s:Left() - elseif s:AltMultipart() - let left = s:Left({'alt': 1}) - else - return -1 - endif - - "get the last char of left - let sexyComMarker = strpart(left, strlen(left)-1) - endif - endif - - if a:space && g:NERDSpaceDelims - let sexyComMarker = sexyComMarker . s:spaceStr - endif - - if a:esc - let sexyComMarker = s:Esc(sexyComMarker) - endif - - return sexyComMarker -endfunction - -" Function: s:GetSexyComLeft(space, esc) {{{2 -" Returns the left delimiter for sexy comments for this filetype or -1 if -" there is none. C style sexy comments are used if possible -" Args: -" -space: specifies if the delim has a space string on the end -" (the space string will only be added if NERDSpaceDelims is set) -" -esc: specifies whether the tricky chars in the string are ESCed -function s:GetSexyComLeft(space, esc) - let lenLeft = strlen(s:Left()) - let lenLeftAlt = strlen(s:Left({'alt': 1})) - let left = '' - - "assume c style sexy comments if possible - if s:HasCStyleComments() - let left = '/*' - else - "grab the longest left delim that has a right - if s:Multipart() && lenLeft >= lenLeftAlt - let left = s:Left() - elseif s:AltMultipart() - let left = s:Left({'alt': 1}) - else - return -1 - endif - endif - - if a:space && g:NERDSpaceDelims - let left = left . s:spaceStr - endif - - if a:esc - let left = s:Esc(left) - endif - - return left -endfunction - -" Function: s:GetSexyComRight(space, esc) {{{2 -" Returns the right delimiter for sexy comments for this filetype or -1 if -" there is none. C style sexy comments are used if possible. -" Args: -" -space: specifies if the delim has a space string on the start -" (the space string will only be added if NERDSpaceDelims -" is specified for the current filetype) -" -esc: specifies whether the tricky chars in the string are ESCed -function s:GetSexyComRight(space, esc) - let lenLeft = strlen(s:Left()) - let lenLeftAlt = strlen(s:Left({'alt': 1})) - let right = '' - - "assume c style sexy comments if possible - if s:HasCStyleComments() - let right = '*/' - else - "grab the right delim that pairs with the longest left delim - if s:Multipart() && lenLeft >= lenLeftAlt - let right = s:Right() - elseif s:AltMultipart() - let right = s:Right({'alt': 1}) - else - return -1 - endif - endif - - if a:space && g:NERDSpaceDelims - let right = s:spaceStr . right - endif - - if a:esc - let right = s:Esc(right) - endif - - return right -endfunction - -" Function: s:HasMultipartDelims() {{{2 -" Returns 1 iff the current filetype has at least one set of multipart delims -function s:HasMultipartDelims() - return s:Multipart() || s:AltMultipart() -endfunction - -" Function: s:HasLeadingTabs(...) {{{2 -" Returns 1 if any of the given strings have leading tabs -function s:HasLeadingTabs(...) - for s in a:000 - if s =~ '^\t.*' - return 1 - end - endfor - return 0 -endfunction -" Function: s:HasCStyleComments() {{{2 -" Returns 1 iff the current filetype has c style comment delimiters -function s:HasCStyleComments() - return (s:Left() == '/*' && s:Right() == '*/') || (s:Left({'alt': 1}) == '/*' && s:Right({'alt': 1}) == '*/') -endfunction - -" Function: s:IsCommentedNormOrSexy(lineNum) {{{2 -"This function is used to determine whether the given line is commented with -"either set of delimiters or if it is part of a sexy comment -" -" Args: -" -lineNum: the line number of the line to check -function s:IsCommentedNormOrSexy(lineNum) - let theLine = getline(a:lineNum) - - "if the line is commented normally return 1 - if s:IsCommented(s:Left(), s:Right(), theLine) || s:IsCommented(s:Left({'alt': 1}), s:Right({'alt': 1}), theLine) - return 1 - endif - - "if the line is part of a sexy comment return 1 - if s:IsInSexyComment(a:lineNum) - return 1 - endif - return 0 -endfunction - -" Function: s:IsCommented(left, right, line) {{{2 -"This function is used to determine whether the given line is commented with -"the given delimiters -" -" Args: -" -line: the line that to check if commented -" -left/right: the left and right delimiters to check for -function s:IsCommented(left, right, line) - "if the line isnt commented return true - if s:FindDelimiterIndex(a:left, a:line) != -1 && (s:FindDelimiterIndex(a:right, a:line) != -1 || !s:Multipart()) - return 1 - endif - return 0 -endfunction - -" Function: s:IsCommentedFromStartOfLine(left, line) {{{2 -"This function is used to determine whether the given line is commented with -"the given delimiters at the start of the line i.e the left delimiter is the -"first thing on the line (apart from spaces\tabs) -" -" Args: -" -line: the line that to check if commented -" -left: the left delimiter to check for -function s:IsCommentedFromStartOfLine(left, line) - let theLine = s:ConvertLeadingTabsToSpaces(a:line) - let numSpaces = strlen(substitute(theLine, '^\( *\).*$', '\1', '')) - let delimIndx = s:FindDelimiterIndex(a:left, theLine) - return delimIndx == numSpaces -endfunction - -" Function: s:IsCommentedOuttermost(left, right, leftAlt, rightAlt, line) {{{2 -" Finds the type of the outtermost delims on the line -" -" Args: -" -line: the line that to check if the outtermost comments on it are -" left/right -" -left/right: the left and right delimiters to check for -" -leftAlt/rightAlt: the left and right alternative delimiters to check for -" -" Returns: -" 0 if the line is not commented with either set of delims -" 1 if the line is commented with the left/right delim set -" 2 if the line is commented with the leftAlt/rightAlt delim set -function s:IsCommentedOuttermost(left, right, leftAlt, rightAlt, line) - "get the first positions of the left delims and the last positions of the - "right delims - let indxLeft = s:FindDelimiterIndex(a:left, a:line) - let indxLeftAlt = s:FindDelimiterIndex(a:leftAlt, a:line) - let indxRight = s:LastIndexOfDelim(a:right, a:line) - let indxRightAlt = s:LastIndexOfDelim(a:rightAlt, a:line) - - "check if the line has a left delim before a leftAlt delim - if (indxLeft <= indxLeftAlt || indxLeftAlt == -1) && indxLeft != -1 - "check if the line has a right delim after any rightAlt delim - if (indxRight > indxRightAlt && indxRight > indxLeft) || !s:Multipart() - return 1 - endif - - "check if the line has a leftAlt delim before a left delim - elseif (indxLeftAlt <= indxLeft || indxLeft == -1) && indxLeftAlt != -1 - "check if the line has a rightAlt delim after any right delim - if (indxRightAlt > indxRight && indxRightAlt > indxLeftAlt) || !s:AltMultipart() - return 2 - endif - else - return 0 - endif - - return 0 - -endfunction - - -" Function: s:IsDelimValid(delimiter, delIndx, line) {{{2 -" This function is responsible for determining whether a given instance of a -" comment delimiter is a real delimiter or not. For example, in java the -" // string is a comment delimiter but in the line: -" System.out.println("//"); -" it does not count as a comment delimiter. This function is responsible for -" distinguishing between such cases. It does so by applying a set of -" heuristics that are not fool proof but should work most of the time. -" -" Args: -" -delimiter: the delimiter we are validating -" -delIndx: the position of delimiter in line -" -line: the line that delimiter occurs in -" -" Returns: -" 0 if the given delimiter is not a real delimiter (as far as we can tell) , -" 1 otherwise -function s:IsDelimValid(delimiter, delIndx, line) - "get the delimiter without the escchars - let l:delimiter = a:delimiter - - "get the strings before and after the delimiter - let preComStr = strpart(a:line, 0, a:delIndx) - let postComStr = strpart(a:line, a:delIndx+strlen(delimiter)) - - "to check if the delimiter is real, make sure it isnt preceded by - "an odd number of quotes and followed by the same (which would indicate - "that it is part of a string and therefore is not a comment) - if !s:IsNumEven(s:CountNonESCedOccurances(preComStr, '"', "\\")) && !s:IsNumEven(s:CountNonESCedOccurances(postComStr, '"', "\\")) - return 0 - endif - if !s:IsNumEven(s:CountNonESCedOccurances(preComStr, "'", "\\")) && !s:IsNumEven(s:CountNonESCedOccurances(postComStr, "'", "\\")) - return 0 - endif - if !s:IsNumEven(s:CountNonESCedOccurances(preComStr, "`", "\\")) && !s:IsNumEven(s:CountNonESCedOccurances(postComStr, "`", "\\")) - return 0 - endif - - - "if the comment delimiter is escaped, assume it isnt a real delimiter - if s:IsEscaped(a:line, a:delIndx, "\\") - return 0 - endif - - "vim comments are so fuckin stupid!! Why the hell do they have comment - "delimiters that are used elsewhere in the syntax?!?! We need to check - "some conditions especially for vim - if &filetype == "vim" - if !s:IsNumEven(s:CountNonESCedOccurances(preComStr, '"', "\\")) - return 0 - endif - - "if the delimiter is on the very first char of the line or is the - "first non-tab/space char on the line then it is a valid comment delimiter - if a:delIndx == 0 || a:line =~ "^[ \t]\\{" . a:delIndx . "\\}\".*$" - return 1 - endif - - let numLeftParen =s:CountNonESCedOccurances(preComStr, "(", "\\") - let numRightParen =s:CountNonESCedOccurances(preComStr, ")", "\\") - - "if the quote is inside brackets then assume it isnt a comment - if numLeftParen > numRightParen - return 0 - endif - - "if the line has an even num of unescaped "'s then we can assume that - "any given " is not a comment delimiter - if s:IsNumEven(s:CountNonESCedOccurances(a:line, "\"", "\\")) - return 0 - endif - endif - - return 1 - -endfunction - -" Function: s:IsNumEven(num) {{{2 -" A small function the returns 1 if the input number is even and 0 otherwise -" Args: -" -num: the number to check -function s:IsNumEven(num) - return (a:num % 2) == 0 -endfunction - -" Function: s:IsEscaped(str, indx, escChar) {{{2 -" This function takes a string, an index into that string and an esc char and -" returns 1 if the char at the index is escaped (i.e if it is preceded by an -" odd number of esc chars) -" Args: -" -str: the string to check -" -indx: the index into str that we want to check -" -escChar: the escape char the char at indx may be ESCed with -function s:IsEscaped(str, indx, escChar) - "initialise numEscChars to 0 and look at the char before indx - let numEscChars = 0 - let curIndx = a:indx-1 - - "keep going back thru str until we either reach the start of the str or - "run out of esc chars - while curIndx >= 0 && strpart(a:str, curIndx, 1) == a:escChar - - "we have found another esc char so add one to the count and move left - "one char - let numEscChars = numEscChars + 1 - let curIndx = curIndx - 1 - - endwhile - - "if there is an odd num of esc chars directly before the char at indx then - "the char at indx is escaped - return !s:IsNumEven(numEscChars) -endfunction - -" Function: s:IsInSexyComment(line) {{{2 -" returns 1 if the given line number is part of a sexy comment -function s:IsInSexyComment(line) - return !empty(s:FindBoundingLinesOfSexyCom(a:line)) -endfunction - -" Function: s:IsSexyComment(topline, bottomline) {{{2 -" This function takes in 2 line numbers and returns 1 if the lines between and -" including the given line numbers are a sexy comment. It returns 0 otherwise. -" Args: -" -topline: the line that the possible sexy comment starts on -" -bottomline: the line that the possible sexy comment stops on -function s:IsSexyComment(topline, bottomline) - - "get the delim set that would be used for a sexy comment - let left = '' - let right = '' - if s:Multipart() - let left = s:Left() - let right = s:Right() - elseif s:AltMultipart() - let left = s:Left({'alt': 1}) - let right = s:Right({'alt': 1}) - else - return 0 - endif - - "swap the top and bottom line numbers around if need be - let topline = a:topline - let bottomline = a:bottomline - if bottomline < topline - topline = bottomline - bottomline = a:topline - endif - - "if there is < 2 lines in the comment it cannot be sexy - if (bottomline - topline) <= 0 - return 0 - endif - - "if the top line doesnt begin with a left delim then the comment isnt sexy - if getline(a:topline) !~ '^[ \t]*' . left - return 0 - endif - - "if there is a right delim on the top line then this isnt a sexy comment - if s:FindDelimiterIndex(right, getline(a:topline)) != -1 - return 0 - endif - - "if there is a left delim on the bottom line then this isnt a sexy comment - if s:FindDelimiterIndex(left, getline(a:bottomline)) != -1 - return 0 - endif - - "if the bottom line doesnt begin with a right delim then the comment isnt - "sexy - if getline(a:bottomline) !~ '^.*' . right . '$' - return 0 - endif - - let sexyComMarker = s:GetSexyComMarker(0, 1) - - "check each of the intermediate lines to make sure they start with a - "sexyComMarker - let currentLine = a:topline+1 - while currentLine < a:bottomline - let theLine = getline(currentLine) - - if theLine !~ '^[ \t]*' . sexyComMarker - return 0 - endif - - "if there is a right delim in an intermediate line then the block isnt - "a sexy comment - if s:FindDelimiterIndex(right, theLine) != -1 - return 0 - endif - - let currentLine = currentLine + 1 - endwhile - - "we have not found anything to suggest that this isnt a sexy comment so - return 1 - -endfunction - -" Function: s:LastIndexOfDelim(delim, str) {{{2 -" This function takes a string and a delimiter and returns the last index of -" that delimiter in string -" Args: -" -delim: the delimiter to look for -" -str: the string to look for delim in -function s:LastIndexOfDelim(delim, str) - let delim = a:delim - let lenDelim = strlen(delim) - - "set index to the first occurrence of delim. If there is no occurrence then - "bail - let indx = s:FindDelimiterIndex(delim, a:str) - if indx == -1 - return -1 - endif - - "keep moving to the next instance of delim in str till there is none left - while 1 - - "search for the next delim after the previous one - let searchStr = strpart(a:str, indx+lenDelim) - let indx2 = s:FindDelimiterIndex(delim, searchStr) - - "if we find a delim update indx to record the position of it, if we - "dont find another delim then indx is the last one so break out of - "this loop - if indx2 != -1 - let indx = indx + indx2 + lenDelim - else - break - endif - endwhile - - return indx - -endfunction - -" Function: s:Left(...) {{{2 -" returns left delimiter data -function s:Left(...) - let params = a:0 ? a:1 : {} - - let delim = has_key(params, 'alt') ? b:NERDCommenterDelims['leftAlt'] : b:NERDCommenterDelims['left'] - - if delim == '' - return '' - endif - - if has_key(params, 'space') && g:NERDSpaceDelims - let delim = delim . s:spaceStr - endif - - if has_key(params, 'esc') - let delim = s:Esc(delim) - endif - - return delim -endfunction - -" Function: s:LeftMostIndx(countCommentedLines, countEmptyLines, topline, bottomline) {{{2 -" This function takes in 2 line numbers and returns the index of the left most -" char (that is not a space or a tab) on all of these lines. -" Args: -" -countCommentedLines: 1 if lines that are commented are to be checked as -" well. 0 otherwise -" -countEmptyLines: 1 if empty lines are to be counted in the search -" -topline: the top line to be checked -" -bottomline: the bottom line to be checked -function s:LeftMostIndx(countCommentedLines, countEmptyLines, topline, bottomline) - - " declare the left most index as an extreme value - let leftMostIndx = 1000 - - " go thru the block line by line updating leftMostIndx - let currentLine = a:topline - while currentLine <= a:bottomline - - " get the next line and if it is allowed to be commented, or is not - " commented, check it - let theLine = getline(currentLine) - if a:countEmptyLines || theLine !~ '^[ \t]*$' - if a:countCommentedLines || (!s:IsCommented(s:Left(), s:Right(), theLine) && !s:IsCommented(s:Left({'alt': 1}), s:Right({'alt': 1}), theLine)) - " convert spaces to tabs and get the number of leading spaces for - " this line and update leftMostIndx if need be - let theLine = s:ConvertLeadingTabsToSpaces(theLine) - let leadSpaceOfLine = strlen( substitute(theLine, '\(^[ \t]*\).*$','\1','') ) - if leadSpaceOfLine < leftMostIndx - let leftMostIndx = leadSpaceOfLine - endif - endif - endif - - " move on to the next line - let currentLine = currentLine + 1 - endwhile - - if leftMostIndx == 1000 - return 0 - else - return leftMostIndx - endif -endfunction - -" Function: s:Multipart() {{{2 -" returns 1 if the current delims are multipart -function s:Multipart() - return s:Right() != '' -endfunction - -" Function: s:NerdEcho(msg, typeOfMsg) {{{2 -" Args: -" -msg: the message to echo -" -typeOfMsg: 0 = warning message -" 1 = normal message -function s:NerdEcho(msg, typeOfMsg) - if a:typeOfMsg == 0 - echohl WarningMsg - echom 'NERDCommenter:' . a:msg - echohl None - elseif a:typeOfMsg == 1 - echom 'NERDCommenter:' . a:msg - endif -endfunction - -" Function: s:NumberOfLeadingTabs(s) {{{2 -" returns the number of leading tabs in the given string -function s:NumberOfLeadingTabs(s) - return strlen(substitute(a:s, '^\(\t*\).*$', '\1', "")) -endfunction - -" Function: s:NumLinesInBuf() {{{2 -" Returns the number of lines in the current buffer -function s:NumLinesInBuf() - return line('$') -endfunction - -" Function: s:ReplaceDelims(toReplace1, toReplace2, replacor1, replacor2, str) {{{2 -" This function takes in a string, 2 delimiters in that string and 2 strings -" to replace these delimiters with. -" -" Args: -" -toReplace1: the first delimiter to replace -" -toReplace2: the second delimiter to replace -" -replacor1: the string to replace toReplace1 with -" -replacor2: the string to replace toReplace2 with -" -str: the string that the delimiters to be replaced are in -function s:ReplaceDelims(toReplace1, toReplace2, replacor1, replacor2, str) - let line = s:ReplaceLeftMostDelim(a:toReplace1, a:replacor1, a:str) - let line = s:ReplaceRightMostDelim(a:toReplace2, a:replacor2, line) - return line -endfunction - -" Function: s:ReplaceLeftMostDelim(toReplace, replacor, str) {{{2 -" This function takes a string and a delimiter and replaces the left most -" occurrence of this delimiter in the string with a given string -" -" Args: -" -toReplace: the delimiter in str that is to be replaced -" -replacor: the string to replace toReplace with -" -str: the string that contains toReplace -function s:ReplaceLeftMostDelim(toReplace, replacor, str) - let toReplace = a:toReplace - let replacor = a:replacor - "get the left most occurrence of toReplace - let indxToReplace = s:FindDelimiterIndex(toReplace, a:str) - - "if there IS an occurrence of toReplace in str then replace it and return - "the resulting string - if indxToReplace != -1 - let line = strpart(a:str, 0, indxToReplace) . replacor . strpart(a:str, indxToReplace+strlen(toReplace)) - return line - endif - - return a:str -endfunction - -" Function: s:ReplaceRightMostDelim(toReplace, replacor, str) {{{2 -" This function takes a string and a delimiter and replaces the right most -" occurrence of this delimiter in the string with a given string -" -" Args: -" -toReplace: the delimiter in str that is to be replaced -" -replacor: the string to replace toReplace with -" -str: the string that contains toReplace -" -function s:ReplaceRightMostDelim(toReplace, replacor, str) - let toReplace = a:toReplace - let replacor = a:replacor - let lenToReplace = strlen(toReplace) - - "get the index of the last delim in str - let indxToReplace = s:LastIndexOfDelim(toReplace, a:str) - - "if there IS a delimiter in str, replace it and return the result - let line = a:str - if indxToReplace != -1 - let line = strpart(a:str, 0, indxToReplace) . replacor . strpart(a:str, indxToReplace+strlen(toReplace)) - endif - return line -endfunction - -"FUNCTION: s:RestoreScreenState() {{{2 -" -"Sets the screen state back to what it was when s:SaveScreenState was last -"called. -" -function s:RestoreScreenState() - if !exists("t:NERDComOldTopLine") || !exists("t:NERDComOldPos") - throw 'NERDCommenter exception: cannot restore screen' - endif - - call cursor(t:NERDComOldTopLine, 0) - normal! zt - call setpos(".", t:NERDComOldPos) -endfunction - -" Function: s:Right(...) {{{2 -" returns right delimiter data -function s:Right(...) - let params = a:0 ? a:1 : {} - - let delim = has_key(params, 'alt') ? b:NERDCommenterDelims['rightAlt'] : b:NERDCommenterDelims['right'] - - if delim == '' - return '' - endif - - if has_key(params, 'space') && g:NERDSpaceDelims - let delim = s:spaceStr . delim - endif - - if has_key(params, 'esc') - let delim = s:Esc(delim) - endif - - return delim -endfunction - -" Function: s:RightMostIndx(countCommentedLines, countEmptyLines, topline, bottomline) {{{2 -" This function takes in 2 line numbers and returns the index of the right most -" char on all of these lines. -" Args: -" -countCommentedLines: 1 if lines that are commented are to be checked as -" well. 0 otherwise -" -countEmptyLines: 1 if empty lines are to be counted in the search -" -topline: the top line to be checked -" -bottomline: the bottom line to be checked -function s:RightMostIndx(countCommentedLines, countEmptyLines, topline, bottomline) - let rightMostIndx = -1 - - " go thru the block line by line updating rightMostIndx - let currentLine = a:topline - while currentLine <= a:bottomline - - " get the next line and see if it is commentable, otherwise it doesnt - " count - let theLine = getline(currentLine) - if a:countEmptyLines || theLine !~ '^[ \t]*$' - - if a:countCommentedLines || (!s:IsCommented(s:Left(), s:Right(), theLine) && !s:IsCommented(s:Left({'alt': 1}), s:Right({'alt': 1}), theLine)) - - " update rightMostIndx if need be - let theLine = s:ConvertLeadingTabsToSpaces(theLine) - let lineLen = strlen(theLine) - if lineLen > rightMostIndx - let rightMostIndx = lineLen - endif - endif - endif - - " move on to the next line - let currentLine = currentLine + 1 - endwhile - - return rightMostIndx -endfunction - -"FUNCTION: s:SaveScreenState() {{{2 -"Saves the current cursor position in the current buffer and the window -"scroll position -function s:SaveScreenState() - let t:NERDComOldPos = getpos(".") - let t:NERDComOldTopLine = line("w0") -endfunction - -" Function: s:SwapOutterMultiPartDelimsForPlaceHolders(line) {{{2 -" This function takes a line and swaps the outter most multi-part delims for -" place holders -" Args: -" -line: the line to swap the delims in -" -function s:SwapOutterMultiPartDelimsForPlaceHolders(line) - " find out if the line is commented using normal delims and/or - " alternate ones - let isCommented = s:IsCommented(s:Left(), s:Right(), a:line) - let isCommentedAlt = s:IsCommented(s:Left({'alt': 1}), s:Right({'alt': 1}), a:line) - - let line2 = a:line - - "if the line is commented and there is a right delimiter, replace - "the delims with place-holders - if isCommented && s:Multipart() - let line2 = s:ReplaceDelims(s:Left(), s:Right(), g:NERDLPlace, g:NERDRPlace, a:line) - - "similarly if the line is commented with the alternative - "delimiters - elseif isCommentedAlt && s:AltMultipart() - let line2 = s:ReplaceDelims(s:Left({'alt': 1}), s:Right({'alt': 1}), g:NERDLPlace, g:NERDRPlace, a:line) - endif - - return line2 -endfunction - -" Function: s:SwapOutterPlaceHoldersForMultiPartDelims(line) {{{2 -" This function takes a line and swaps the outtermost place holders for -" multi-part delims -" Args: -" -line: the line to swap the delims in -" -function s:SwapOutterPlaceHoldersForMultiPartDelims(line) - let left = '' - let right = '' - if s:Multipart() - let left = s:Left() - let right = s:Right() - elseif s:AltMultipart() - let left = s:Left({'alt': 1}) - let right = s:Right({'alt': 1}) - endif - - let line = s:ReplaceDelims(g:NERDLPlace, g:NERDRPlace, left, right, a:line) - return line -endfunction -" Function: s:TabbedCol(line, col) {{{2 -" Gets the col number for given line and existing col number. The new col -" number is the col number when all leading spaces are converted to tabs -" Args: -" -line:the line to get the rel col for -" -col: the abs col -function s:TabbedCol(line, col) - let lineTruncated = strpart(a:line, 0, a:col) - let lineSpacesToTabs = substitute(lineTruncated, s:TabSpace(), '\t', 'g') - return strlen(lineSpacesToTabs) -endfunction -"FUNCTION: s:TabSpace() {{{2 -"returns a string of spaces equal in length to &tabstop -function s:TabSpace() - let tabSpace = "" - let spacesPerTab = &tabstop - while spacesPerTab > 0 - let tabSpace = tabSpace . " " - let spacesPerTab = spacesPerTab - 1 - endwhile - return tabSpace -endfunction - -" Function: s:UnEsc(str, escChar) {{{2 -" This function removes all the escape chars from a string -" Args: -" -str: the string to remove esc chars from -" -escChar: the escape char to be removed -function s:UnEsc(str, escChar) - return substitute(a:str, a:escChar, "", "g") -endfunction - -" Function: s:UntabbedCol(line, col) {{{2 -" Takes a line and a col and returns the absolute column of col taking into -" account that a tab is worth 3 or 4 (or whatever) spaces. -" Args: -" -line:the line to get the abs col for -" -col: the col that doesnt take into account tabs -function s:UntabbedCol(line, col) - let lineTruncated = strpart(a:line, 0, a:col) - let lineTabsToSpaces = substitute(lineTruncated, '\t', s:TabSpace(), 'g') - return strlen(lineTabsToSpaces) -endfunction -" Section: Comment mapping setup {{{1 -" =========================================================================== - -" switch to/from alternative delimiters -nnoremap NERDCommenterAltDelims :call SwitchToAlternativeDelimiters(1) - -" comment out lines -nnoremap NERDCommenterComment :call NERDComment(0, "norm") -vnoremap NERDCommenterComment :call NERDComment(1, "norm") - -" toggle comments -nnoremap NERDCommenterToggle :call NERDComment(0, "toggle") -vnoremap NERDCommenterToggle :call NERDComment(1, "toggle") - -" minimal comments -nnoremap NERDCommenterMinimal :call NERDComment(0, "minimal") -vnoremap NERDCommenterMinimal :call NERDComment(1, "minimal") - -" sexy comments -nnoremap NERDCommenterSexy :call NERDComment(0, "sexy") -vnoremap NERDCommenterSexy :call NERDComment(1, "sexy") - -" invert comments -nnoremap NERDCommenterInvert :call NERDComment(0, "invert") -vnoremap NERDCommenterInvert :call NERDComment(1, "invert") - -" yank then comment -nmap NERDCommenterYank :call NERDComment(0, "yank") -vmap NERDCommenterYank :call NERDComment(1, "yank") - -" left aligned comments -nnoremap NERDCommenterAlignLeft :call NERDComment(0, "alignLeft") -vnoremap NERDCommenterAlignLeft :call NERDComment(1, "alignLeft") - -" left and right aligned comments -nnoremap NERDCommenterAlignBoth :call NERDComment(0, "alignBoth") -vnoremap NERDCommenterAlignBoth :call NERDComment(1, "alignBoth") - -" nested comments -nnoremap NERDCommenterNest :call NERDComment(0, "nested") -vnoremap NERDCommenterNest :call NERDComment(1, "nested") - -" uncomment -nnoremap NERDCommenterUncomment :call NERDComment(0, "uncomment") -vnoremap NERDCommenterUncomment :call NERDComment(1, "uncomment") - -" comment till the end of the line -nnoremap NERDCommenterToEOL :call NERDComment(0, "toEOL") - -" append comments -nmap NERDCommenterAppend :call NERDComment(0, "append") - -" insert comments -inoremap NERDCommenterInInsert :call NERDComment(0, "insert") - - -function! s:CreateMaps(target, combo) - if !hasmapto(a:target, 'n') - exec 'nmap ' . a:combo . ' ' . a:target - endif - - if !hasmapto(a:target, 'v') - exec 'vmap ' . a:combo . ' ' . a:target - endif -endfunction - -if g:NERDCreateDefaultMappings - call s:CreateMaps('NERDCommenterComment', 'cc') - call s:CreateMaps('NERDCommenterToggle', 'c') - call s:CreateMaps('NERDCommenterMinimal', 'cm') - call s:CreateMaps('NERDCommenterSexy', 'cs') - call s:CreateMaps('NERDCommenterInvert', 'ci') - call s:CreateMaps('NERDCommenterYank', 'cy') - call s:CreateMaps('NERDCommenterAlignLeft', 'cl') - call s:CreateMaps('NERDCommenterAlignBoth', 'cb') - call s:CreateMaps('NERDCommenterNest', 'cn') - call s:CreateMaps('NERDCommenterUncomment', 'cu') - call s:CreateMaps('NERDCommenterToEOL', 'c$') - call s:CreateMaps('NERDCommenterAppend', 'cA') - - if !hasmapto('NERDCommenterAltDelims', 'n') - nmap ca NERDCommenterAltDelims - endif -endif - - - -" Section: Menu item setup {{{1 -" =========================================================================== -"check if the user wants the menu to be displayed -if g:NERDMenuMode != 0 - - let menuRoot = "" - if g:NERDMenuMode == 1 - let menuRoot = 'comment' - elseif g:NERDMenuMode == 2 - let menuRoot = '&comment' - elseif g:NERDMenuMode == 3 - let menuRoot = '&Plugin.&comment' - endif - - function! s:CreateMenuItems(target, desc, root) - exec 'nmenu ' . a:root . '.' . a:desc . ' ' . a:target - exec 'vmenu ' . a:root . '.' . a:desc . ' ' . a:target - endfunction - call s:CreateMenuItems("NERDCommenterComment", 'Comment', menuRoot) - call s:CreateMenuItems("NERDCommenterToggle", 'Toggle', menuRoot) - call s:CreateMenuItems('NERDCommenterMinimal', 'Minimal', menuRoot) - call s:CreateMenuItems('NERDCommenterNest', 'Nested', menuRoot) - exec 'nmenu '. menuRoot .'.To\ EOL NERDCommenterToEOL' - call s:CreateMenuItems('NERDCommenterInvert', 'Invert', menuRoot) - call s:CreateMenuItems('NERDCommenterSexy', 'Sexy', menuRoot) - call s:CreateMenuItems('NERDCommenterYank', 'Yank\ then\ comment', menuRoot) - exec 'nmenu '. menuRoot .'.Append NERDCommenterAppend' - exec 'menu '. menuRoot .'.-Sep- :' - call s:CreateMenuItems('NERDCommenterAlignLeft', 'Left\ aligned', menuRoot) - call s:CreateMenuItems('NERDCommenterAlignBoth', 'Left\ and\ right\ aligned', menuRoot) - exec 'menu '. menuRoot .'.-Sep2- :' - call s:CreateMenuItems('NERDCommenterUncomment', 'Uncomment', menuRoot) - exec 'nmenu '. menuRoot .'.Switch\ Delimiters NERDCommenterAltDelims' - exec 'imenu '. menuRoot .'.Insert\ Comment\ Here NERDCommenterInInsert' - exec 'menu '. menuRoot .'.-Sep3- :' - exec 'menu '. menuRoot .'.Help :help NERDCommenterContents' -endif -" vim: set foldmethod=marker : diff --git a/oldStyle/disabled_plugins/NERD_tree.vim b/oldStyle/disabled_plugins/NERD_tree.vim deleted file mode 100644 index bc34775..0000000 --- a/oldStyle/disabled_plugins/NERD_tree.vim +++ /dev/null @@ -1,4017 +0,0 @@ -" ============================================================================ -" File: NERD_tree.vim -" Description: vim global plugin that provides a nice tree explorer -" Maintainer: Martin Grenfell -" Last Change: 28 December, 2011 -" License: This program is free software. It comes without any warranty, -" to the extent permitted by applicable law. You can redistribute -" it and/or modify it under the terms of the Do What The Fuck You -" Want To Public License, Version 2, as published by Sam Hocevar. -" See http://sam.zoy.org/wtfpl/COPYING for more details. -" -" ============================================================================ -let s:NERD_tree_version = '4.2.0' - -" SECTION: Script init stuff {{{1 -"============================================================ -if exists("loaded_nerd_tree") - finish -endif -if v:version < 700 - echoerr "NERDTree: this plugin requires vim >= 7. DOWNLOAD IT! You'll thank me later!" - finish -endif -let loaded_nerd_tree = 1 - -"for line continuation - i.e dont want C in &cpo -let s:old_cpo = &cpo -set cpo&vim - -let s:running_windows = has("win16") || has("win32") || has("win64") - -"Function: s:initVariable() function {{{2 -"This function is used to initialise a given variable to a given value. The -"variable is only initialised if it does not exist prior -" -"Args: -"var: the name of the var to be initialised -"value: the value to initialise var to -" -"Returns: -"1 if the var is set, 0 otherwise -function! s:initVariable(var, value) - if !exists(a:var) - exec 'let ' . a:var . ' = ' . "'" . substitute(a:value, "'", "''", "g") . "'" - return 1 - endif - return 0 -endfunction - -"SECTION: Init variable calls and other random constants {{{2 -call s:initVariable("g:NERDChristmasTree", 1) -call s:initVariable("g:NERDTreeAutoCenter", 1) -call s:initVariable("g:NERDTreeAutoCenterThreshold", 3) -call s:initVariable("g:NERDTreeCaseSensitiveSort", 0) -call s:initVariable("g:NERDTreeChDirMode", 0) -call s:initVariable("g:NERDTreeMinimalUI", 0) -if !exists("g:NERDTreeIgnore") - let g:NERDTreeIgnore = ['\~$'] -endif -call s:initVariable("g:NERDTreeBookmarksFile", expand('$HOME') . '/.NERDTreeBookmarks') -call s:initVariable("g:NERDTreeHighlightCursorline", 1) -call s:initVariable("g:NERDTreeHijackNetrw", 1) -call s:initVariable("g:NERDTreeMouseMode", 1) -call s:initVariable("g:NERDTreeNotificationThreshold", 100) -call s:initVariable("g:NERDTreeQuitOnOpen", 0) -call s:initVariable("g:NERDTreeShowBookmarks", 0) -call s:initVariable("g:NERDTreeShowFiles", 1) -call s:initVariable("g:NERDTreeShowHidden", 0) -call s:initVariable("g:NERDTreeShowLineNumbers", 0) -call s:initVariable("g:NERDTreeSortDirs", 1) -call s:initVariable("g:NERDTreeDirArrows", !s:running_windows) - -if !exists("g:NERDTreeSortOrder") - let g:NERDTreeSortOrder = ['\/$', '*', '\.swp$', '\.bak$', '\~$'] -else - "if there isnt a * in the sort sequence then add one - if count(g:NERDTreeSortOrder, '*') < 1 - call add(g:NERDTreeSortOrder, '*') - endif -endif - -"we need to use this number many times for sorting... so we calculate it only -"once here -let s:NERDTreeSortStarIndex = index(g:NERDTreeSortOrder, '*') - -if !exists('g:NERDTreeStatusline') - - "the exists() crap here is a hack to stop vim spazzing out when - "loading a session that was created with an open nerd tree. It spazzes - "because it doesnt store b:NERDTreeRoot (its a b: var, and its a hash) - let g:NERDTreeStatusline = "%{exists('b:NERDTreeRoot')?b:NERDTreeRoot.path.str():''}" - -endif -call s:initVariable("g:NERDTreeWinPos", "left") -call s:initVariable("g:NERDTreeWinSize", 31) - -"init the shell commands that will be used to copy nodes, and remove dir trees -" -"Note: the space after the command is important -if s:running_windows - call s:initVariable("g:NERDTreeRemoveDirCmd", 'rmdir /s /q ') -else - call s:initVariable("g:NERDTreeRemoveDirCmd", 'rm -rf ') - call s:initVariable("g:NERDTreeCopyCmd", 'cp -r ') -endif - - -"SECTION: Init variable calls for key mappings {{{2 -call s:initVariable("g:NERDTreeMapActivateNode", "o") -call s:initVariable("g:NERDTreeMapChangeRoot", "C") -call s:initVariable("g:NERDTreeMapChdir", "cd") -call s:initVariable("g:NERDTreeMapCloseChildren", "X") -call s:initVariable("g:NERDTreeMapCloseDir", "x") -call s:initVariable("g:NERDTreeMapDeleteBookmark", "D") -call s:initVariable("g:NERDTreeMapMenu", "m") -call s:initVariable("g:NERDTreeMapHelp", "?") -call s:initVariable("g:NERDTreeMapJumpFirstChild", "K") -call s:initVariable("g:NERDTreeMapJumpLastChild", "J") -call s:initVariable("g:NERDTreeMapJumpNextSibling", "") -call s:initVariable("g:NERDTreeMapJumpParent", "p") -call s:initVariable("g:NERDTreeMapJumpPrevSibling", "") -call s:initVariable("g:NERDTreeMapJumpRoot", "P") -call s:initVariable("g:NERDTreeMapOpenExpl", "e") -call s:initVariable("g:NERDTreeMapOpenInTab", "t") -call s:initVariable("g:NERDTreeMapOpenInTabSilent", "T") -call s:initVariable("g:NERDTreeMapOpenRecursively", "O") -call s:initVariable("g:NERDTreeMapOpenSplit", "i") -call s:initVariable("g:NERDTreeMapOpenVSplit", "s") -call s:initVariable("g:NERDTreeMapPreview", "g" . NERDTreeMapActivateNode) -call s:initVariable("g:NERDTreeMapPreviewSplit", "g" . NERDTreeMapOpenSplit) -call s:initVariable("g:NERDTreeMapPreviewVSplit", "g" . NERDTreeMapOpenVSplit) -call s:initVariable("g:NERDTreeMapQuit", "q") -call s:initVariable("g:NERDTreeMapRefresh", "r") -call s:initVariable("g:NERDTreeMapRefreshRoot", "R") -call s:initVariable("g:NERDTreeMapToggleBookmarks", "B") -call s:initVariable("g:NERDTreeMapToggleFiles", "F") -call s:initVariable("g:NERDTreeMapToggleFilters", "f") -call s:initVariable("g:NERDTreeMapToggleHidden", "I") -call s:initVariable("g:NERDTreeMapToggleZoom", "A") -call s:initVariable("g:NERDTreeMapUpdir", "u") -call s:initVariable("g:NERDTreeMapUpdirKeepOpen", "U") - -"SECTION: Script level variable declaration{{{2 -if s:running_windows - let s:escape_chars = " `\|\"#%&,?()\*^<>" -else - let s:escape_chars = " \\`\|\"#%&,?()\*^<>[]" -endif -let s:NERDTreeBufName = 'NERD_tree_' - -let s:tree_wid = 2 -let s:tree_markup_reg = '^[ `|]*[\-+~▾▸ ]\+' -let s:tree_up_dir_line = '.. (up a dir)' - -"the number to add to the nerd tree buffer name to make the buf name unique -let s:next_buffer_number = 1 - -" SECTION: Commands {{{1 -"============================================================ -"init the command that users start the nerd tree with -command! -n=? -complete=dir -bar NERDTree :call s:initNerdTree('') -command! -n=? -complete=dir -bar NERDTreeToggle :call s:toggle('') -command! -n=0 -bar NERDTreeClose :call s:closeTreeIfOpen() -command! -n=1 -complete=customlist,s:completeBookmarks -bar NERDTreeFromBookmark call s:initNerdTree('') -command! -n=0 -bar NERDTreeMirror call s:initNerdTreeMirror() -command! -n=0 -bar NERDTreeFind call s:findAndRevealPath() -" SECTION: Auto commands {{{1 -"============================================================ -augroup NERDTree - "Save the cursor position whenever we close the nerd tree - exec "autocmd BufWinLeave ". s:NERDTreeBufName ."* call saveScreenState()" - - "disallow insert mode in the NERDTree - exec "autocmd BufEnter ". s:NERDTreeBufName ."* stopinsert" - - "cache bookmarks when vim loads - autocmd VimEnter * call s:Bookmark.CacheBookmarks(0) - - "load all nerdtree plugins after vim starts - autocmd VimEnter * runtime! nerdtree_plugin/**/*.vim -augroup END - -if g:NERDTreeHijackNetrw - augroup NERDTreeHijackNetrw - autocmd VimEnter * silent! autocmd! FileExplorer - au BufEnter,VimEnter * call s:checkForBrowse(expand("")) - augroup END -endif - -"SECTION: Classes {{{1 -"============================================================ -"CLASS: Bookmark {{{2 -"============================================================ -let s:Bookmark = {} -" FUNCTION: Bookmark.activate() {{{3 -function! s:Bookmark.activate() - if self.path.isDirectory - call self.toRoot() - else - if self.validate() - let n = s:TreeFileNode.New(self.path) - call n.open() - call s:closeTreeIfQuitOnOpen() - endif - endif -endfunction -" FUNCTION: Bookmark.AddBookmark(name, path) {{{3 -" Class method to add a new bookmark to the list, if a previous bookmark exists -" with the same name, just update the path for that bookmark -function! s:Bookmark.AddBookmark(name, path) - for i in s:Bookmark.Bookmarks() - if i.name ==# a:name - let i.path = a:path - return - endif - endfor - call add(s:Bookmark.Bookmarks(), s:Bookmark.New(a:name, a:path)) - call s:Bookmark.Sort() -endfunction -" Function: Bookmark.Bookmarks() {{{3 -" Class method to get all bookmarks. Lazily initializes the bookmarks global -" variable -function! s:Bookmark.Bookmarks() - if !exists("g:NERDTreeBookmarks") - let g:NERDTreeBookmarks = [] - endif - return g:NERDTreeBookmarks -endfunction -" Function: Bookmark.BookmarkExistsFor(name) {{{3 -" class method that returns 1 if a bookmark with the given name is found, 0 -" otherwise -function! s:Bookmark.BookmarkExistsFor(name) - try - call s:Bookmark.BookmarkFor(a:name) - return 1 - catch /^NERDTree.BookmarkNotFoundError/ - return 0 - endtry -endfunction -" Function: Bookmark.BookmarkFor(name) {{{3 -" Class method to get the bookmark that has the given name. {} is return if no -" bookmark is found -function! s:Bookmark.BookmarkFor(name) - for i in s:Bookmark.Bookmarks() - if i.name ==# a:name - return i - endif - endfor - throw "NERDTree.BookmarkNotFoundError: no bookmark found for name: \"". a:name .'"' -endfunction -" Function: Bookmark.BookmarkNames() {{{3 -" Class method to return an array of all bookmark names -function! s:Bookmark.BookmarkNames() - let names = [] - for i in s:Bookmark.Bookmarks() - call add(names, i.name) - endfor - return names -endfunction -" FUNCTION: Bookmark.CacheBookmarks(silent) {{{3 -" Class method to read all bookmarks from the bookmarks file intialize -" bookmark objects for each one. -" -" Args: -" silent - dont echo an error msg if invalid bookmarks are found -function! s:Bookmark.CacheBookmarks(silent) - if filereadable(g:NERDTreeBookmarksFile) - let g:NERDTreeBookmarks = [] - let g:NERDTreeInvalidBookmarks = [] - let bookmarkStrings = readfile(g:NERDTreeBookmarksFile) - let invalidBookmarksFound = 0 - for i in bookmarkStrings - - "ignore blank lines - if i != '' - - let name = substitute(i, '^\(.\{-}\) .*$', '\1', '') - let path = substitute(i, '^.\{-} \(.*\)$', '\1', '') - - try - let bookmark = s:Bookmark.New(name, s:Path.New(path)) - call add(g:NERDTreeBookmarks, bookmark) - catch /^NERDTree.InvalidArgumentsError/ - call add(g:NERDTreeInvalidBookmarks, i) - let invalidBookmarksFound += 1 - endtry - endif - endfor - if invalidBookmarksFound - call s:Bookmark.Write() - if !a:silent - call s:echo(invalidBookmarksFound . " invalid bookmarks were read. See :help NERDTreeInvalidBookmarks for info.") - endif - endif - call s:Bookmark.Sort() - endif -endfunction -" FUNCTION: Bookmark.compareTo(otherbookmark) {{{3 -" Compare these two bookmarks for sorting purposes -function! s:Bookmark.compareTo(otherbookmark) - return a:otherbookmark.name < self.name -endfunction -" FUNCTION: Bookmark.ClearAll() {{{3 -" Class method to delete all bookmarks. -function! s:Bookmark.ClearAll() - for i in s:Bookmark.Bookmarks() - call i.delete() - endfor - call s:Bookmark.Write() -endfunction -" FUNCTION: Bookmark.delete() {{{3 -" Delete this bookmark. If the node for this bookmark is under the current -" root, then recache bookmarks for its Path object -function! s:Bookmark.delete() - let node = {} - try - let node = self.getNode(1) - catch /^NERDTree.BookmarkedNodeNotFoundError/ - endtry - call remove(s:Bookmark.Bookmarks(), index(s:Bookmark.Bookmarks(), self)) - if !empty(node) - call node.path.cacheDisplayString() - endif - call s:Bookmark.Write() -endfunction -" FUNCTION: Bookmark.getNode(searchFromAbsoluteRoot) {{{3 -" Gets the treenode for this bookmark -" -" Args: -" searchFromAbsoluteRoot: specifies whether we should search from the current -" tree root, or the highest cached node -function! s:Bookmark.getNode(searchFromAbsoluteRoot) - let searchRoot = a:searchFromAbsoluteRoot ? s:TreeDirNode.AbsoluteTreeRoot() : b:NERDTreeRoot - let targetNode = searchRoot.findNode(self.path) - if empty(targetNode) - throw "NERDTree.BookmarkedNodeNotFoundError: no node was found for bookmark: " . self.name - endif - return targetNode -endfunction -" FUNCTION: Bookmark.GetNodeForName(name, searchFromAbsoluteRoot) {{{3 -" Class method that finds the bookmark with the given name and returns the -" treenode for it. -function! s:Bookmark.GetNodeForName(name, searchFromAbsoluteRoot) - let bookmark = s:Bookmark.BookmarkFor(a:name) - return bookmark.getNode(a:searchFromAbsoluteRoot) -endfunction -" FUNCTION: Bookmark.GetSelected() {{{3 -" returns the Bookmark the cursor is over, or {} -function! s:Bookmark.GetSelected() - let line = getline(".") - let name = substitute(line, '^>\(.\{-}\) .\+$', '\1', '') - if name != line - try - return s:Bookmark.BookmarkFor(name) - catch /^NERDTree.BookmarkNotFoundError/ - return {} - endtry - endif - return {} -endfunction - -" Function: Bookmark.InvalidBookmarks() {{{3 -" Class method to get all invalid bookmark strings read from the bookmarks -" file -function! s:Bookmark.InvalidBookmarks() - if !exists("g:NERDTreeInvalidBookmarks") - let g:NERDTreeInvalidBookmarks = [] - endif - return g:NERDTreeInvalidBookmarks -endfunction -" FUNCTION: Bookmark.mustExist() {{{3 -function! s:Bookmark.mustExist() - if !self.path.exists() - call s:Bookmark.CacheBookmarks(1) - throw "NERDTree.BookmarkPointsToInvalidLocationError: the bookmark \"". - \ self.name ."\" points to a non existing location: \"". self.path.str() - endif -endfunction -" FUNCTION: Bookmark.New(name, path) {{{3 -" Create a new bookmark object with the given name and path object -function! s:Bookmark.New(name, path) - if a:name =~# ' ' - throw "NERDTree.IllegalBookmarkNameError: illegal name:" . a:name - endif - - let newBookmark = copy(self) - let newBookmark.name = a:name - let newBookmark.path = a:path - return newBookmark -endfunction -" FUNCTION: Bookmark.openInNewTab(options) {{{3 -" Create a new bookmark object with the given name and path object -function! s:Bookmark.openInNewTab(options) - let currentTab = tabpagenr() - if self.path.isDirectory - tabnew - call s:initNerdTree(self.name) - else - exec "tabedit " . self.path.str({'format': 'Edit'}) - endif - - if has_key(a:options, 'stayInCurrentTab') - exec "tabnext " . currentTab - endif -endfunction -" Function: Bookmark.setPath(path) {{{3 -" makes this bookmark point to the given path -function! s:Bookmark.setPath(path) - let self.path = a:path -endfunction -" Function: Bookmark.Sort() {{{3 -" Class method that sorts all bookmarks -function! s:Bookmark.Sort() - let CompareFunc = function("s:compareBookmarks") - call sort(s:Bookmark.Bookmarks(), CompareFunc) -endfunction -" Function: Bookmark.str() {{{3 -" Get the string that should be rendered in the view for this bookmark -function! s:Bookmark.str() - let pathStrMaxLen = winwidth(s:getTreeWinNum()) - 4 - len(self.name) - if &nu - let pathStrMaxLen = pathStrMaxLen - &numberwidth - endif - - let pathStr = self.path.str({'format': 'UI'}) - if len(pathStr) > pathStrMaxLen - let pathStr = '<' . strpart(pathStr, len(pathStr) - pathStrMaxLen) - endif - return '>' . self.name . ' ' . pathStr -endfunction -" FUNCTION: Bookmark.toRoot() {{{3 -" Make the node for this bookmark the new tree root -function! s:Bookmark.toRoot() - if self.validate() - try - let targetNode = self.getNode(1) - catch /^NERDTree.BookmarkedNodeNotFoundError/ - let targetNode = s:TreeFileNode.New(s:Bookmark.BookmarkFor(self.name).path) - endtry - call targetNode.makeRoot() - call s:renderView() - call targetNode.putCursorHere(0, 0) - endif -endfunction -" FUNCTION: Bookmark.ToRoot(name) {{{3 -" Make the node for this bookmark the new tree root -function! s:Bookmark.ToRoot(name) - let bookmark = s:Bookmark.BookmarkFor(a:name) - call bookmark.toRoot() -endfunction - - -"FUNCTION: Bookmark.validate() {{{3 -function! s:Bookmark.validate() - if self.path.exists() - return 1 - else - call s:Bookmark.CacheBookmarks(1) - call s:renderView() - call s:echo(self.name . "now points to an invalid location. See :help NERDTreeInvalidBookmarks for info.") - return 0 - endif -endfunction - -" Function: Bookmark.Write() {{{3 -" Class method to write all bookmarks to the bookmarks file -function! s:Bookmark.Write() - let bookmarkStrings = [] - for i in s:Bookmark.Bookmarks() - call add(bookmarkStrings, i.name . ' ' . i.path.str()) - endfor - - "add a blank line before the invalid ones - call add(bookmarkStrings, "") - - for j in s:Bookmark.InvalidBookmarks() - call add(bookmarkStrings, j) - endfor - call writefile(bookmarkStrings, g:NERDTreeBookmarksFile) -endfunction -"CLASS: KeyMap {{{2 -"============================================================ -let s:KeyMap = {} -"FUNCTION: KeyMap.All() {{{3 -function! s:KeyMap.All() - if !exists("s:keyMaps") - let s:keyMaps = [] - endif - return s:keyMaps -endfunction - -"FUNCTION: KeyMap.BindAll() {{{3 -function! s:KeyMap.BindAll() - for i in s:KeyMap.All() - call i.bind() - endfor -endfunction - -"FUNCTION: KeyMap.bind() {{{3 -function! s:KeyMap.bind() - exec "nnoremap ". self.key ." :call ". self.callback ."()" -endfunction - -"FUNCTION: KeyMap.Create(options) {{{3 -function! s:KeyMap.Create(options) - let newKeyMap = copy(self) - let newKeyMap.key = a:options['key'] - let newKeyMap.quickhelpText = a:options['quickhelpText'] - let newKeyMap.callback = a:options['callback'] - call add(s:KeyMap.All(), newKeyMap) -endfunction -"CLASS: MenuController {{{2 -"============================================================ -let s:MenuController = {} -"FUNCTION: MenuController.New(menuItems) {{{3 -"create a new menu controller that operates on the given menu items -function! s:MenuController.New(menuItems) - let newMenuController = copy(self) - if a:menuItems[0].isSeparator() - let newMenuController.menuItems = a:menuItems[1:-1] - else - let newMenuController.menuItems = a:menuItems - endif - return newMenuController -endfunction - -"FUNCTION: MenuController.showMenu() {{{3 -"start the main loop of the menu and get the user to choose/execute a menu -"item -function! s:MenuController.showMenu() - call self._saveOptions() - - try - let self.selection = 0 - - let done = 0 - while !done - redraw! - call self._echoPrompt() - let key = nr2char(getchar()) - let done = self._handleKeypress(key) - endwhile - finally - call self._restoreOptions() - endtry - - if self.selection != -1 - let m = self._current() - call m.execute() - endif -endfunction - -"FUNCTION: MenuController._echoPrompt() {{{3 -function! s:MenuController._echoPrompt() - echo "NERDTree Menu. Use j/k/enter and the shortcuts indicated" - echo "==========================================================" - - for i in range(0, len(self.menuItems)-1) - if self.selection == i - echo "> " . self.menuItems[i].text - else - echo " " . self.menuItems[i].text - endif - endfor -endfunction - -"FUNCTION: MenuController._current(key) {{{3 -"get the MenuItem that is currently selected -function! s:MenuController._current() - return self.menuItems[self.selection] -endfunction - -"FUNCTION: MenuController._handleKeypress(key) {{{3 -"change the selection (if appropriate) and return 1 if the user has made -"their choice, 0 otherwise -function! s:MenuController._handleKeypress(key) - if a:key == 'j' - call self._cursorDown() - elseif a:key == 'k' - call self._cursorUp() - elseif a:key == nr2char(27) "escape - let self.selection = -1 - return 1 - elseif a:key == "\r" || a:key == "\n" "enter and ctrl-j - return 1 - else - let index = self._nextIndexFor(a:key) - if index != -1 - let self.selection = index - if len(self._allIndexesFor(a:key)) == 1 - return 1 - endif - endif - endif - - return 0 -endfunction - -"FUNCTION: MenuController._allIndexesFor(shortcut) {{{3 -"get indexes to all menu items with the given shortcut -function! s:MenuController._allIndexesFor(shortcut) - let toReturn = [] - - for i in range(0, len(self.menuItems)-1) - if self.menuItems[i].shortcut == a:shortcut - call add(toReturn, i) - endif - endfor - - return toReturn -endfunction - -"FUNCTION: MenuController._nextIndexFor(shortcut) {{{3 -"get the index to the next menu item with the given shortcut, starts from the -"current cursor location and wraps around to the top again if need be -function! s:MenuController._nextIndexFor(shortcut) - for i in range(self.selection+1, len(self.menuItems)-1) - if self.menuItems[i].shortcut == a:shortcut - return i - endif - endfor - - for i in range(0, self.selection) - if self.menuItems[i].shortcut == a:shortcut - return i - endif - endfor - - return -1 -endfunction - -"FUNCTION: MenuController._setCmdheight() {{{3 -"sets &cmdheight to whatever is needed to display the menu -function! s:MenuController._setCmdheight() - let &cmdheight = len(self.menuItems) + 3 -endfunction - -"FUNCTION: MenuController._saveOptions() {{{3 -"set any vim options that are required to make the menu work (saving their old -"values) -function! s:MenuController._saveOptions() - let self._oldLazyredraw = &lazyredraw - let self._oldCmdheight = &cmdheight - set nolazyredraw - call self._setCmdheight() -endfunction - -"FUNCTION: MenuController._restoreOptions() {{{3 -"restore the options we saved in _saveOptions() -function! s:MenuController._restoreOptions() - let &cmdheight = self._oldCmdheight - let &lazyredraw = self._oldLazyredraw -endfunction - -"FUNCTION: MenuController._cursorDown() {{{3 -"move the cursor to the next menu item, skipping separators -function! s:MenuController._cursorDown() - let done = 0 - while !done - if self.selection < len(self.menuItems)-1 - let self.selection += 1 - else - let self.selection = 0 - endif - - if !self._current().isSeparator() - let done = 1 - endif - endwhile -endfunction - -"FUNCTION: MenuController._cursorUp() {{{3 -"move the cursor to the previous menu item, skipping separators -function! s:MenuController._cursorUp() - let done = 0 - while !done - if self.selection > 0 - let self.selection -= 1 - else - let self.selection = len(self.menuItems)-1 - endif - - if !self._current().isSeparator() - let done = 1 - endif - endwhile -endfunction - -"CLASS: MenuItem {{{2 -"============================================================ -let s:MenuItem = {} -"FUNCTION: MenuItem.All() {{{3 -"get all top level menu items -function! s:MenuItem.All() - if !exists("s:menuItems") - let s:menuItems = [] - endif - return s:menuItems -endfunction - -"FUNCTION: MenuItem.AllEnabled() {{{3 -"get all top level menu items that are currently enabled -function! s:MenuItem.AllEnabled() - let toReturn = [] - for i in s:MenuItem.All() - if i.enabled() - call add(toReturn, i) - endif - endfor - return toReturn -endfunction - -"FUNCTION: MenuItem.Create(options) {{{3 -"make a new menu item and add it to the global list -function! s:MenuItem.Create(options) - let newMenuItem = copy(self) - - let newMenuItem.text = a:options['text'] - let newMenuItem.shortcut = a:options['shortcut'] - let newMenuItem.children = [] - - let newMenuItem.isActiveCallback = -1 - if has_key(a:options, 'isActiveCallback') - let newMenuItem.isActiveCallback = a:options['isActiveCallback'] - endif - - let newMenuItem.callback = -1 - if has_key(a:options, 'callback') - let newMenuItem.callback = a:options['callback'] - endif - - if has_key(a:options, 'parent') - call add(a:options['parent'].children, newMenuItem) - else - call add(s:MenuItem.All(), newMenuItem) - endif - - return newMenuItem -endfunction - -"FUNCTION: MenuItem.CreateSeparator(options) {{{3 -"make a new separator menu item and add it to the global list -function! s:MenuItem.CreateSeparator(options) - let standard_options = { 'text': '--------------------', - \ 'shortcut': -1, - \ 'callback': -1 } - let options = extend(a:options, standard_options, "force") - - return s:MenuItem.Create(options) -endfunction - -"FUNCTION: MenuItem.CreateSubmenu(options) {{{3 -"make a new submenu and add it to global list -function! s:MenuItem.CreateSubmenu(options) - let standard_options = { 'callback': -1 } - let options = extend(a:options, standard_options, "force") - - return s:MenuItem.Create(options) -endfunction - -"FUNCTION: MenuItem.enabled() {{{3 -"return 1 if this menu item should be displayed -" -"delegates off to the isActiveCallback, and defaults to 1 if no callback was -"specified -function! s:MenuItem.enabled() - if self.isActiveCallback != -1 - return {self.isActiveCallback}() - endif - return 1 -endfunction - -"FUNCTION: MenuItem.execute() {{{3 -"perform the action behind this menu item, if this menuitem has children then -"display a new menu for them, otherwise deletegate off to the menuitem's -"callback -function! s:MenuItem.execute() - if len(self.children) - let mc = s:MenuController.New(self.children) - call mc.showMenu() - else - if self.callback != -1 - call {self.callback}() - endif - endif -endfunction - -"FUNCTION: MenuItem.isSeparator() {{{3 -"return 1 if this menuitem is a separator -function! s:MenuItem.isSeparator() - return self.callback == -1 && self.children == [] -endfunction - -"FUNCTION: MenuItem.isSubmenu() {{{3 -"return 1 if this menuitem is a submenu -function! s:MenuItem.isSubmenu() - return self.callback == -1 && !empty(self.children) -endfunction - -"CLASS: TreeFileNode {{{2 -"This class is the parent of the TreeDirNode class and constitures the -"'Component' part of the composite design pattern between the treenode -"classes. -"============================================================ -let s:TreeFileNode = {} -"FUNCTION: TreeFileNode.activate(forceKeepWinOpen) {{{3 -function! s:TreeFileNode.activate(forceKeepWinOpen) - call self.open() - if !a:forceKeepWinOpen - call s:closeTreeIfQuitOnOpen() - end -endfunction -"FUNCTION: TreeFileNode.bookmark(name) {{{3 -"bookmark this node with a:name -function! s:TreeFileNode.bookmark(name) - - "if a bookmark exists with the same name and the node is cached then save - "it so we can update its display string - let oldMarkedNode = {} - try - let oldMarkedNode = s:Bookmark.GetNodeForName(a:name, 1) - catch /^NERDTree.BookmarkNotFoundError/ - catch /^NERDTree.BookmarkedNodeNotFoundError/ - endtry - - call s:Bookmark.AddBookmark(a:name, self.path) - call self.path.cacheDisplayString() - call s:Bookmark.Write() - - if !empty(oldMarkedNode) - call oldMarkedNode.path.cacheDisplayString() - endif -endfunction -"FUNCTION: TreeFileNode.cacheParent() {{{3 -"initializes self.parent if it isnt already -function! s:TreeFileNode.cacheParent() - if empty(self.parent) - let parentPath = self.path.getParent() - if parentPath.equals(self.path) - throw "NERDTree.CannotCacheParentError: already at root" - endif - let self.parent = s:TreeFileNode.New(parentPath) - endif -endfunction -"FUNCTION: TreeFileNode.compareNodes {{{3 -"This is supposed to be a class level method but i cant figure out how to -"get func refs to work from a dict.. -" -"A class level method that compares two nodes -" -"Args: -"n1, n2: the 2 nodes to compare -function! s:compareNodes(n1, n2) - return a:n1.path.compareTo(a:n2.path) -endfunction - -"FUNCTION: TreeFileNode.clearBoomarks() {{{3 -function! s:TreeFileNode.clearBoomarks() - for i in s:Bookmark.Bookmarks() - if i.path.equals(self.path) - call i.delete() - end - endfor - call self.path.cacheDisplayString() -endfunction -"FUNCTION: TreeFileNode.copy(dest) {{{3 -function! s:TreeFileNode.copy(dest) - call self.path.copy(a:dest) - let newPath = s:Path.New(a:dest) - let parent = b:NERDTreeRoot.findNode(newPath.getParent()) - if !empty(parent) - call parent.refresh() - return parent.findNode(newPath) - else - return {} - endif -endfunction - -"FUNCTION: TreeFileNode.delete {{{3 -"Removes this node from the tree and calls the Delete method for its path obj -function! s:TreeFileNode.delete() - call self.path.delete() - call self.parent.removeChild(self) -endfunction - -"FUNCTION: TreeFileNode.displayString() {{{3 -" -"Returns a string that specifies how the node should be represented as a -"string -" -"Return: -"a string that can be used in the view to represent this node -function! s:TreeFileNode.displayString() - return self.path.displayString() -endfunction - -"FUNCTION: TreeFileNode.equals(treenode) {{{3 -" -"Compares this treenode to the input treenode and returns 1 if they are the -"same node. -" -"Use this method instead of == because sometimes when the treenodes contain -"many children, vim seg faults when doing == -" -"Args: -"treenode: the other treenode to compare to -function! s:TreeFileNode.equals(treenode) - return self.path.str() ==# a:treenode.path.str() -endfunction - -"FUNCTION: TreeFileNode.findNode(path) {{{3 -"Returns self if this node.path.Equals the given path. -"Returns {} if not equal. -" -"Args: -"path: the path object to compare against -function! s:TreeFileNode.findNode(path) - if a:path.equals(self.path) - return self - endif - return {} -endfunction -"FUNCTION: TreeFileNode.findOpenDirSiblingWithVisibleChildren(direction) {{{3 -" -"Finds the next sibling for this node in the indicated direction. This sibling -"must be a directory and may/may not have children as specified. -" -"Args: -"direction: 0 if you want to find the previous sibling, 1 for the next sibling -" -"Return: -"a treenode object or {} if no appropriate sibling could be found -function! s:TreeFileNode.findOpenDirSiblingWithVisibleChildren(direction) - "if we have no parent then we can have no siblings - if self.parent != {} - let nextSibling = self.findSibling(a:direction) - - while nextSibling != {} - if nextSibling.path.isDirectory && nextSibling.hasVisibleChildren() && nextSibling.isOpen - return nextSibling - endif - let nextSibling = nextSibling.findSibling(a:direction) - endwhile - endif - - return {} -endfunction -"FUNCTION: TreeFileNode.findSibling(direction) {{{3 -" -"Finds the next sibling for this node in the indicated direction -" -"Args: -"direction: 0 if you want to find the previous sibling, 1 for the next sibling -" -"Return: -"a treenode object or {} if no sibling could be found -function! s:TreeFileNode.findSibling(direction) - "if we have no parent then we can have no siblings - if self.parent != {} - - "get the index of this node in its parents children - let siblingIndx = self.parent.getChildIndex(self.path) - - if siblingIndx != -1 - "move a long to the next potential sibling node - let siblingIndx = a:direction ==# 1 ? siblingIndx+1 : siblingIndx-1 - - "keep moving along to the next sibling till we find one that is valid - let numSiblings = self.parent.getChildCount() - while siblingIndx >= 0 && siblingIndx < numSiblings - - "if the next node is not an ignored node (i.e. wont show up in the - "view) then return it - if self.parent.children[siblingIndx].path.ignore() ==# 0 - return self.parent.children[siblingIndx] - endif - - "go to next node - let siblingIndx = a:direction ==# 1 ? siblingIndx+1 : siblingIndx-1 - endwhile - endif - endif - - return {} -endfunction - -"FUNCTION: TreeFileNode.getLineNum(){{{3 -"returns the line number this node is rendered on, or -1 if it isnt rendered -function! s:TreeFileNode.getLineNum() - "if the node is the root then return the root line no. - if self.isRoot() - return s:TreeFileNode.GetRootLineNum() - endif - - let totalLines = line("$") - - "the path components we have matched so far - let pathcomponents = [substitute(b:NERDTreeRoot.path.str({'format': 'UI'}), '/ *$', '', '')] - "the index of the component we are searching for - let curPathComponent = 1 - - let fullpath = self.path.str({'format': 'UI'}) - - - let lnum = s:TreeFileNode.GetRootLineNum() - while lnum > 0 - let lnum = lnum + 1 - "have we reached the bottom of the tree? - if lnum ==# totalLines+1 - return -1 - endif - - let curLine = getline(lnum) - - let indent = s:indentLevelFor(curLine) - if indent ==# curPathComponent - let curLine = s:stripMarkupFromLine(curLine, 1) - - let curPath = join(pathcomponents, '/') . '/' . curLine - if stridx(fullpath, curPath, 0) ==# 0 - if fullpath ==# curPath || strpart(fullpath, len(curPath)-1,1) ==# '/' - let curLine = substitute(curLine, '/ *$', '', '') - call add(pathcomponents, curLine) - let curPathComponent = curPathComponent + 1 - - if fullpath ==# curPath - return lnum - endif - endif - endif - endif - endwhile - return -1 -endfunction - -"FUNCTION: TreeFileNode.GetRootForTab(){{{3 -"get the root node for this tab -function! s:TreeFileNode.GetRootForTab() - if s:treeExistsForTab() - return getbufvar(t:NERDTreeBufName, 'NERDTreeRoot') - end - return {} -endfunction -"FUNCTION: TreeFileNode.GetRootLineNum(){{{3 -"gets the line number of the root node -function! s:TreeFileNode.GetRootLineNum() - let rootLine = 1 - while getline(rootLine) !~# '^\(/\|<\)' - let rootLine = rootLine + 1 - endwhile - return rootLine -endfunction - -"FUNCTION: TreeFileNode.GetSelected() {{{3 -"gets the treenode that the cursor is currently over -function! s:TreeFileNode.GetSelected() - try - let path = s:getPath(line(".")) - if path ==# {} - return {} - endif - return b:NERDTreeRoot.findNode(path) - catch /NERDTree/ - return {} - endtry -endfunction -"FUNCTION: TreeFileNode.isVisible() {{{3 -"returns 1 if this node should be visible according to the tree filters and -"hidden file filters (and their on/off status) -function! s:TreeFileNode.isVisible() - return !self.path.ignore() -endfunction -"FUNCTION: TreeFileNode.isRoot() {{{3 -"returns 1 if this node is b:NERDTreeRoot -function! s:TreeFileNode.isRoot() - if !s:treeExistsForBuf() - throw "NERDTree.NoTreeError: No tree exists for the current buffer" - endif - - return self.equals(b:NERDTreeRoot) -endfunction - -"FUNCTION: TreeFileNode.makeRoot() {{{3 -"Make this node the root of the tree -function! s:TreeFileNode.makeRoot() - if self.path.isDirectory - let b:NERDTreeRoot = self - else - call self.cacheParent() - let b:NERDTreeRoot = self.parent - endif - - call b:NERDTreeRoot.open() - - "change dir to the dir of the new root if instructed to - if g:NERDTreeChDirMode ==# 2 - exec "cd " . b:NERDTreeRoot.path.str({'format': 'Edit'}) - endif -endfunction -"FUNCTION: TreeFileNode.New(path) {{{3 -"Returns a new TreeNode object with the given path and parent -" -"Args: -"path: a path object representing the full filesystem path to the file/dir that the node represents -function! s:TreeFileNode.New(path) - if a:path.isDirectory - return s:TreeDirNode.New(a:path) - else - let newTreeNode = copy(self) - let newTreeNode.path = a:path - let newTreeNode.parent = {} - return newTreeNode - endif -endfunction - -"FUNCTION: TreeFileNode.open() {{{3 -"Open the file represented by the given node in the current window, splitting -"the window if needed -" -"ARGS: -"treenode: file node to open -function! s:TreeFileNode.open() - if b:NERDTreeType ==# "secondary" - exec 'edit ' . self.path.str({'format': 'Edit'}) - return - endif - - "if the file is already open in this tab then just stick the cursor in it - let winnr = bufwinnr('^' . self.path.str() . '$') - if winnr != -1 - call s:exec(winnr . "wincmd w") - - else - if !s:isWindowUsable(winnr("#")) && s:firstUsableWindow() ==# -1 - call self.openSplit() - else - try - if !s:isWindowUsable(winnr("#")) - call s:exec(s:firstUsableWindow() . "wincmd w") - else - call s:exec('wincmd p') - endif - exec ("edit " . self.path.str({'format': 'Edit'})) - catch /^Vim\%((\a\+)\)\=:E37/ - call s:putCursorInTreeWin() - throw "NERDTree.FileAlreadyOpenAndModifiedError: ". self.path.str() ." is already open and modified." - catch /^Vim\%((\a\+)\)\=:/ - echo v:exception - endtry - endif - endif -endfunction -"FUNCTION: TreeFileNode.openSplit() {{{3 -"Open this node in a new window -function! s:TreeFileNode.openSplit() - - if b:NERDTreeType ==# "secondary" - exec "split " . self.path.str({'format': 'Edit'}) - return - endif - - " Save the user's settings for splitbelow and splitright - let savesplitbelow=&splitbelow - let savesplitright=&splitright - - " 'there' will be set to a command to move from the split window - " back to the explorer window - " - " 'back' will be set to a command to move from the explorer window - " back to the newly split window - " - " 'right' and 'below' will be set to the settings needed for - " splitbelow and splitright IF the explorer is the only window. - " - let there= g:NERDTreeWinPos ==# "left" ? "wincmd h" : "wincmd l" - let back = g:NERDTreeWinPos ==# "left" ? "wincmd l" : "wincmd h" - let right= g:NERDTreeWinPos ==# "left" - let below=0 - - " Attempt to go to adjacent window - call s:exec(back) - - let onlyOneWin = (winnr("$") ==# 1) - - " If no adjacent window, set splitright and splitbelow appropriately - if onlyOneWin - let &splitright=right - let &splitbelow=below - else - " found adjacent window - invert split direction - let &splitright=!right - let &splitbelow=!below - endif - - let splitMode = onlyOneWin ? "vertical" : "" - - " Open the new window - try - exec(splitMode." sp " . self.path.str({'format': 'Edit'})) - catch /^Vim\%((\a\+)\)\=:E37/ - call s:putCursorInTreeWin() - throw "NERDTree.FileAlreadyOpenAndModifiedError: ". self.path.str() ." is already open and modified." - catch /^Vim\%((\a\+)\)\=:/ - "do nothing - endtry - - "resize the tree window if no other window was open before - if onlyOneWin - let size = exists("b:NERDTreeOldWindowSize") ? b:NERDTreeOldWindowSize : g:NERDTreeWinSize - call s:exec(there) - exec("silent ". splitMode ." resize ". size) - call s:exec('wincmd p') - endif - - " Restore splitmode settings - let &splitbelow=savesplitbelow - let &splitright=savesplitright -endfunction -"FUNCTION: TreeFileNode.openVSplit() {{{3 -"Open this node in a new vertical window -function! s:TreeFileNode.openVSplit() - if b:NERDTreeType ==# "secondary" - exec "vnew " . self.path.str({'format': 'Edit'}) - return - endif - - let winwidth = winwidth(".") - if winnr("$")==#1 - let winwidth = g:NERDTreeWinSize - endif - - call s:exec("wincmd p") - exec "vnew " . self.path.str({'format': 'Edit'}) - - "resize the nerd tree back to the original size - call s:putCursorInTreeWin() - exec("silent vertical resize ". winwidth) - call s:exec('wincmd p') -endfunction -"FUNCTION: TreeFileNode.openInNewTab(options) {{{3 -function! s:TreeFileNode.openInNewTab(options) - let currentTab = tabpagenr() - - if !has_key(a:options, 'keepTreeOpen') - call s:closeTreeIfQuitOnOpen() - endif - - exec "tabedit " . self.path.str({'format': 'Edit'}) - - if has_key(a:options, 'stayInCurrentTab') && a:options['stayInCurrentTab'] - exec "tabnext " . currentTab - endif - -endfunction -"FUNCTION: TreeFileNode.putCursorHere(isJump, recurseUpward){{{3 -"Places the cursor on the line number this node is rendered on -" -"Args: -"isJump: 1 if this cursor movement should be counted as a jump by vim -"recurseUpward: try to put the cursor on the parent if the this node isnt -"visible -function! s:TreeFileNode.putCursorHere(isJump, recurseUpward) - let ln = self.getLineNum() - if ln != -1 - if a:isJump - mark ' - endif - call cursor(ln, col(".")) - else - if a:recurseUpward - let node = self - while node != {} && node.getLineNum() ==# -1 - let node = node.parent - call node.open() - endwhile - call s:renderView() - call node.putCursorHere(a:isJump, 0) - endif - endif -endfunction - -"FUNCTION: TreeFileNode.refresh() {{{3 -function! s:TreeFileNode.refresh() - call self.path.refresh() -endfunction -"FUNCTION: TreeFileNode.rename() {{{3 -"Calls the rename method for this nodes path obj -function! s:TreeFileNode.rename(newName) - let newName = substitute(a:newName, '\(\\\|\/\)$', '', '') - call self.path.rename(newName) - call self.parent.removeChild(self) - - let parentPath = self.path.getParent() - let newParent = b:NERDTreeRoot.findNode(parentPath) - - if newParent != {} - call newParent.createChild(self.path, 1) - call newParent.refresh() - endif -endfunction -"FUNCTION: TreeFileNode.renderToString {{{3 -"returns a string representation for this tree to be rendered in the view -function! s:TreeFileNode.renderToString() - return self._renderToString(0, 0, [], self.getChildCount() ==# 1) -endfunction - - -"Args: -"depth: the current depth in the tree for this call -"drawText: 1 if we should actually draw the line for this node (if 0 then the -"child nodes are rendered only) -"vertMap: a binary array that indicates whether a vertical bar should be draw -"for each depth in the tree -"isLastChild:true if this curNode is the last child of its parent -function! s:TreeFileNode._renderToString(depth, drawText, vertMap, isLastChild) - let output = "" - if a:drawText ==# 1 - - let treeParts = '' - - "get all the leading spaces and vertical tree parts for this line - if a:depth > 1 - for j in a:vertMap[0:-2] - if g:NERDTreeDirArrows - let treeParts = treeParts . ' ' - else - if j ==# 1 - let treeParts = treeParts . '| ' - else - let treeParts = treeParts . ' ' - endif - endif - endfor - endif - - "get the last vertical tree part for this line which will be different - "if this node is the last child of its parent - if !g:NERDTreeDirArrows - if a:isLastChild - let treeParts = treeParts . '`' - else - let treeParts = treeParts . '|' - endif - endif - - "smack the appropriate dir/file symbol on the line before the file/dir - "name itself - if self.path.isDirectory - if self.isOpen - if g:NERDTreeDirArrows - let treeParts = treeParts . '▾ ' - else - let treeParts = treeParts . '~' - endif - else - if g:NERDTreeDirArrows - let treeParts = treeParts . '▸ ' - else - let treeParts = treeParts . '+' - endif - endif - else - if g:NERDTreeDirArrows - let treeParts = treeParts . ' ' - else - let treeParts = treeParts . '-' - endif - endif - let line = treeParts . self.displayString() - - let output = output . line . "\n" - endif - - "if the node is an open dir, draw its children - if self.path.isDirectory ==# 1 && self.isOpen ==# 1 - - let childNodesToDraw = self.getVisibleChildren() - if len(childNodesToDraw) > 0 - - "draw all the nodes children except the last - let lastIndx = len(childNodesToDraw)-1 - if lastIndx > 0 - for i in childNodesToDraw[0:lastIndx-1] - let output = output . i._renderToString(a:depth + 1, 1, add(copy(a:vertMap), 1), 0) - endfor - endif - - "draw the last child, indicating that it IS the last - let output = output . childNodesToDraw[lastIndx]._renderToString(a:depth + 1, 1, add(copy(a:vertMap), 0), 1) - endif - endif - - return output -endfunction -"CLASS: TreeDirNode {{{2 -"This class is a child of the TreeFileNode class and constitutes the -"'Composite' part of the composite design pattern between the treenode -"classes. -"============================================================ -let s:TreeDirNode = copy(s:TreeFileNode) -"FUNCTION: TreeDirNode.AbsoluteTreeRoot(){{{3 -"class method that returns the highest cached ancestor of the current root -function! s:TreeDirNode.AbsoluteTreeRoot() - let currentNode = b:NERDTreeRoot - while currentNode.parent != {} - let currentNode = currentNode.parent - endwhile - return currentNode -endfunction -"FUNCTION: TreeDirNode.activate(forceKeepWinOpen) {{{3 -unlet s:TreeDirNode.activate -function! s:TreeDirNode.activate(forceKeepWinOpen) - call self.toggleOpen() - call s:renderView() - call self.putCursorHere(0, 0) -endfunction -"FUNCTION: TreeDirNode.addChild(treenode, inOrder) {{{3 -"Adds the given treenode to the list of children for this node -" -"Args: -"-treenode: the node to add -"-inOrder: 1 if the new node should be inserted in sorted order -function! s:TreeDirNode.addChild(treenode, inOrder) - call add(self.children, a:treenode) - let a:treenode.parent = self - - if a:inOrder - call self.sortChildren() - endif -endfunction - -"FUNCTION: TreeDirNode.close() {{{3 -"Closes this directory -function! s:TreeDirNode.close() - let self.isOpen = 0 -endfunction - -"FUNCTION: TreeDirNode.closeChildren() {{{3 -"Closes all the child dir nodes of this node -function! s:TreeDirNode.closeChildren() - for i in self.children - if i.path.isDirectory - call i.close() - call i.closeChildren() - endif - endfor -endfunction - -"FUNCTION: TreeDirNode.createChild(path, inOrder) {{{3 -"Instantiates a new child node for this node with the given path. The new -"nodes parent is set to this node. -" -"Args: -"path: a Path object that this node will represent/contain -"inOrder: 1 if the new node should be inserted in sorted order -" -"Returns: -"the newly created node -function! s:TreeDirNode.createChild(path, inOrder) - let newTreeNode = s:TreeFileNode.New(a:path) - call self.addChild(newTreeNode, a:inOrder) - return newTreeNode -endfunction - -"FUNCTION: TreeDirNode.findNode(path) {{{3 -"Will find one of the children (recursively) that has the given path -" -"Args: -"path: a path object -unlet s:TreeDirNode.findNode -function! s:TreeDirNode.findNode(path) - if a:path.equals(self.path) - return self - endif - if stridx(a:path.str(), self.path.str(), 0) ==# -1 - return {} - endif - - if self.path.isDirectory - for i in self.children - let retVal = i.findNode(a:path) - if retVal != {} - return retVal - endif - endfor - endif - return {} -endfunction -"FUNCTION: TreeDirNode.getChildCount() {{{3 -"Returns the number of children this node has -function! s:TreeDirNode.getChildCount() - return len(self.children) -endfunction - -"FUNCTION: TreeDirNode.getChild(path) {{{3 -"Returns child node of this node that has the given path or {} if no such node -"exists. -" -"This function doesnt not recurse into child dir nodes -" -"Args: -"path: a path object -function! s:TreeDirNode.getChild(path) - if stridx(a:path.str(), self.path.str(), 0) ==# -1 - return {} - endif - - let index = self.getChildIndex(a:path) - if index ==# -1 - return {} - else - return self.children[index] - endif - -endfunction - -"FUNCTION: TreeDirNode.getChildByIndex(indx, visible) {{{3 -"returns the child at the given index -"Args: -"indx: the index to get the child from -"visible: 1 if only the visible children array should be used, 0 if all the -"children should be searched. -function! s:TreeDirNode.getChildByIndex(indx, visible) - let array_to_search = a:visible? self.getVisibleChildren() : self.children - if a:indx > len(array_to_search) - throw "NERDTree.InvalidArgumentsError: Index is out of bounds." - endif - return array_to_search[a:indx] -endfunction - -"FUNCTION: TreeDirNode.getChildIndex(path) {{{3 -"Returns the index of the child node of this node that has the given path or -"-1 if no such node exists. -" -"This function doesnt not recurse into child dir nodes -" -"Args: -"path: a path object -function! s:TreeDirNode.getChildIndex(path) - if stridx(a:path.str(), self.path.str(), 0) ==# -1 - return -1 - endif - - "do a binary search for the child - let a = 0 - let z = self.getChildCount() - while a < z - let mid = (a+z)/2 - let diff = a:path.compareTo(self.children[mid].path) - - if diff ==# -1 - let z = mid - elseif diff ==# 1 - let a = mid+1 - else - return mid - endif - endwhile - return -1 -endfunction - -"FUNCTION: TreeDirNode.GetSelected() {{{3 -"Returns the current node if it is a dir node, or else returns the current -"nodes parent -unlet s:TreeDirNode.GetSelected -function! s:TreeDirNode.GetSelected() - let currentDir = s:TreeFileNode.GetSelected() - if currentDir != {} && !currentDir.isRoot() - if currentDir.path.isDirectory ==# 0 - let currentDir = currentDir.parent - endif - endif - return currentDir -endfunction -"FUNCTION: TreeDirNode.getVisibleChildCount() {{{3 -"Returns the number of visible children this node has -function! s:TreeDirNode.getVisibleChildCount() - return len(self.getVisibleChildren()) -endfunction - -"FUNCTION: TreeDirNode.getVisibleChildren() {{{3 -"Returns a list of children to display for this node, in the correct order -" -"Return: -"an array of treenodes -function! s:TreeDirNode.getVisibleChildren() - let toReturn = [] - for i in self.children - if i.path.ignore() ==# 0 - call add(toReturn, i) - endif - endfor - return toReturn -endfunction - -"FUNCTION: TreeDirNode.hasVisibleChildren() {{{3 -"returns 1 if this node has any childre, 0 otherwise.. -function! s:TreeDirNode.hasVisibleChildren() - return self.getVisibleChildCount() != 0 -endfunction - -"FUNCTION: TreeDirNode._initChildren() {{{3 -"Removes all childen from this node and re-reads them -" -"Args: -"silent: 1 if the function should not echo any "please wait" messages for -"large directories -" -"Return: the number of child nodes read -function! s:TreeDirNode._initChildren(silent) - "remove all the current child nodes - let self.children = [] - - "get an array of all the files in the nodes dir - let dir = self.path - let globDir = dir.str({'format': 'Glob'}) - let filesStr = globpath(globDir, '*') . "\n" . globpath(globDir, '.*') - let files = split(filesStr, "\n") - - if !a:silent && len(files) > g:NERDTreeNotificationThreshold - call s:echo("Please wait, caching a large dir ...") - endif - - let invalidFilesFound = 0 - for i in files - - "filter out the .. and . directories - "Note: we must match .. AND ../ cos sometimes the globpath returns - "../ for path with strange chars (eg $) - if i !~# '\/\.\.\/\?$' && i !~# '\/\.\/\?$' - - "put the next file in a new node and attach it - try - let path = s:Path.New(i) - call self.createChild(path, 0) - catch /^NERDTree.\(InvalidArguments\|InvalidFiletype\)Error/ - let invalidFilesFound += 1 - endtry - endif - endfor - - call self.sortChildren() - - if !a:silent && len(files) > g:NERDTreeNotificationThreshold - call s:echo("Please wait, caching a large dir ... DONE (". self.getChildCount() ." nodes cached).") - endif - - if invalidFilesFound - call s:echoWarning(invalidFilesFound . " file(s) could not be loaded into the NERD tree") - endif - return self.getChildCount() -endfunction -"FUNCTION: TreeDirNode.New(path) {{{3 -"Returns a new TreeNode object with the given path and parent -" -"Args: -"path: a path object representing the full filesystem path to the file/dir that the node represents -unlet s:TreeDirNode.New -function! s:TreeDirNode.New(path) - if a:path.isDirectory != 1 - throw "NERDTree.InvalidArgumentsError: A TreeDirNode object must be instantiated with a directory Path object." - endif - - let newTreeNode = copy(self) - let newTreeNode.path = a:path - - let newTreeNode.isOpen = 0 - let newTreeNode.children = [] - - let newTreeNode.parent = {} - - return newTreeNode -endfunction -"FUNCTION: TreeDirNode.open() {{{3 -"Reads in all this nodes children -" -"Return: the number of child nodes read -unlet s:TreeDirNode.open -function! s:TreeDirNode.open() - let self.isOpen = 1 - if self.children ==# [] - return self._initChildren(0) - else - return 0 - endif -endfunction - -" FUNCTION: TreeDirNode.openExplorer() {{{3 -" opens an explorer window for this node in the previous window (could be a -" nerd tree or a netrw) -function! s:TreeDirNode.openExplorer() - let oldwin = winnr() - call s:exec('wincmd p') - if oldwin ==# winnr() || (&modified && s:bufInWindows(winbufnr(winnr())) < 2) - call s:exec('wincmd p') - call self.openSplit() - else - exec ("silent edit " . self.path.str({'format': 'Edit'})) - endif -endfunction -"FUNCTION: TreeDirNode.openInNewTab(options) {{{3 -unlet s:TreeDirNode.openInNewTab -function! s:TreeDirNode.openInNewTab(options) - let currentTab = tabpagenr() - - if !has_key(a:options, 'keepTreeOpen') || !a:options['keepTreeOpen'] - call s:closeTreeIfQuitOnOpen() - endif - - tabnew - call s:initNerdTree(self.path.str()) - - if has_key(a:options, 'stayInCurrentTab') && a:options['stayInCurrentTab'] - exec "tabnext " . currentTab - endif -endfunction -"FUNCTION: TreeDirNode.openRecursively() {{{3 -"Opens this treenode and all of its children whose paths arent 'ignored' -"because of the file filters. -" -"This method is actually a wrapper for the OpenRecursively2 method which does -"the work. -function! s:TreeDirNode.openRecursively() - call self._openRecursively2(1) -endfunction - -"FUNCTION: TreeDirNode._openRecursively2() {{{3 -"Opens this all children of this treenode recursively if either: -" *they arent filtered by file filters -" *a:forceOpen is 1 -" -"Args: -"forceOpen: 1 if this node should be opened regardless of file filters -function! s:TreeDirNode._openRecursively2(forceOpen) - if self.path.ignore() ==# 0 || a:forceOpen - let self.isOpen = 1 - if self.children ==# [] - call self._initChildren(1) - endif - - for i in self.children - if i.path.isDirectory ==# 1 - call i._openRecursively2(0) - endif - endfor - endif -endfunction - -"FUNCTION: TreeDirNode.refresh() {{{3 -unlet s:TreeDirNode.refresh -function! s:TreeDirNode.refresh() - call self.path.refresh() - - "if this node was ever opened, refresh its children - if self.isOpen || !empty(self.children) - "go thru all the files/dirs under this node - let newChildNodes = [] - let invalidFilesFound = 0 - let dir = self.path - let globDir = dir.str({'format': 'Glob'}) - let filesStr = globpath(globDir, '*') . "\n" . globpath(globDir, '.*') - let files = split(filesStr, "\n") - for i in files - "filter out the .. and . directories - "Note: we must match .. AND ../ cos sometimes the globpath returns - "../ for path with strange chars (eg $) - if i !~# '\/\.\.\/\?$' && i !~# '\/\.\/\?$' - - try - "create a new path and see if it exists in this nodes children - let path = s:Path.New(i) - let newNode = self.getChild(path) - if newNode != {} - call newNode.refresh() - call add(newChildNodes, newNode) - - "the node doesnt exist so create it - else - let newNode = s:TreeFileNode.New(path) - let newNode.parent = self - call add(newChildNodes, newNode) - endif - - - catch /^NERDTree.InvalidArgumentsError/ - let invalidFilesFound = 1 - endtry - endif - endfor - - "swap this nodes children out for the children we just read/refreshed - let self.children = newChildNodes - call self.sortChildren() - - if invalidFilesFound - call s:echoWarning("some files could not be loaded into the NERD tree") - endif - endif -endfunction - -"FUNCTION: TreeDirNode.reveal(path) {{{3 -"reveal the given path, i.e. cache and open all treenodes needed to display it -"in the UI -function! s:TreeDirNode.reveal(path) - if !a:path.isUnder(self.path) - throw "NERDTree.InvalidArgumentsError: " . a:path.str() . " should be under " . self.path.str() - endif - - call self.open() - - if self.path.equals(a:path.getParent()) - let n = self.findNode(a:path) - call s:renderView() - call n.putCursorHere(1,0) - return - endif - - let p = a:path - while !p.getParent().equals(self.path) - let p = p.getParent() - endwhile - - let n = self.findNode(p) - call n.reveal(a:path) -endfunction -"FUNCTION: TreeDirNode.removeChild(treenode) {{{3 -" -"Removes the given treenode from this nodes set of children -" -"Args: -"treenode: the node to remove -" -"Throws a NERDTree.ChildNotFoundError if the given treenode is not found -function! s:TreeDirNode.removeChild(treenode) - for i in range(0, self.getChildCount()-1) - if self.children[i].equals(a:treenode) - call remove(self.children, i) - return - endif - endfor - - throw "NERDTree.ChildNotFoundError: child node was not found" -endfunction - -"FUNCTION: TreeDirNode.sortChildren() {{{3 -" -"Sorts the children of this node according to alphabetical order and the -"directory priority. -" -function! s:TreeDirNode.sortChildren() - let CompareFunc = function("s:compareNodes") - call sort(self.children, CompareFunc) -endfunction - -"FUNCTION: TreeDirNode.toggleOpen() {{{3 -"Opens this directory if it is closed and vice versa -function! s:TreeDirNode.toggleOpen() - if self.isOpen ==# 1 - call self.close() - else - call self.open() - endif -endfunction - -"FUNCTION: TreeDirNode.transplantChild(newNode) {{{3 -"Replaces the child of this with the given node (where the child node's full -"path matches a:newNode's fullpath). The search for the matching node is -"non-recursive -" -"Arg: -"newNode: the node to graft into the tree -function! s:TreeDirNode.transplantChild(newNode) - for i in range(0, self.getChildCount()-1) - if self.children[i].equals(a:newNode) - let self.children[i] = a:newNode - let a:newNode.parent = self - break - endif - endfor -endfunction -"============================================================ -"CLASS: Path {{{2 -"============================================================ -let s:Path = {} -"FUNCTION: Path.AbsolutePathFor(str) {{{3 -function! s:Path.AbsolutePathFor(str) - let prependCWD = 0 - if s:running_windows - let prependCWD = a:str !~# '^.:\(\\\|\/\)' - else - let prependCWD = a:str !~# '^/' - endif - - let toReturn = a:str - if prependCWD - let toReturn = getcwd() . s:Path.Slash() . a:str - endif - - return toReturn -endfunction -"FUNCTION: Path.bookmarkNames() {{{3 -function! s:Path.bookmarkNames() - if !exists("self._bookmarkNames") - call self.cacheDisplayString() - endif - return self._bookmarkNames -endfunction -"FUNCTION: Path.cacheDisplayString() {{{3 -function! s:Path.cacheDisplayString() - let self.cachedDisplayString = self.getLastPathComponent(1) - - if self.isExecutable - let self.cachedDisplayString = self.cachedDisplayString . '*' - endif - - let self._bookmarkNames = [] - for i in s:Bookmark.Bookmarks() - if i.path.equals(self) - call add(self._bookmarkNames, i.name) - endif - endfor - if !empty(self._bookmarkNames) - let self.cachedDisplayString .= ' {' . join(self._bookmarkNames) . '}' - endif - - if self.isSymLink - let self.cachedDisplayString .= ' -> ' . self.symLinkDest - endif - - if self.isReadOnly - let self.cachedDisplayString .= ' [RO]' - endif -endfunction -"FUNCTION: Path.changeToDir() {{{3 -function! s:Path.changeToDir() - let dir = self.str({'format': 'Cd'}) - if self.isDirectory ==# 0 - let dir = self.getParent().str({'format': 'Cd'}) - endif - - try - execute "cd " . dir - call s:echo("CWD is now: " . getcwd()) - catch - throw "NERDTree.PathChangeError: cannot change CWD to " . dir - endtry -endfunction - -"FUNCTION: Path.compareTo() {{{3 -" -"Compares this Path to the given path and returns 0 if they are equal, -1 if -"this Path is "less than" the given path, or 1 if it is "greater". -" -"Args: -"path: the path object to compare this to -" -"Return: -"1, -1 or 0 -function! s:Path.compareTo(path) - let thisPath = self.getLastPathComponent(1) - let thatPath = a:path.getLastPathComponent(1) - - "if the paths are the same then clearly we return 0 - if thisPath ==# thatPath - return 0 - endif - - let thisSS = self.getSortOrderIndex() - let thatSS = a:path.getSortOrderIndex() - - "compare the sort sequences, if they are different then the return - "value is easy - if thisSS < thatSS - return -1 - elseif thisSS > thatSS - return 1 - else - "if the sort sequences are the same then compare the paths - "alphabetically - let pathCompare = g:NERDTreeCaseSensitiveSort ? thisPath <# thatPath : thisPath limit - let toReturn = "<" . strpart(toReturn, len(toReturn) - limit + 1) - endif - endif - - return toReturn -endfunction - -"FUNCTION: Path._strForUI() {{{3 -function! s:Path._strForUI() - let toReturn = '/' . join(self.pathSegments, '/') - if self.isDirectory && toReturn != '/' - let toReturn = toReturn . '/' - endif - return toReturn -endfunction - -"FUNCTION: Path._strForCd() {{{3 -" -" returns a string that can be used with :cd -function! s:Path._strForCd() - return escape(self.str(), s:escape_chars) -endfunction -"FUNCTION: Path._strForEdit() {{{3 -" -"Return: the string for this path that is suitable to be used with the :edit -"command -function! s:Path._strForEdit() - let p = self.str({'format': 'UI'}) - let cwd = getcwd() - - if s:running_windows - let p = tolower(self.str()) - let cwd = tolower(getcwd()) - endif - - let p = escape(p, s:escape_chars) - - let cwd = cwd . s:Path.Slash() - - "return a relative path if we can - if stridx(p, cwd) ==# 0 - let p = strpart(p, strlen(cwd)) - endif - - if p ==# '' - let p = '.' - endif - - return p - -endfunction -"FUNCTION: Path._strForGlob() {{{3 -function! s:Path._strForGlob() - let lead = s:Path.Slash() - - "if we are running windows then slap a drive letter on the front - if s:running_windows - let lead = self.drive . '\' - endif - - let toReturn = lead . join(self.pathSegments, s:Path.Slash()) - - if !s:running_windows - let toReturn = escape(toReturn, s:escape_chars) - endif - return toReturn -endfunction -"FUNCTION: Path._str() {{{3 -" -"Gets the string path for this path object that is appropriate for the OS. -"EG, in windows c:\foo\bar -" in *nix /foo/bar -function! s:Path._str() - let lead = s:Path.Slash() - - "if we are running windows then slap a drive letter on the front - if s:running_windows - let lead = self.drive . '\' - endif - - return lead . join(self.pathSegments, s:Path.Slash()) -endfunction - -"FUNCTION: Path.strTrunk() {{{3 -"Gets the path without the last segment on the end. -function! s:Path.strTrunk() - return self.drive . '/' . join(self.pathSegments[0:-2], '/') -endfunction - -"FUNCTION: Path.WinToUnixPath(pathstr){{{3 -"Takes in a windows path and returns the unix equiv -" -"A class level method -" -"Args: -"pathstr: the windows path to convert -function! s:Path.WinToUnixPath(pathstr) - if !s:running_windows - return a:pathstr - endif - - let toReturn = a:pathstr - - "remove the x:\ of the front - let toReturn = substitute(toReturn, '^.*:\(\\\|/\)\?', '/', "") - - "convert all \ chars to / - let toReturn = substitute(toReturn, '\', '/', "g") - - return toReturn -endfunction - -" SECTION: General Functions {{{1 -"============================================================ -"FUNCTION: s:bufInWindows(bnum){{{2 -"[[STOLEN FROM VTREEEXPLORER.VIM]] -"Determine the number of windows open to this buffer number. -"Care of Yegappan Lakshman. Thanks! -" -"Args: -"bnum: the subject buffers buffer number -function! s:bufInWindows(bnum) - let cnt = 0 - let winnum = 1 - while 1 - let bufnum = winbufnr(winnum) - if bufnum < 0 - break - endif - if bufnum ==# a:bnum - let cnt = cnt + 1 - endif - let winnum = winnum + 1 - endwhile - - return cnt -endfunction " >>> -"FUNCTION: s:checkForBrowse(dir) {{{2 -"inits a secondary nerd tree in the current buffer if appropriate -function! s:checkForBrowse(dir) - if a:dir != '' && isdirectory(a:dir) - call s:initNerdTreeInPlace(a:dir) - endif -endfunction -"FUNCTION: s:compareBookmarks(first, second) {{{2 -"Compares two bookmarks -function! s:compareBookmarks(first, second) - return a:first.compareTo(a:second) -endfunction - -" FUNCTION: s:completeBookmarks(A,L,P) {{{2 -" completion function for the bookmark commands -function! s:completeBookmarks(A,L,P) - return filter(s:Bookmark.BookmarkNames(), 'v:val =~# "^' . a:A . '"') -endfunction -" FUNCTION: s:exec(cmd) {{{2 -" same as :exec cmd but eventignore=all is set for the duration -function! s:exec(cmd) - let old_ei = &ei - set ei=all - exec a:cmd - let &ei = old_ei -endfunction -" FUNCTION: s:findAndRevealPath() {{{2 -function! s:findAndRevealPath() - try - let p = s:Path.New(expand("%:p")) - catch /^NERDTree.InvalidArgumentsError/ - call s:echo("no file for the current buffer") - return - endtry - - if !s:treeExistsForTab() - try - let cwd = s:Path.New(getcwd()) - catch /^NERDTree.InvalidArgumentsError/ - call s:echo("current directory does not exist.") - let cwd = p.getParent() - endtry - - if p.isUnder(cwd) - call s:initNerdTree(cwd.str()) - else - call s:initNerdTree(p.getParent().str()) - endif - else - if !p.isUnder(s:TreeFileNode.GetRootForTab().path) - call s:initNerdTree(p.getParent().str()) - else - if !s:isTreeOpen() - call s:toggle("") - endif - endif - endif - call s:putCursorInTreeWin() - call b:NERDTreeRoot.reveal(p) -endfunction -"FUNCTION: s:initNerdTree(name) {{{2 -"Initialise the nerd tree for this tab. The tree will start in either the -"given directory, or the directory associated with the given bookmark -" -"Args: -"name: the name of a bookmark or a directory -function! s:initNerdTree(name) - let path = {} - if s:Bookmark.BookmarkExistsFor(a:name) - let path = s:Bookmark.BookmarkFor(a:name).path - else - let dir = a:name ==# '' ? getcwd() : a:name - - "hack to get an absolute path if a relative path is given - if dir =~# '^\.' - let dir = getcwd() . s:Path.Slash() . dir - endif - let dir = resolve(dir) - - try - let path = s:Path.New(dir) - catch /^NERDTree.InvalidArgumentsError/ - call s:echo("No bookmark or directory found for: " . a:name) - return - endtry - endif - if !path.isDirectory - let path = path.getParent() - endif - - "if instructed to, then change the vim CWD to the dir the NERDTree is - "inited in - if g:NERDTreeChDirMode != 0 - call path.changeToDir() - endif - - if s:treeExistsForTab() - if s:isTreeOpen() - call s:closeTree() - endif - unlet t:NERDTreeBufName - endif - - let newRoot = s:TreeDirNode.New(path) - call newRoot.open() - - call s:createTreeWin() - let b:treeShowHelp = 0 - let b:NERDTreeIgnoreEnabled = 1 - let b:NERDTreeShowFiles = g:NERDTreeShowFiles - let b:NERDTreeShowHidden = g:NERDTreeShowHidden - let b:NERDTreeShowBookmarks = g:NERDTreeShowBookmarks - let b:NERDTreeRoot = newRoot - - let b:NERDTreeType = "primary" - - call s:renderView() - call b:NERDTreeRoot.putCursorHere(0, 0) -endfunction - -"FUNCTION: s:initNerdTreeInPlace(dir) {{{2 -function! s:initNerdTreeInPlace(dir) - try - let path = s:Path.New(a:dir) - catch /^NERDTree.InvalidArgumentsError/ - call s:echo("Invalid directory name:" . a:name) - return - endtry - - "we want the directory buffer to disappear when we do the :edit below - setlocal bufhidden=wipe - - let previousBuf = expand("#") - - "we need a unique name for each secondary tree buffer to ensure they are - "all independent - exec "silent edit " . s:nextBufferName() - - let b:NERDTreePreviousBuf = bufnr(previousBuf) - - let b:NERDTreeRoot = s:TreeDirNode.New(path) - call b:NERDTreeRoot.open() - - call s:setCommonBufOptions() - let b:NERDTreeType = "secondary" - - call s:renderView() -endfunction -" FUNCTION: s:initNerdTreeMirror() {{{2 -function! s:initNerdTreeMirror() - - "get the names off all the nerd tree buffers - let treeBufNames = [] - for i in range(1, tabpagenr("$")) - let nextName = s:tabpagevar(i, 'NERDTreeBufName') - if nextName != -1 && (!exists("t:NERDTreeBufName") || nextName != t:NERDTreeBufName) - call add(treeBufNames, nextName) - endif - endfor - let treeBufNames = s:unique(treeBufNames) - - "map the option names (that the user will be prompted with) to the nerd - "tree buffer names - let options = {} - let i = 0 - while i < len(treeBufNames) - let bufName = treeBufNames[i] - let treeRoot = getbufvar(bufName, "NERDTreeRoot") - let options[i+1 . '. ' . treeRoot.path.str() . ' (buf name: ' . bufName . ')'] = bufName - let i = i + 1 - endwhile - - "work out which tree to mirror, if there is more than 1 then ask the user - let bufferName = '' - if len(keys(options)) > 1 - let choices = ["Choose a tree to mirror"] - let choices = extend(choices, sort(keys(options))) - let choice = inputlist(choices) - if choice < 1 || choice > len(options) || choice ==# '' - return - endif - - let bufferName = options[sort(keys(options))[choice-1]] - elseif len(keys(options)) ==# 1 - let bufferName = values(options)[0] - else - call s:echo("No trees to mirror") - return - endif - - if s:treeExistsForTab() && s:isTreeOpen() - call s:closeTree() - endif - - let t:NERDTreeBufName = bufferName - call s:createTreeWin() - exec 'buffer ' . bufferName - if !&hidden - call s:renderView() - endif -endfunction -" FUNCTION: s:nextBufferName() {{{2 -" returns the buffer name for the next nerd tree -function! s:nextBufferName() - let name = s:NERDTreeBufName . s:next_buffer_number - let s:next_buffer_number += 1 - return name -endfunction -" FUNCTION: s:tabpagevar(tabnr, var) {{{2 -function! s:tabpagevar(tabnr, var) - let currentTab = tabpagenr() - let old_ei = &ei - set ei=all - - exec "tabnext " . a:tabnr - let v = -1 - if exists('t:' . a:var) - exec 'let v = t:' . a:var - endif - exec "tabnext " . currentTab - - let &ei = old_ei - - return v -endfunction -" Function: s:treeExistsForBuffer() {{{2 -" Returns 1 if a nerd tree root exists in the current buffer -function! s:treeExistsForBuf() - return exists("b:NERDTreeRoot") -endfunction -" Function: s:treeExistsForTab() {{{2 -" Returns 1 if a nerd tree root exists in the current tab -function! s:treeExistsForTab() - return exists("t:NERDTreeBufName") -endfunction -" Function: s:unique(list) {{{2 -" returns a:list without duplicates -function! s:unique(list) - let uniqlist = [] - for elem in a:list - if index(uniqlist, elem) ==# -1 - let uniqlist += [elem] - endif - endfor - return uniqlist -endfunction -" SECTION: Public API {{{1 -"============================================================ -let g:NERDTreePath = s:Path -let g:NERDTreeDirNode = s:TreeDirNode -let g:NERDTreeFileNode = s:TreeFileNode -let g:NERDTreeBookmark = s:Bookmark - -function! NERDTreeAddMenuItem(options) - call s:MenuItem.Create(a:options) -endfunction - -function! NERDTreeAddMenuSeparator(...) - let opts = a:0 ? a:1 : {} - call s:MenuItem.CreateSeparator(opts) -endfunction - -function! NERDTreeAddSubmenu(options) - return s:MenuItem.Create(a:options) -endfunction - -function! NERDTreeAddKeyMap(options) - call s:KeyMap.Create(a:options) -endfunction - -function! NERDTreeRender() - call s:renderView() -endfunction - -" SECTION: View Functions {{{1 -"============================================================ -"FUNCTION: s:centerView() {{{2 -"centers the nerd tree window around the cursor (provided the nerd tree -"options permit) -function! s:centerView() - if g:NERDTreeAutoCenter - let current_line = winline() - let lines_to_top = current_line - let lines_to_bottom = winheight(s:getTreeWinNum()) - current_line - if lines_to_top < g:NERDTreeAutoCenterThreshold || lines_to_bottom < g:NERDTreeAutoCenterThreshold - normal! zz - endif - endif -endfunction -"FUNCTION: s:closeTree() {{{2 -"Closes the primary NERD tree window for this tab -function! s:closeTree() - if !s:isTreeOpen() - throw "NERDTree.NoTreeFoundError: no NERDTree is open" - endif - - if winnr("$") != 1 - if winnr() == s:getTreeWinNum() - wincmd p - let bufnr = bufnr("") - wincmd p - else - let bufnr = bufnr("") - endif - - call s:exec(s:getTreeWinNum() . " wincmd w") - close - call s:exec(bufwinnr(bufnr) . " wincmd w") - else - close - endif -endfunction - -"FUNCTION: s:closeTreeIfOpen() {{{2 -"Closes the NERD tree window if it is open -function! s:closeTreeIfOpen() - if s:isTreeOpen() - call s:closeTree() - endif -endfunction -"FUNCTION: s:closeTreeIfQuitOnOpen() {{{2 -"Closes the NERD tree window if the close on open option is set -function! s:closeTreeIfQuitOnOpen() - if g:NERDTreeQuitOnOpen && s:isTreeOpen() - call s:closeTree() - endif -endfunction -"FUNCTION: s:createTreeWin() {{{2 -"Inits the NERD tree window. ie. opens it, sizes it, sets all the local -"options etc -function! s:createTreeWin() - "create the nerd tree window - let splitLocation = g:NERDTreeWinPos ==# "left" ? "topleft " : "botright " - let splitSize = g:NERDTreeWinSize - - if !exists('t:NERDTreeBufName') - let t:NERDTreeBufName = s:nextBufferName() - silent! exec splitLocation . 'vertical ' . splitSize . ' new' - silent! exec "edit " . t:NERDTreeBufName - else - silent! exec splitLocation . 'vertical ' . splitSize . ' split' - silent! exec "buffer " . t:NERDTreeBufName - endif - - setlocal winfixwidth - call s:setCommonBufOptions() -endfunction - -"FUNCTION: s:dumpHelp {{{2 -"prints out the quick help -function! s:dumpHelp() - let old_h = @h - if b:treeShowHelp ==# 1 - let @h= "\" NERD tree (" . s:NERD_tree_version . ") quickhelp~\n" - let @h=@h."\" ============================\n" - let @h=@h."\" File node mappings~\n" - let @h=@h."\" ". (g:NERDTreeMouseMode ==# 3 ? "single" : "double") ."-click,\n" - let @h=@h."\" ,\n" - if b:NERDTreeType ==# "primary" - let @h=@h."\" ". g:NERDTreeMapActivateNode .": open in prev window\n" - else - let @h=@h."\" ". g:NERDTreeMapActivateNode .": open in current window\n" - endif - if b:NERDTreeType ==# "primary" - let @h=@h."\" ". g:NERDTreeMapPreview .": preview\n" - endif - let @h=@h."\" ". g:NERDTreeMapOpenInTab.": open in new tab\n" - let @h=@h."\" ". g:NERDTreeMapOpenInTabSilent .": open in new tab silently\n" - let @h=@h."\" middle-click,\n" - let @h=@h."\" ". g:NERDTreeMapOpenSplit .": open split\n" - let @h=@h."\" ". g:NERDTreeMapPreviewSplit .": preview split\n" - let @h=@h."\" ". g:NERDTreeMapOpenVSplit .": open vsplit\n" - let @h=@h."\" ". g:NERDTreeMapPreviewVSplit .": preview vsplit\n" - - let @h=@h."\"\n\" ----------------------------\n" - let @h=@h."\" Directory node mappings~\n" - let @h=@h."\" ". (g:NERDTreeMouseMode ==# 1 ? "double" : "single") ."-click,\n" - let @h=@h."\" ". g:NERDTreeMapActivateNode .": open & close node\n" - let @h=@h."\" ". g:NERDTreeMapOpenRecursively .": recursively open node\n" - let @h=@h."\" ". g:NERDTreeMapCloseDir .": close parent of node\n" - let @h=@h."\" ". g:NERDTreeMapCloseChildren .": close all child nodes of\n" - let @h=@h."\" current node recursively\n" - let @h=@h."\" middle-click,\n" - let @h=@h."\" ". g:NERDTreeMapOpenExpl.": explore selected dir\n" - - let @h=@h."\"\n\" ----------------------------\n" - let @h=@h."\" Bookmark table mappings~\n" - let @h=@h."\" double-click,\n" - let @h=@h."\" ". g:NERDTreeMapActivateNode .": open bookmark\n" - let @h=@h."\" ". g:NERDTreeMapOpenInTab.": open in new tab\n" - let @h=@h."\" ". g:NERDTreeMapOpenInTabSilent .": open in new tab silently\n" - let @h=@h."\" ". g:NERDTreeMapDeleteBookmark .": delete bookmark\n" - - let @h=@h."\"\n\" ----------------------------\n" - let @h=@h."\" Tree navigation mappings~\n" - let @h=@h."\" ". g:NERDTreeMapJumpRoot .": go to root\n" - let @h=@h."\" ". g:NERDTreeMapJumpParent .": go to parent\n" - let @h=@h."\" ". g:NERDTreeMapJumpFirstChild .": go to first child\n" - let @h=@h."\" ". g:NERDTreeMapJumpLastChild .": go to last child\n" - let @h=@h."\" ". g:NERDTreeMapJumpNextSibling .": go to next sibling\n" - let @h=@h."\" ". g:NERDTreeMapJumpPrevSibling .": go to prev sibling\n" - - let @h=@h."\"\n\" ----------------------------\n" - let @h=@h."\" Filesystem mappings~\n" - let @h=@h."\" ". g:NERDTreeMapChangeRoot .": change tree root to the\n" - let @h=@h."\" selected dir\n" - let @h=@h."\" ". g:NERDTreeMapUpdir .": move tree root up a dir\n" - let @h=@h."\" ". g:NERDTreeMapUpdirKeepOpen .": move tree root up a dir\n" - let @h=@h."\" but leave old root open\n" - let @h=@h."\" ". g:NERDTreeMapRefresh .": refresh cursor dir\n" - let @h=@h."\" ". g:NERDTreeMapRefreshRoot .": refresh current root\n" - let @h=@h."\" ". g:NERDTreeMapMenu .": Show menu\n" - let @h=@h."\" ". g:NERDTreeMapChdir .":change the CWD to the\n" - let @h=@h."\" selected dir\n" - - let @h=@h."\"\n\" ----------------------------\n" - let @h=@h."\" Tree filtering mappings~\n" - let @h=@h."\" ". g:NERDTreeMapToggleHidden .": hidden files (" . (b:NERDTreeShowHidden ? "on" : "off") . ")\n" - let @h=@h."\" ". g:NERDTreeMapToggleFilters .": file filters (" . (b:NERDTreeIgnoreEnabled ? "on" : "off") . ")\n" - let @h=@h."\" ". g:NERDTreeMapToggleFiles .": files (" . (b:NERDTreeShowFiles ? "on" : "off") . ")\n" - let @h=@h."\" ". g:NERDTreeMapToggleBookmarks .": bookmarks (" . (b:NERDTreeShowBookmarks ? "on" : "off") . ")\n" - - "add quickhelp entries for each custom key map - if len(s:KeyMap.All()) - let @h=@h."\"\n\" ----------------------------\n" - let @h=@h."\" Custom mappings~\n" - for i in s:KeyMap.All() - let @h=@h."\" ". i.key .": ". i.quickhelpText ."\n" - endfor - endif - - let @h=@h."\"\n\" ----------------------------\n" - let @h=@h."\" Other mappings~\n" - let @h=@h."\" ". g:NERDTreeMapQuit .": Close the NERDTree window\n" - let @h=@h."\" ". g:NERDTreeMapToggleZoom .": Zoom (maximize-minimize)\n" - let @h=@h."\" the NERDTree window\n" - let @h=@h."\" ". g:NERDTreeMapHelp .": toggle help\n" - let @h=@h."\"\n\" ----------------------------\n" - let @h=@h."\" Bookmark commands~\n" - let @h=@h."\" :Bookmark \n" - let @h=@h."\" :BookmarkToRoot \n" - let @h=@h."\" :RevealBookmark \n" - let @h=@h."\" :OpenBookmark \n" - let @h=@h."\" :ClearBookmarks []\n" - let @h=@h."\" :ClearAllBookmarks\n" - silent! put h - elseif g:NERDTreeMinimalUI == 0 - let @h="\" Press ". g:NERDTreeMapHelp ." for help\n" - silent! put h - endif - - let @h = old_h -endfunction -"FUNCTION: s:echo {{{2 -"A wrapper for :echo. Appends 'NERDTree:' on the front of all messages -" -"Args: -"msg: the message to echo -function! s:echo(msg) - redraw - echomsg "NERDTree: " . a:msg -endfunction -"FUNCTION: s:echoWarning {{{2 -"Wrapper for s:echo, sets the message type to warningmsg for this message -"Args: -"msg: the message to echo -function! s:echoWarning(msg) - echohl warningmsg - call s:echo(a:msg) - echohl normal -endfunction -"FUNCTION: s:echoError {{{2 -"Wrapper for s:echo, sets the message type to errormsg for this message -"Args: -"msg: the message to echo -function! s:echoError(msg) - echohl errormsg - call s:echo(a:msg) - echohl normal -endfunction -"FUNCTION: s:firstUsableWindow(){{{2 -"find the window number of the first normal window -function! s:firstUsableWindow() - let i = 1 - while i <= winnr("$") - let bnum = winbufnr(i) - if bnum != -1 && getbufvar(bnum, '&buftype') ==# '' - \ && !getwinvar(i, '&previewwindow') - \ && (!getbufvar(bnum, '&modified') || &hidden) - return i - endif - - let i += 1 - endwhile - return -1 -endfunction -"FUNCTION: s:getPath(ln) {{{2 -"Gets the full path to the node that is rendered on the given line number -" -"Args: -"ln: the line number to get the path for -" -"Return: -"A path if a node was selected, {} if nothing is selected. -"If the 'up a dir' line was selected then the path to the parent of the -"current root is returned -function! s:getPath(ln) - let line = getline(a:ln) - - let rootLine = s:TreeFileNode.GetRootLineNum() - - "check to see if we have the root node - if a:ln == rootLine - return b:NERDTreeRoot.path - endif - - if !g:NERDTreeDirArrows - " in case called from outside the tree - if line !~# '^ *[|`▸▾ ]' || line =~# '^$' - return {} - endif - endif - - if line ==# s:tree_up_dir_line - return b:NERDTreeRoot.path.getParent() - endif - - let indent = s:indentLevelFor(line) - - "remove the tree parts and the leading space - let curFile = s:stripMarkupFromLine(line, 0) - - let wasdir = 0 - if curFile =~# '/$' - let wasdir = 1 - let curFile = substitute(curFile, '/\?$', '/', "") - endif - - let dir = "" - let lnum = a:ln - while lnum > 0 - let lnum = lnum - 1 - let curLine = getline(lnum) - let curLineStripped = s:stripMarkupFromLine(curLine, 1) - - "have we reached the top of the tree? - if lnum == rootLine - let dir = b:NERDTreeRoot.path.str({'format': 'UI'}) . dir - break - endif - if curLineStripped =~# '/$' - let lpindent = s:indentLevelFor(curLine) - if lpindent < indent - let indent = indent - 1 - - let dir = substitute (curLineStripped,'^\\', "", "") . dir - continue - endif - endif - endwhile - let curFile = b:NERDTreeRoot.path.drive . dir . curFile - let toReturn = s:Path.New(curFile) - return toReturn -endfunction - -"FUNCTION: s:getTreeWinNum() {{{2 -"gets the nerd tree window number for this tab -function! s:getTreeWinNum() - if exists("t:NERDTreeBufName") - return bufwinnr(t:NERDTreeBufName) - else - return -1 - endif -endfunction -"FUNCTION: s:indentLevelFor(line) {{{2 -function! s:indentLevelFor(line) - let level = match(a:line, '[^ \-+~▸▾`|]') / s:tree_wid - " check if line includes arrows - if match(a:line, '[▸▾]') > -1 - " decrement level as arrow uses 3 ascii chars - let level = level - 1 - endif - return level -endfunction -"FUNCTION: s:isTreeOpen() {{{2 -function! s:isTreeOpen() - return s:getTreeWinNum() != -1 -endfunction -"FUNCTION: s:isWindowUsable(winnumber) {{{2 -"Returns 0 if opening a file from the tree in the given window requires it to -"be split, 1 otherwise -" -"Args: -"winnumber: the number of the window in question -function! s:isWindowUsable(winnumber) - "gotta split if theres only one window (i.e. the NERD tree) - if winnr("$") ==# 1 - return 0 - endif - - let oldwinnr = winnr() - call s:exec(a:winnumber . "wincmd p") - let specialWindow = getbufvar("%", '&buftype') != '' || getwinvar('%', '&previewwindow') - let modified = &modified - call s:exec(oldwinnr . "wincmd p") - - "if its a special window e.g. quickfix or another explorer plugin then we - "have to split - if specialWindow - return 0 - endif - - if &hidden - return 1 - endif - - return !modified || s:bufInWindows(winbufnr(a:winnumber)) >= 2 -endfunction - -" FUNCTION: s:jumpToChild(direction) {{{2 -" Args: -" direction: 0 if going to first child, 1 if going to last -function! s:jumpToChild(direction) - let currentNode = s:TreeFileNode.GetSelected() - if currentNode ==# {} || currentNode.isRoot() - call s:echo("cannot jump to " . (a:direction ? "last" : "first") . " child") - return - end - let dirNode = currentNode.parent - let childNodes = dirNode.getVisibleChildren() - - let targetNode = childNodes[0] - if a:direction - let targetNode = childNodes[len(childNodes) - 1] - endif - - if targetNode.equals(currentNode) - let siblingDir = currentNode.parent.findOpenDirSiblingWithVisibleChildren(a:direction) - if siblingDir != {} - let indx = a:direction ? siblingDir.getVisibleChildCount()-1 : 0 - let targetNode = siblingDir.getChildByIndex(indx, 1) - endif - endif - - call targetNode.putCursorHere(1, 0) - - call s:centerView() -endfunction - - -"FUNCTION: s:promptToDelBuffer(bufnum, msg){{{2 -"prints out the given msg and, if the user responds by pushing 'y' then the -"buffer with the given bufnum is deleted -" -"Args: -"bufnum: the buffer that may be deleted -"msg: a message that will be echoed to the user asking them if they wish to -" del the buffer -function! s:promptToDelBuffer(bufnum, msg) - echo a:msg - if nr2char(getchar()) ==# 'y' - exec "silent bdelete! " . a:bufnum - endif -endfunction - -"FUNCTION: s:putCursorOnBookmarkTable(){{{2 -"Places the cursor at the top of the bookmarks table -function! s:putCursorOnBookmarkTable() - if !b:NERDTreeShowBookmarks - throw "NERDTree.IllegalOperationError: cant find bookmark table, bookmarks arent active" - endif - - if g:NERDTreeMinimalUI - return cursor(1, 2) - endif - - let rootNodeLine = s:TreeFileNode.GetRootLineNum() - - let line = 1 - while getline(line) !~# '^>-\+Bookmarks-\+$' - let line = line + 1 - if line >= rootNodeLine - throw "NERDTree.BookmarkTableNotFoundError: didnt find the bookmarks table" - endif - endwhile - call cursor(line, 2) -endfunction - -"FUNCTION: s:putCursorInTreeWin(){{{2 -"Places the cursor in the nerd tree window -function! s:putCursorInTreeWin() - if !s:isTreeOpen() - throw "NERDTree.InvalidOperationError: cant put cursor in NERD tree window, no window exists" - endif - - call s:exec(s:getTreeWinNum() . "wincmd w") -endfunction - -"FUNCTION: s:renderBookmarks {{{2 -function! s:renderBookmarks() - - if g:NERDTreeMinimalUI == 0 - call setline(line(".")+1, ">----------Bookmarks----------") - call cursor(line(".")+1, col(".")) - endif - - for i in s:Bookmark.Bookmarks() - call setline(line(".")+1, i.str()) - call cursor(line(".")+1, col(".")) - endfor - - call setline(line(".")+1, '') - call cursor(line(".")+1, col(".")) -endfunction -"FUNCTION: s:renderView {{{2 -"The entry function for rendering the tree -function! s:renderView() - setlocal modifiable - - "remember the top line of the buffer and the current line so we can - "restore the view exactly how it was - let curLine = line(".") - let curCol = col(".") - let topLine = line("w0") - - "delete all lines in the buffer (being careful not to clobber a register) - silent 1,$delete _ - - call s:dumpHelp() - - "delete the blank line before the help and add one after it - if g:NERDTreeMinimalUI == 0 - call setline(line(".")+1, "") - call cursor(line(".")+1, col(".")) - endif - - if b:NERDTreeShowBookmarks - call s:renderBookmarks() - endif - - "add the 'up a dir' line - if !g:NERDTreeMinimalUI - call setline(line(".")+1, s:tree_up_dir_line) - call cursor(line(".")+1, col(".")) - endif - - "draw the header line - let header = b:NERDTreeRoot.path.str({'format': 'UI', 'truncateTo': winwidth(0)}) - call setline(line(".")+1, header) - call cursor(line(".")+1, col(".")) - - "draw the tree - let old_o = @o - let @o = b:NERDTreeRoot.renderToString() - silent put o - let @o = old_o - - "delete the blank line at the top of the buffer - silent 1,1delete _ - - "restore the view - let old_scrolloff=&scrolloff - let &scrolloff=0 - call cursor(topLine, 1) - normal! zt - call cursor(curLine, curCol) - let &scrolloff = old_scrolloff - - setlocal nomodifiable -endfunction - -"FUNCTION: s:renderViewSavingPosition {{{2 -"Renders the tree and ensures the cursor stays on the current node or the -"current nodes parent if it is no longer available upon re-rendering -function! s:renderViewSavingPosition() - let currentNode = s:TreeFileNode.GetSelected() - - "go up the tree till we find a node that will be visible or till we run - "out of nodes - while currentNode != {} && !currentNode.isVisible() && !currentNode.isRoot() - let currentNode = currentNode.parent - endwhile - - call s:renderView() - - if currentNode != {} - call currentNode.putCursorHere(0, 0) - endif -endfunction -"FUNCTION: s:restoreScreenState() {{{2 -" -"Sets the screen state back to what it was when s:saveScreenState was last -"called. -" -"Assumes the cursor is in the NERDTree window -function! s:restoreScreenState() - if !exists("b:NERDTreeOldTopLine") || !exists("b:NERDTreeOldPos") || !exists("b:NERDTreeOldWindowSize") - return - endif - exec("silent vertical resize ".b:NERDTreeOldWindowSize) - - let old_scrolloff=&scrolloff - let &scrolloff=0 - call cursor(b:NERDTreeOldTopLine, 0) - normal! zt - call setpos(".", b:NERDTreeOldPos) - let &scrolloff=old_scrolloff -endfunction - -"FUNCTION: s:saveScreenState() {{{2 -"Saves the current cursor position in the current buffer and the window -"scroll position -function! s:saveScreenState() - let win = winnr() - try - call s:putCursorInTreeWin() - let b:NERDTreeOldPos = getpos(".") - let b:NERDTreeOldTopLine = line("w0") - let b:NERDTreeOldWindowSize = winwidth("") - call s:exec(win . "wincmd w") - catch /^NERDTree.InvalidOperationError/ - endtry -endfunction - -"FUNCTION: s:setCommonBufOptions() {{{2 -function! s:setCommonBufOptions() - "throwaway buffer options - setlocal noswapfile - setlocal buftype=nofile - setlocal bufhidden=hide - setlocal nowrap - setlocal foldcolumn=0 - setlocal nobuflisted - setlocal nospell - if g:NERDTreeShowLineNumbers - setlocal nu - else - setlocal nonu - if v:version >= 703 - setlocal nornu - endif - endif - - iabc - - if g:NERDTreeHighlightCursorline - setlocal cursorline - endif - - call s:setupStatusline() - - - let b:treeShowHelp = 0 - let b:NERDTreeIgnoreEnabled = 1 - let b:NERDTreeShowFiles = g:NERDTreeShowFiles - let b:NERDTreeShowHidden = g:NERDTreeShowHidden - let b:NERDTreeShowBookmarks = g:NERDTreeShowBookmarks - setfiletype nerdtree - call s:bindMappings() -endfunction - -"FUNCTION: s:setupStatusline() {{{2 -function! s:setupStatusline() - if g:NERDTreeStatusline != -1 - let &l:statusline = g:NERDTreeStatusline - endif -endfunction -"FUNCTION: s:stripMarkupFromLine(line, removeLeadingSpaces){{{2 -"returns the given line with all the tree parts stripped off -" -"Args: -"line: the subject line -"removeLeadingSpaces: 1 if leading spaces are to be removed (leading spaces = -"any spaces before the actual text of the node) -function! s:stripMarkupFromLine(line, removeLeadingSpaces) - let line = a:line - "remove the tree parts and the leading space - let line = substitute (line, s:tree_markup_reg,"","") - - "strip off any read only flag - let line = substitute (line, ' \[RO\]', "","") - - "strip off any bookmark flags - let line = substitute (line, ' {[^}]*}', "","") - - "strip off any executable flags - let line = substitute (line, '*\ze\($\| \)', "","") - - let wasdir = 0 - if line =~# '/$' - let wasdir = 1 - endif - let line = substitute (line,' -> .*',"","") " remove link to - if wasdir ==# 1 - let line = substitute (line, '/\?$', '/', "") - endif - - if a:removeLeadingSpaces - let line = substitute (line, '^ *', '', '') - endif - - return line -endfunction - -"FUNCTION: s:toggle(dir) {{{2 -"Toggles the NERD tree. I.e the NERD tree is open, it is closed, if it is -"closed it is restored or initialized (if it doesnt exist) -" -"Args: -"dir: the full path for the root node (is only used if the NERD tree is being -"initialized. -function! s:toggle(dir) - if s:treeExistsForTab() - if !s:isTreeOpen() - call s:createTreeWin() - if !&hidden - call s:renderView() - endif - call s:restoreScreenState() - else - call s:closeTree() - endif - else - call s:initNerdTree(a:dir) - endif -endfunction -"SECTION: Interface bindings {{{1 -"============================================================ -"FUNCTION: s:activateNode(forceKeepWindowOpen) {{{2 -"If the current node is a file, open it in the previous window (or a new one -"if the previous is modified). If it is a directory then it is opened. -" -"args: -"forceKeepWindowOpen - dont close the window even if NERDTreeQuitOnOpen is set -function! s:activateNode(forceKeepWindowOpen) - if getline(".") ==# s:tree_up_dir_line - return s:upDir(0) - endif - - let treenode = s:TreeFileNode.GetSelected() - if treenode != {} - call treenode.activate(a:forceKeepWindowOpen) - else - let bookmark = s:Bookmark.GetSelected() - if !empty(bookmark) - call bookmark.activate() - endif - endif -endfunction - -"FUNCTION: s:bindMappings() {{{2 -function! s:bindMappings() - " set up mappings and commands for this buffer - nnoremap :call handleMiddleMouse() - nnoremap :call checkForActivate() - nnoremap <2-leftmouse> :call activateNode(0) - - exec "nnoremap ". g:NERDTreeMapActivateNode . " :call activateNode(0)" - exec "nnoremap ". g:NERDTreeMapOpenSplit ." :call openEntrySplit(0,0)" - exec "nnoremap :call activateNode(0)" - - exec "nnoremap ". g:NERDTreeMapPreview ." :call previewNode(0)" - exec "nnoremap ". g:NERDTreeMapPreviewSplit ." :call previewNode(1)" - - exec "nnoremap ". g:NERDTreeMapOpenVSplit ." :call openEntrySplit(1,0)" - exec "nnoremap ". g:NERDTreeMapPreviewVSplit ." :call previewNode(2)" - - exec "nnoremap ". g:NERDTreeMapOpenRecursively ." :call openNodeRecursively()" - - exec "nnoremap ". g:NERDTreeMapUpdirKeepOpen ." :call upDir(1)" - exec "nnoremap ". g:NERDTreeMapUpdir ." :call upDir(0)" - exec "nnoremap ". g:NERDTreeMapChangeRoot ." :call chRoot()" - - exec "nnoremap ". g:NERDTreeMapChdir ." :call chCwd()" - - exec "nnoremap ". g:NERDTreeMapQuit ." :call closeTreeWindow()" - - exec "nnoremap ". g:NERDTreeMapRefreshRoot ." :call refreshRoot()" - exec "nnoremap ". g:NERDTreeMapRefresh ." :call refreshCurrent()" - - exec "nnoremap ". g:NERDTreeMapHelp ." :call displayHelp()" - exec "nnoremap ". g:NERDTreeMapToggleZoom ." :call toggleZoom()" - exec "nnoremap ". g:NERDTreeMapToggleHidden ." :call toggleShowHidden()" - exec "nnoremap ". g:NERDTreeMapToggleFilters ." :call toggleIgnoreFilter()" - exec "nnoremap ". g:NERDTreeMapToggleFiles ." :call toggleShowFiles()" - exec "nnoremap ". g:NERDTreeMapToggleBookmarks ." :call toggleShowBookmarks()" - - exec "nnoremap ". g:NERDTreeMapCloseDir ." :call closeCurrentDir()" - exec "nnoremap ". g:NERDTreeMapCloseChildren ." :call closeChildren()" - - exec "nnoremap ". g:NERDTreeMapMenu ." :call showMenu()" - - exec "nnoremap ". g:NERDTreeMapJumpParent ." :call jumpToParent()" - exec "nnoremap ". g:NERDTreeMapJumpNextSibling ." :call jumpToSibling(1)" - exec "nnoremap ". g:NERDTreeMapJumpPrevSibling ." :call jumpToSibling(0)" - exec "nnoremap ". g:NERDTreeMapJumpFirstChild ." :call jumpToFirstChild()" - exec "nnoremap ". g:NERDTreeMapJumpLastChild ." :call jumpToLastChild()" - exec "nnoremap ". g:NERDTreeMapJumpRoot ." :call jumpToRoot()" - - exec "nnoremap ". g:NERDTreeMapOpenInTab ." :call openInNewTab(0)" - exec "nnoremap ". g:NERDTreeMapOpenInTabSilent ." :call openInNewTab(1)" - - exec "nnoremap ". g:NERDTreeMapOpenExpl ." :call openExplorer()" - - exec "nnoremap ". g:NERDTreeMapDeleteBookmark ." :call deleteBookmark()" - - "bind all the user custom maps - call s:KeyMap.BindAll() - - command! -buffer -nargs=? Bookmark :call bookmarkNode('') - command! -buffer -complete=customlist,s:completeBookmarks -nargs=1 RevealBookmark :call revealBookmark('') - command! -buffer -complete=customlist,s:completeBookmarks -nargs=1 OpenBookmark :call openBookmark('') - command! -buffer -complete=customlist,s:completeBookmarks -nargs=* ClearBookmarks call clearBookmarks('') - command! -buffer -complete=customlist,s:completeBookmarks -nargs=+ BookmarkToRoot call s:Bookmark.ToRoot('') - command! -buffer -nargs=0 ClearAllBookmarks call s:Bookmark.ClearAll() call renderView() - command! -buffer -nargs=0 ReadBookmarks call s:Bookmark.CacheBookmarks(0) call renderView() - command! -buffer -nargs=0 WriteBookmarks call s:Bookmark.Write() -endfunction - -" FUNCTION: s:bookmarkNode(name) {{{2 -" Associate the current node with the given name -function! s:bookmarkNode(...) - let currentNode = s:TreeFileNode.GetSelected() - if currentNode != {} - let name = a:1 - if empty(name) - let name = currentNode.path.getLastPathComponent(0) - endif - try - call currentNode.bookmark(name) - call s:renderView() - catch /^NERDTree.IllegalBookmarkNameError/ - call s:echo("bookmark names must not contain spaces") - endtry - else - call s:echo("select a node first") - endif -endfunction -"FUNCTION: s:checkForActivate() {{{2 -"Checks if the click should open the current node, if so then activate() is -"called (directories are automatically opened if the symbol beside them is -"clicked) -function! s:checkForActivate() - let currentNode = s:TreeFileNode.GetSelected() - if currentNode != {} - let startToCur = strpart(getline(line(".")), 0, col(".")) - - if currentNode.path.isDirectory - if startToCur =~# s:tree_markup_reg . '$' && startToCur =~# '[+~▾▸]$' - call s:activateNode(0) - return - endif - endif - - if (g:NERDTreeMouseMode ==# 2 && currentNode.path.isDirectory) || g:NERDTreeMouseMode ==# 3 - let char = strpart(startToCur, strlen(startToCur)-1, 1) - if char !~# s:tree_markup_reg - call s:activateNode(0) - return - endif - endif - endif -endfunction - -" FUNCTION: s:chCwd() {{{2 -function! s:chCwd() - let treenode = s:TreeFileNode.GetSelected() - if treenode ==# {} - call s:echo("Select a node first") - return - endif - - try - call treenode.path.changeToDir() - catch /^NERDTree.PathChangeError/ - call s:echoWarning("could not change cwd") - endtry -endfunction - -" FUNCTION: s:chRoot() {{{2 -" changes the current root to the selected one -function! s:chRoot() - let treenode = s:TreeFileNode.GetSelected() - if treenode ==# {} - call s:echo("Select a node first") - return - endif - - call treenode.makeRoot() - call s:renderView() - call b:NERDTreeRoot.putCursorHere(0, 0) -endfunction - -" FUNCTION: s:clearBookmarks(bookmarks) {{{2 -function! s:clearBookmarks(bookmarks) - if a:bookmarks ==# '' - let currentNode = s:TreeFileNode.GetSelected() - if currentNode != {} - call currentNode.clearBoomarks() - endif - else - for name in split(a:bookmarks, ' ') - let bookmark = s:Bookmark.BookmarkFor(name) - call bookmark.delete() - endfor - endif - call s:renderView() -endfunction -" FUNCTION: s:closeChildren() {{{2 -" closes all childnodes of the current node -function! s:closeChildren() - let currentNode = s:TreeDirNode.GetSelected() - if currentNode ==# {} - call s:echo("Select a node first") - return - endif - - call currentNode.closeChildren() - call s:renderView() - call currentNode.putCursorHere(0, 0) -endfunction -" FUNCTION: s:closeCurrentDir() {{{2 -" closes the parent dir of the current node -function! s:closeCurrentDir() - let treenode = s:TreeFileNode.GetSelected() - if treenode ==# {} - call s:echo("Select a node first") - return - endif - - let parent = treenode.parent - if parent ==# {} || parent.isRoot() - call s:echo("cannot close tree root") - else - call treenode.parent.close() - call s:renderView() - call treenode.parent.putCursorHere(0, 0) - endif -endfunction -" FUNCTION: s:closeTreeWindow() {{{2 -" close the tree window -function! s:closeTreeWindow() - if b:NERDTreeType ==# "secondary" && b:NERDTreePreviousBuf != -1 - exec "buffer " . b:NERDTreePreviousBuf - else - if winnr("$") > 1 - call s:closeTree() - else - call s:echo("Cannot close last window") - endif - endif -endfunction -" FUNCTION: s:deleteBookmark() {{{2 -" if the cursor is on a bookmark, prompt to delete -function! s:deleteBookmark() - let bookmark = s:Bookmark.GetSelected() - if bookmark ==# {} - call s:echo("Put the cursor on a bookmark") - return - endif - - echo "Are you sure you wish to delete the bookmark:\n\"" . bookmark.name . "\" (yN):" - - if nr2char(getchar()) ==# 'y' - try - call bookmark.delete() - call s:renderView() - redraw - catch /^NERDTree/ - call s:echoWarning("Could not remove bookmark") - endtry - else - call s:echo("delete aborted" ) - endif - -endfunction - -" FUNCTION: s:displayHelp() {{{2 -" toggles the help display -function! s:displayHelp() - let b:treeShowHelp = b:treeShowHelp ? 0 : 1 - call s:renderView() - call s:centerView() -endfunction - -" FUNCTION: s:handleMiddleMouse() {{{2 -function! s:handleMiddleMouse() - let curNode = s:TreeFileNode.GetSelected() - if curNode ==# {} - call s:echo("Put the cursor on a node first" ) - return - endif - - if curNode.path.isDirectory - call s:openExplorer() - else - call s:openEntrySplit(0,0) - endif -endfunction - - -" FUNCTION: s:jumpToFirstChild() {{{2 -" wrapper for the jump to child method -function! s:jumpToFirstChild() - call s:jumpToChild(0) -endfunction - -" FUNCTION: s:jumpToLastChild() {{{2 -" wrapper for the jump to child method -function! s:jumpToLastChild() - call s:jumpToChild(1) -endfunction - -" FUNCTION: s:jumpToParent() {{{2 -" moves the cursor to the parent of the current node -function! s:jumpToParent() - let currentNode = s:TreeFileNode.GetSelected() - if !empty(currentNode) - if !empty(currentNode.parent) - call currentNode.parent.putCursorHere(1, 0) - call s:centerView() - else - call s:echo("cannot jump to parent") - endif - else - call s:echo("put the cursor on a node first") - endif -endfunction - -" FUNCTION: s:jumpToRoot() {{{2 -" moves the cursor to the root node -function! s:jumpToRoot() - call b:NERDTreeRoot.putCursorHere(1, 0) - call s:centerView() -endfunction - -" FUNCTION: s:jumpToSibling() {{{2 -" moves the cursor to the sibling of the current node in the given direction -" -" Args: -" forward: 1 if the cursor should move to the next sibling, 0 if it should -" move back to the previous sibling -function! s:jumpToSibling(forward) - let currentNode = s:TreeFileNode.GetSelected() - if !empty(currentNode) - let sibling = currentNode.findSibling(a:forward) - - if !empty(sibling) - call sibling.putCursorHere(1, 0) - call s:centerView() - endif - else - call s:echo("put the cursor on a node first") - endif -endfunction - -" FUNCTION: s:openBookmark(name) {{{2 -" put the cursor on the given bookmark and, if its a file, open it -function! s:openBookmark(name) - try - let targetNode = s:Bookmark.GetNodeForName(a:name, 0) - call targetNode.putCursorHere(0, 1) - redraw! - catch /^NERDTree.BookmarkedNodeNotFoundError/ - call s:echo("note - target node is not cached") - let bookmark = s:Bookmark.BookmarkFor(a:name) - let targetNode = s:TreeFileNode.New(bookmark.path) - endtry - if targetNode.path.isDirectory - call targetNode.openExplorer() - else - call targetNode.open() - endif -endfunction -" FUNCTION: s:openEntrySplit(vertical, forceKeepWindowOpen) {{{2 -"Opens the currently selected file from the explorer in a -"new window -" -"args: -"forceKeepWindowOpen - dont close the window even if NERDTreeQuitOnOpen is set -function! s:openEntrySplit(vertical, forceKeepWindowOpen) - let treenode = s:TreeFileNode.GetSelected() - if treenode != {} - if a:vertical - call treenode.openVSplit() - else - call treenode.openSplit() - endif - if !a:forceKeepWindowOpen - call s:closeTreeIfQuitOnOpen() - endif - else - call s:echo("select a node first") - endif -endfunction - -" FUNCTION: s:openExplorer() {{{2 -function! s:openExplorer() - let treenode = s:TreeDirNode.GetSelected() - if treenode != {} - call treenode.openExplorer() - else - call s:echo("select a node first") - endif -endfunction - -" FUNCTION: s:openInNewTab(stayCurrentTab) {{{2 -" Opens the selected node or bookmark in a new tab -" Args: -" stayCurrentTab: if 1 then vim will stay in the current tab, if 0 then vim -" will go to the tab where the new file is opened -function! s:openInNewTab(stayCurrentTab) - let target = s:TreeFileNode.GetSelected() - if target == {} - let target = s:Bookmark.GetSelected() - endif - - if target != {} - call target.openInNewTab({'stayInCurrentTab': a:stayCurrentTab}) - endif -endfunction - -" FUNCTION: s:openNodeRecursively() {{{2 -function! s:openNodeRecursively() - let treenode = s:TreeFileNode.GetSelected() - if treenode ==# {} || treenode.path.isDirectory ==# 0 - call s:echo("Select a directory node first" ) - else - call s:echo("Recursively opening node. Please wait...") - call treenode.openRecursively() - call s:renderView() - redraw - call s:echo("Recursively opening node. Please wait... DONE") - endif - -endfunction - -"FUNCTION: s:previewNode() {{{2 -"Args: -" openNewWin: if 0, use the previous window, if 1 open in new split, if 2 -" open in a vsplit -function! s:previewNode(openNewWin) - let currentBuf = bufnr("") - if a:openNewWin > 0 - call s:openEntrySplit(a:openNewWin ==# 2,1) - else - call s:activateNode(1) - end - call s:exec(bufwinnr(currentBuf) . "wincmd w") -endfunction - -" FUNCTION: s:revealBookmark(name) {{{2 -" put the cursor on the node associate with the given name -function! s:revealBookmark(name) - try - let targetNode = s:Bookmark.GetNodeForName(a:name, 0) - call targetNode.putCursorHere(0, 1) - catch /^NERDTree.BookmarkNotFoundError/ - call s:echo("Bookmark isnt cached under the current root") - endtry -endfunction -" FUNCTION: s:refreshRoot() {{{2 -" Reloads the current root. All nodes below this will be lost and the root dir -" will be reloaded. -function! s:refreshRoot() - call s:echo("Refreshing the root node. This could take a while...") - call b:NERDTreeRoot.refresh() - call s:renderView() - redraw - call s:echo("Refreshing the root node. This could take a while... DONE") -endfunction - -" FUNCTION: s:refreshCurrent() {{{2 -" refreshes the root for the current node -function! s:refreshCurrent() - let treenode = s:TreeDirNode.GetSelected() - if treenode ==# {} - call s:echo("Refresh failed. Select a node first") - return - endif - - call s:echo("Refreshing node. This could take a while...") - call treenode.refresh() - call s:renderView() - redraw - call s:echo("Refreshing node. This could take a while... DONE") -endfunction -" FUNCTION: s:showMenu() {{{2 -function! s:showMenu() - let curNode = s:TreeFileNode.GetSelected() - if curNode ==# {} - call s:echo("Put the cursor on a node first" ) - return - endif - - let mc = s:MenuController.New(s:MenuItem.AllEnabled()) - call mc.showMenu() -endfunction - -" FUNCTION: s:toggleIgnoreFilter() {{{2 -" toggles the use of the NERDTreeIgnore option -function! s:toggleIgnoreFilter() - let b:NERDTreeIgnoreEnabled = !b:NERDTreeIgnoreEnabled - call s:renderViewSavingPosition() - call s:centerView() -endfunction - -" FUNCTION: s:toggleShowBookmarks() {{{2 -" toggles the display of bookmarks -function! s:toggleShowBookmarks() - let b:NERDTreeShowBookmarks = !b:NERDTreeShowBookmarks - if b:NERDTreeShowBookmarks - call s:renderView() - call s:putCursorOnBookmarkTable() - else - call s:renderViewSavingPosition() - endif - call s:centerView() -endfunction -" FUNCTION: s:toggleShowFiles() {{{2 -" toggles the display of hidden files -function! s:toggleShowFiles() - let b:NERDTreeShowFiles = !b:NERDTreeShowFiles - call s:renderViewSavingPosition() - call s:centerView() -endfunction - -" FUNCTION: s:toggleShowHidden() {{{2 -" toggles the display of hidden files -function! s:toggleShowHidden() - let b:NERDTreeShowHidden = !b:NERDTreeShowHidden - call s:renderViewSavingPosition() - call s:centerView() -endfunction - -" FUNCTION: s:toggleZoom() {{2 -" zoom (maximize/minimize) the NERDTree window -function! s:toggleZoom() - if exists("b:NERDTreeZoomed") && b:NERDTreeZoomed - let size = exists("b:NERDTreeOldWindowSize") ? b:NERDTreeOldWindowSize : g:NERDTreeWinSize - exec "silent vertical resize ". size - let b:NERDTreeZoomed = 0 - else - exec "vertical resize" - let b:NERDTreeZoomed = 1 - endif -endfunction - -"FUNCTION: s:upDir(keepState) {{{2 -"moves the tree up a level -" -"Args: -"keepState: 1 if the current root should be left open when the tree is -"re-rendered -function! s:upDir(keepState) - let cwd = b:NERDTreeRoot.path.str({'format': 'UI'}) - if cwd ==# "/" || cwd =~# '^[^/]..$' - call s:echo("already at top dir") - else - if !a:keepState - call b:NERDTreeRoot.close() - endif - - let oldRoot = b:NERDTreeRoot - - if empty(b:NERDTreeRoot.parent) - let path = b:NERDTreeRoot.path.getParent() - let newRoot = s:TreeDirNode.New(path) - call newRoot.open() - call newRoot.transplantChild(b:NERDTreeRoot) - let b:NERDTreeRoot = newRoot - else - let b:NERDTreeRoot = b:NERDTreeRoot.parent - endif - - if g:NERDTreeChDirMode ==# 2 - call b:NERDTreeRoot.path.changeToDir() - endif - - call s:renderView() - call oldRoot.putCursorHere(0, 0) - endif -endfunction - - -"reset &cpo back to users setting -let &cpo = s:old_cpo - -" vim: set sw=4 sts=4 et fdm=marker: diff --git a/oldStyle/disabled_plugins/conque_term.vim b/oldStyle/disabled_plugins/conque_term.vim deleted file mode 100644 index 3d2e59d..0000000 --- a/oldStyle/disabled_plugins/conque_term.vim +++ /dev/null @@ -1,213 +0,0 @@ -" FILE: plugin/conque_term.vim {{{ -" AUTHOR: Nico Raffo -" WEBSITE: http://conque.googlecode.com -" MODIFIED: 2011-08-12 -" VERSION: 2.2, for Vim 7.0 -" LICENSE: -" Conque - Vim terminal/console emulator -" Copyright (C) 2009-__YEAR__ Nico Raffo -" -" MIT License -" -" Permission is hereby granted, free of charge, to any person obtaining a copy -" of this software and associated documentation files (the "Software"), to deal -" in the Software without restriction, including without limitation the rights -" to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -" copies of the Software, and to permit persons to whom the Software is -" furnished to do so, subject to the following conditions: -" -" The above copyright notice and this permission notice shall be included in -" all copies or substantial portions of the Software. -" -" THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -" IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -" FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -" AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -" LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -" OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -" THE SOFTWARE. -" }}} - -" See docs/conque_term.txt for help or type :help ConqueTerm - -if exists('g:ConqueTerm_Loaded') || v:version < 700 - finish -endif - -" ********************************************************************************************************** -" **** CONFIGURATION *************************************************************************************** -" ********************************************************************************************************** - -" {{{ - -" Fast mode {{{ -" Disables all features which could cause Conque to run slowly, including: -" * Disables terminal colors -" * Disables some multi-byte character handling -if !exists('g:ConqueTerm_FastMode') - let g:ConqueTerm_FastMode = 0 -endif " }}} - -" automatically go into insert mode when entering buffer {{{ -if !exists('g:ConqueTerm_InsertOnEnter') - let g:ConqueTerm_InsertOnEnter = 0 -endif " }}} - -" Allow user to use keys to switch window in insert mode. {{{ -if !exists('g:ConqueTerm_CWInsert') - let g:ConqueTerm_CWInsert = 0 -endif " }}} - -" Choose key mapping to leave insert mode {{{ -" If you choose something other than '', then will be sent to terminal -" Using a different key will usually fix Alt/Meta key issues -if !exists('g:ConqueTerm_EscKey') - let g:ConqueTerm_EscKey = '' -endif " }}} - -" Use this key to execute the current file in a split window. {{{ -" THIS IS A GLOBAL KEY MAPPING -if !exists('g:ConqueTerm_ExecFileKey') - let g:ConqueTerm_ExecFileKey = '' -endif " }}} - -" Use this key to send the current file contents to conque. {{{ -" THIS IS A GLOBAL KEY MAPPING -if !exists('g:ConqueTerm_SendFileKey') - let g:ConqueTerm_SendFileKey = '' -endif " }}} - -" Use this key to send selected text to conque. {{{ -" THIS IS A GLOBAL KEY MAPPING -if !exists('g:ConqueTerm_SendVisKey') - let g:ConqueTerm_SendVisKey = '' -endif " }}} - -" Use this key to toggle terminal key mappings. {{{ -" Only mapped inside of Conque buffers. -if !exists('g:ConqueTerm_ToggleKey') - let g:ConqueTerm_ToggleKey = '' -endif " }}} - -" Enable color. {{{ -" If your apps use a lot of color it will slow down the shell. -" 0 - no terminal colors. You still will see Vim syntax highlighting. -" 1 - limited terminal colors (recommended). Past terminal color history cleared regularly. -" 2 - all terminal colors. Terminal color history never cleared. -if !exists('g:ConqueTerm_Color') - let g:ConqueTerm_Color = 1 -endif " }}} - -" Color mode. Windows ONLY {{{ -" Set this variable to 'conceal' to use Vim's conceal mode for terminal colors. -" This makes colors render much faster, but has some odd baggage. -if !exists('g:ConqueTerm_ColorMode') - let g:ConqueTerm_ColorMode = '' -endif " }}} - -" TERM environment setting {{{ -if !exists('g:ConqueTerm_TERM') - let g:ConqueTerm_TERM = 'vt100' -endif " }}} - -" Syntax for your buffer {{{ -if !exists('g:ConqueTerm_Syntax') - let g:ConqueTerm_Syntax = 'conque_term' -endif " }}} - -" Keep on updating the shell window after you've switched to another buffer {{{ -if !exists('g:ConqueTerm_ReadUnfocused') - let g:ConqueTerm_ReadUnfocused = 0 -endif " }}} - -" Use this regular expression to highlight prompt {{{ -if !exists('g:ConqueTerm_PromptRegex') - let g:ConqueTerm_PromptRegex = '^\w\+@[0-9A-Za-z_.-]\+:[0-9A-Za-z_./\~,:-]\+\$' -endif " }}} - -" Choose which Python version to attempt to load first {{{ -" Valid values are 2, 3 or 0 (no preference) -if !exists('g:ConqueTerm_PyVersion') - let g:ConqueTerm_PyVersion = 2 -endif " }}} - -" Path to python.exe. (Windows only) {{{ -" By default, Conque will check C:\PythonNN\python.exe then will search system path -" If you have installed Python in an unusual location and it's not in your path, fill in the full path below -" E.g. 'C:\Program Files\Python\Python27\python.exe' -if !exists('g:ConqueTerm_PyExe') - let g:ConqueTerm_PyExe = '' -endif " }}} - -" Automatically close buffer when program exits {{{ -if !exists('g:ConqueTerm_CloseOnEnd') - let g:ConqueTerm_CloseOnEnd = 0 -endif " }}} - -" Send function key presses to terminal {{{ -if !exists('g:ConqueTerm_SendFunctionKeys') - let g:ConqueTerm_SendFunctionKeys = 0 -endif " }}} - -" Session support {{{ -if !exists('g:ConqueTerm_SessionSupport') - let g:ConqueTerm_SessionSupport = 0 -endif " }}} - -" hide Conque startup messages {{{ -" messages should only appear the first 3 times you start Vim with a new version of Conque -" and include important Conque feature and option descriptions -" TODO - disabled and unused for now -if !exists('g:ConqueTerm_StartMessages') - let g:ConqueTerm_StartMessages = 1 -endif " }}} - -" Windows character code page {{{ -" Leave at 0 to use current environment code page. -" Use 65001 for utf-8, although many console apps do not support it. -if !exists('g:ConqueTerm_CodePage') - let g:ConqueTerm_CodePage = 0 -endif " }}} - -" InsertCharPre support {{{ -" Disable this feature by default, still in Beta -if !exists('g:ConqueTerm_InsertCharPre') - let g:ConqueTerm_InsertCharPre = 0 -endif " }}} - -" }}} - -" ********************************************************************************************************** -" **** Startup ********************************************************************************************* -" ********************************************************************************************************** - -" Startup {{{ - -let g:ConqueTerm_Loaded = 1 -let g:ConqueTerm_Idx = 0 -let g:ConqueTerm_Version = 210 - -command! -nargs=+ -complete=shellcmd ConqueTerm call conque_term#open() -command! -nargs=+ -complete=shellcmd ConqueTermSplit call conque_term#open(, ['belowright split']) -command! -nargs=+ -complete=shellcmd ConqueTermVSplit call conque_term#open(, ['belowright vsplit']) -command! -nargs=+ -complete=shellcmd ConqueTermTab call conque_term#open(, ['tabnew']) - -" }}} - -" ********************************************************************************************************** -" **** Global Mappings & Autocommands ********************************************************************** -" ********************************************************************************************************** - -" Startup {{{ - -if exists('g:ConqueTerm_SessionSupport') && g:ConqueTerm_SessionSupport == 1 - autocmd SessionLoadPost * call conque_term#resume_session() -endif - -if maparg(g:ConqueTerm_ExecFileKey, 'n') == '' - exe 'nnoremap ' . g:ConqueTerm_ExecFileKey . ' :call conque_term#exec_file()' -endif - -" }}} - -" vim:foldmethod=marker diff --git a/oldStyle/disabled_plugins/jsbeautify.vim b/oldStyle/disabled_plugins/jsbeautify.vim deleted file mode 100644 index b75bbf1..0000000 --- a/oldStyle/disabled_plugins/jsbeautify.vim +++ /dev/null @@ -1,629 +0,0 @@ -if &cp || exists("loaded_jsbeautify") - finish -endif -let loaded_jsbeautify = 3 - - - -function! s:trim_output() - while len(s:output) > 0 && (s:output[len(s:output)-1] == " " || s:output[len(s:output)-1] == s:indent_string) - call remove(s:output, -1) - endwhile -endfunction - -function! s:print_newline(ignore_repeated) - let s:if_line_flag = 0 - call s:trim_output() - if len(s:output)==0 - return - endif - if s:output[len(s:output)-1] != "\n" || !a:ignore_repeated - call add(s:output, "\n") - endif - let index = 0 - while index < s:indent_level - call add(s:output, s:indent_string) - let index += 1 - endwhile -endfunction - -function! s:print_space() - let last_output = " " - if len(s:output) > 0 - let last_output = s:output[len(s:output) - 1] - endif - if last_output != " " && last_output != "\n" && last_output != s:indent_string - call add(s:output, " ") - endif -endfunction - -function! s:print_token() - call add(s:output, s:token_text) -endfunctio - -function! s:indent() - let s:indent_level += 1 -endfunction - -function! s:unindent() - if s:indent_level - let s:indent_level -= 1 - endif -endfunction - -function! s:remove_indent() - if len(s:output)>0 && s:output[len(s:output) -1] == s:indent_string - call remove(s:output, -1) - endif -endfunction - -function! s:set_mode(mode) - call add(s:modes, s:current_mode) - let s:current_mode = a:mode -endfunction - -function! s:restore_mode() - if s:current_mode == "DO_BLOCK" - let s:do_block_just_closed = 1 - else - let s:do_block_just_closed = 0 - endif - let s:current_mode = remove(s:modes, -1) -endfunction - -function! s:in_array(what, arr) - return index(a:arr, a:what) != -1 -endfunction - -function! s:get_next_token() - let n_newlines = 0 - - if s:parser_pos >= len(s:input) - return ["", "TK_EOF"] - endif - - let c = s:input[s:parser_pos] - let s:parser_pos += 1 - - while s:in_array(c, s:whitespace) - if s:parser_pos >= len(s:input) - return ["", "TK_EOF"] - endif - - if c == "\n" - let n_newlines += 1 - endif - - let c = s:input[s:parser_pos] - let s:parser_pos += 1 - endwhile - - let wanted_newline = 0 - - if s:opt_preserve_newlines - if n_newlines > 1 - for i in [0, 1] - call s:print_newline(i==0) - endfor - endif - let wanted_newline = n_newlines == 1 - endif - - if s:in_array(c, s:wordchar) - if s:parser_pos < len(s:input) - while s:in_array(s:input[s:parser_pos], s:wordchar) - let c .= s:input[s:parser_pos] - let s:parser_pos += 1 - if s:parser_pos == len(s:input) - break - endif - endwhile - endif - - "if s:parser_pos != len(s:input) && c =~ /^[0-9]+[Ee]$/ && (s:input[s:parser_pos] == "-" || s:input[s:parser_pos] == "+") - "let sign = s:input[s:parser_pos] - "let s:parser_pos += 1 - - "let t = get_next_token(s:parser_pos) - "let c .= sign . t[0] - "return [c, "TK_WORD"] - " endif - - if c == "in" - return [c, "TK_OPERATOR"] - endif - if wanted_newline && s:last_type != "TK_OPERATOR" && !s:if_line_flag - call s:print_newline(1) - endif - return [c, "TK_WORD"] - endif - if c == "(" || c == "[" - return [c, "TK_START_EXPR"] - endif - - if c == ")" || c == "]" - return [c, "TK_END_EXPR"] - endif - - if c == "{" - return [c, "TK_START_BLOCK"] - endif - - if c == "}" - return [c, "TK_END_BLOCK"] - endif - - if c == ";" - return [c, "TK_SEMICOLON"] - endif - - if c == "/" - let comment = "" - if s:input[s:parser_pos] == "*" - let s:parser_pos += 1 - if s:parser_pos < len(s:input) - while !(s:input[s:parser_pos] == "*" && s:parser_pos + 1 < len(s:input) && s:input[s:parser_pos + 1] == "/" && s:parser_pos < len(s:input)) - let comment .= s:input[s:parser_pos] - let s:parser_pos += 1 - if s:parser_pos >= len(s:input) - break - endif - endwhile - endif - let s:parser_pos += 2 - return ['/*' . comment . '*/', 'TK_BLOCK_COMMENT'] - endif - - " peek for comment // ... - if s:input[s:parser_pos] == "/" - let comment = c - while s:input[s:parser_pos] != "\r" && s:input[s:parser_pos] != "\n" - let comment .= s:input[s:parser_pos] - let s:parser_pos += 1 - if s:parser_pos >= len(s:input) - break - endif - endwhile - let s:parser_pos += 1 - if wanted_newline - call s:print_newline(1) - endif - return [comment, "TK_COMMENT"] - endif - endif - - if c == "'" || c =='"' || (c == "/" && ((s:last_type == "TK_WORD" && s:last_text == "return") || (s:last_type == "TK_START_EXPR" || s:last_type == "TK_START_BLOCK" || s:last_type == "TK_END_BLOCK" || s:last_type == "TK_OPERATOR" || s:last_type == "TK_EOF" || s:last_type == "TK_SEMICOLON"))) - let sep = c - let esc = 0 - let resulting_string = c - - if s:parser_pos < len(s:input) - while esc || s:input[s:parser_pos] != sep - let resulting_string .= s:input[s:parser_pos] - if !esc - let esc = s:input[s:parser_pos] == "\\" - else - let esc = 0 - endif - let s:parser_pos += 1 - if s:parser_pos >= len(s:input) - return [resulting_string, "TK_STRING"] - endif - endwhile - endif - - let s:parser_pos += 1 - - let resulting_string .= sep - - if sep == "/" - - while s:parser_pos < len(s:input) && s:in_array(s:input[s:parser_pos], s:wordchar) - let resulting_string .= s:input[s:parser_pos] - let s:parser_pos += 1 - endwhile - endif - return [resulting_string, "TK_STRING"] - endif - - if c == "#" - let sharp = "#" - if s:parser_pos < len(s:input) && s:in_array(s:input[s:parser_pos], s:digits) - let c = s:input[s:parser_pos] - let sharp .= c - let s:parser_pos += 1 - - while s:parser_pos < len(s:input) && c != "#" && c !="=" - let c = s:input[s:parser_pos] - let sharp .= c - let s:parser_pos += 1 - endwhile - - if c == "#" - return [sharp, "TK_WORD"] - else - return [sharp, "TK_OPERATOR"] - endif - endif - endif - - if c == "<" && s:input[s:parser_pos-1 : s:parser_pos+3] == "" - let s:parser_pos += 2 - if wanted_newline - call s:print_newline(1) - endif - return ["-->", "TK_COMMENT"] - endif - - if s:in_array(c, s:punct) - while s:parser_pos < len(s:input) && s:in_array(c . s:input[s:parser_pos], s:punct) - let c .= s:input[s:parser_pos] - let s:parser_pos += 1 - if s:parser_pos >= len(s:input) - break - endif - endwhile - - return [c, "TK_OPERATOR"] - endif - - return [c, "TK_UNKNOWN"] - endif - - - -endfunction - -function! s:is_js() - return expand("%:e") == "js" -endfunction - -"function! g:Jsbeautify(js_source_text, options) -function! g:Jsbeautify() - if !s:is_js() - echo "Not a JS file." - return - endif - - "let a:options = {} - let s:opt_indent_size = 1 - let s:opt_indent_char = " " - let s:opt_preserve_newlines = 1 - let s:opt_indent_level = 0 - - let s:if_line_flag = 0 - "-------------------------------- - - let s:indent_string = "" - while s:opt_indent_size > 0 - let s:indent_string .= s:opt_indent_char - let s:opt_indent_size -= 1 - endwhile - - let s:indent_level = s:opt_indent_level - - let lines = getline(1, "$") - let s:input = join(lines, "\n") - "let s:input = a:js_source_text - - let s:last_word = "" "last 'TK_WORD' passed - let s:last_type = "TK_START_EXPR" "last token type - let s:last_text = "" "last token text - let s:output = [] - - let s:do_block_just_closed = 0 - let s:var_line = 0 - let s:var_line_tainted = 0 - - let s:whitespace = ["\n", "\r", "\t", " "] - let s:wordchar = split("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_$", '\zs') - let s:digits = split("0123456789", '\zs') - - "