diff options
Diffstat (limited to 'runtime/autoload')
-rw-r--r-- | runtime/autoload/adacomplete.vim | 109 | ||||
-rw-r--r-- | runtime/autoload/csscomplete.vim | 740 | ||||
-rw-r--r-- | runtime/autoload/decada.vim | 75 | ||||
-rw-r--r-- | runtime/autoload/getscript.vim | 501 | ||||
-rw-r--r-- | runtime/autoload/netrw.vim | 4597 | ||||
-rw-r--r-- | runtime/autoload/pythoncomplete.vim | 94 | ||||
-rw-r--r-- | runtime/autoload/rubycomplete.vim | 896 | ||||
-rw-r--r-- | runtime/autoload/syntaxcomplete.vim | 117 | ||||
-rw-r--r-- | runtime/autoload/xmlcomplete.vim | 24 | ||||
-rw-r--r-- | runtime/autoload/zip.vim | 138 |
10 files changed, 4709 insertions, 2582 deletions
diff --git a/runtime/autoload/adacomplete.vim b/runtime/autoload/adacomplete.vim new file mode 100644 index 000000000..28d68f63d --- /dev/null +++ b/runtime/autoload/adacomplete.vim @@ -0,0 +1,109 @@ +"------------------------------------------------------------------------------ +" Description: Vim Ada omnicompletion file +" Language: Ada (2005) +" $Id$ +" Maintainer: Martin Krischik +" $Author$ +" $Date$ +" Version: 4.2 +" $Revision$ +" $HeadURL: https://svn.sourceforge.net/svnroot/gnuada/trunk/tools/vim/autoload/adacomplete.vim $ +" History: 24.05.2006 MK Unified Headers +" 26.05.2006 MK improved search for begin of word. +" 16.07.2006 MK Ada-Mode as vim-ball +" 15.10.2006 MK Bram's suggestion for runtime integration +" 05.11.2006 MK Bram suggested not to use include protection for +" autoload +" 05.11.2006 MK Bram suggested agaist using setlocal omnifunc +" 05.11.2006 MK Bram suggested to save on spaces +" Help Page: ft-ada-omni +"------------------------------------------------------------------------------ + +if version < 700 + finish +endif + +" Section: adacomplete#Complete () {{{1 +" +" This function is used for the 'omnifunc' option. +" +function! adacomplete#Complete (findstart, base) + if a:findstart == 1 + return ada#User_Complete (a:findstart, a:base) + else + " + " look up matches + " + if exists ("g:ada_omni_with_keywords") + call ada#User_Complete (a:findstart, a:base) + endif + " + " search tag file for matches + " + let l:Pattern = '^' . a:base . '.*$' + let l:Tag_List = taglist (l:Pattern) + " + " add symbols + " + for Tag_Item in l:Tag_List + if l:Tag_Item['kind'] == '' + " + " Tag created by gnat xref + " + let l:Match_Item = { + \ 'word': l:Tag_Item['name'], + \ 'menu': l:Tag_Item['filename'], + \ 'info': "Symbol from file " . l:Tag_Item['filename'] . " line " . l:Tag_Item['cmd'], + \ 'kind': 's', + \ 'icase': 1} + else + " + " Tag created by ctags + " + let l:Info = 'Symbol : ' . l:Tag_Item['name'] . "\n" + let l:Info .= 'Of type : ' . g:ada#Ctags_Kinds[l:Tag_Item['kind']][1] . "\n" + let l:Info .= 'Defined in File : ' . l:Tag_Item['filename'] . "\n" + + if has_key( l:Tag_Item, 'package') + let l:Info .= 'Package : ' . l:Tag_Item['package'] . "\n" + let l:Menu = l:Tag_Item['package'] + elseif has_key( l:Tag_Item, 'separate') + let l:Info .= 'Separate from Package : ' . l:Tag_Item['separate'] . "\n" + let l:Menu = l:Tag_Item['separate'] + elseif has_key( l:Tag_Item, 'packspec') + let l:Info .= 'Package Specification : ' . l:Tag_Item['packspec'] . "\n" + let l:Menu = l:Tag_Item['packspec'] + elseif has_key( l:Tag_Item, 'type') + let l:Info .= 'Datetype : ' . l:Tag_Item['type'] . "\n" + let l:Menu = l:Tag_Item['type'] + else + let l:Menu = l:Tag_Item['filename'] + endif + + let l:Match_Item = { + \ 'word': l:Tag_Item['name'], + \ 'menu': l:Menu, + \ 'info': l:Info, + \ 'kind': l:Tag_Item['kind'], + \ 'icase': 1} + endif + if complete_add (l:Match_Item) == 0 + return [] + endif + if complete_check () + return [] + endif + endfor + return [] + endif +endfunction adacomplete#Complete + +finish " 1}}} + +"------------------------------------------------------------------------------ +" Copyright (C) 2006 Martin Krischik +" +" Vim is Charityware - see ":help license" or uganda.txt for licence details. +"------------------------------------------------------------------------------ +" vim: textwidth=78 wrap tabstop=8 shiftwidth=3 softtabstop=3 noexpandtab +" vim: foldmethod=marker diff --git a/runtime/autoload/csscomplete.vim b/runtime/autoload/csscomplete.vim index a6f7041ff..c9a5997c1 100644 --- a/runtime/autoload/csscomplete.vim +++ b/runtime/autoload/csscomplete.vim @@ -1,422 +1,407 @@ " Vim completion script " Language: CSS 2.1 " Maintainer: Mikolaj Machowski ( mikmach AT wp DOT pl ) -" Last Change: 2006 Apr 30 +" Last Change: 2007 Mar 11 function! csscomplete#CompleteCSS(findstart, base) + if a:findstart " We need whole line to proper checking - let line = getline('.') - let start = col('.') - 1 + let line = getline('.') + let start = col('.') - 1 let compl_begin = col('.') - 2 - while start >= 0 && line[start - 1] =~ '\(\k\|-\)' + while start >= 0 && line[start - 1] =~ '\%(\k\|-\)' let start -= 1 endwhile let b:compl_context = getline('.')[0:compl_begin] return start +endif + +" There are few chars important for context: +" ^ ; : { } /* */ +" Where ^ is start of line and /* */ are comment borders +" Depending on their relative position to cursor we will know what should +" be completed. +" 1. if nearest are ^ or { or ; current word is property +" 2. if : it is value (with exception of pseudo things) +" 3. if } we are outside of css definitions +" 4. for comments ignoring is be the easiest but assume they are the same +" as 1. +" 5. if @ complete at-rule +" 6. if ! complete important +if exists("b:compl_context") + let line = b:compl_context + unlet! b:compl_context else - " There are few chars important for context: - " ^ ; : { } /* */ - " Where ^ is start of line and /* */ are comment borders - " Depending on their relative position to cursor we will now what should - " be completed. - " 1. if nearest are ^ or { or ; current word is property - " 2. if : it is value (with exception of pseudo things) - " 3. if } we are outside of css definitions - " 4. for comments ignoring is be the easiest but assume they are the same - " as 1. - " 5. if @ complete at-rule - " 6. if ! complete important - if exists("b:compl_context") - let line = b:compl_context - unlet! b:compl_context - else - let line = a:base - endif - - let res = [] - let res2 = [] - let borders = {} - - " We need the last occurrence of char so reverse line - let revline = join(reverse(split(line, '.\zs')), '') - - let openbrace = stridx(revline, '{') - let closebrace = stridx(revline, '}') - let colon = stridx(revline, ':') - let semicolon = stridx(revline, ';') - let opencomm = stridx(revline, '*/') " Line was reversed - let closecomm = stridx(revline, '/*') " Line was reversed - let style = stridx(revline, '=\s*elyts') " Line was reversed - let atrule = stridx(revline, '@') - let exclam = stridx(revline, '!') - - if openbrace > -1 - let borders[openbrace] = "openbrace" - endif - if closebrace > -1 - let borders[closebrace] = "closebrace" - endif - if colon > -1 - let borders[colon] = "colon" - endif - if semicolon > -1 - let borders[semicolon] = "semicolon" - endif - if opencomm > -1 - let borders[opencomm] = "opencomm" - endif - if closecomm > -1 - let borders[closecomm] = "closecomm" - endif - if style > -1 - let borders[style] = "style" - endif - if atrule > -1 - let borders[atrule] = "atrule" - endif - if exclam > -1 - let borders[exclam] = "exclam" - endif - - - if len(borders) == 0 || borders[min(keys(borders))] =~ '^\(openbrace\|semicolon\|opencomm\|closecomm\|style\)$' - " Complete properties - - let values = split("azimuth background background-attachment background-color background-image background-position background-repeat border bottom border-collapse border-color border-spacing border-style border-top border-right border-bottom border-left border-top-color border-right-color border-bottom-color border-left-color border-top-style border-right-style border-bottom-style border-left-style border-top-width border-right-width border-bottom-width border-left-width border-width caption-side clear clip color content counter-increment counter-reset cue cue-after cue-before cursor display direction elevation empty-cells float font font-family font-size font-style font-variant font-weight height left letter-spacing line-height list-style list-style-image list-style-position list-style-type margin margin-right margin-left margin-top margin-bottom max-height max-width min-height min-width orphans outline outline-color outline-style outline-width overflow padding padding-top padding-right padding-bottom padding-left page-break-after page-break-before page-break-inside pause pause-after pause-before pitch pitch-range play-during position quotes right richness speak speak-header speak-numeral speak-punctuation speech-rate stress table-layout text-align text-decoration text-indent text-transform top unicode-bidi vertical-align visibility voice-family volume white-space width widows word-spacing z-index") - - let entered_property = matchstr(line, '.\{-}\zs[a-zA-Z-]*$') - - for m in values - if m =~? '^'.entered_property - call add(res, m . ':') - elseif m =~? entered_property - call add(res2, m . ':') - endif - endfor - - return res + res2 - - elseif borders[min(keys(borders))] == 'colon' - " Get name of property - let prop = tolower(matchstr(line, '\zs[a-zA-Z-]*\ze\s*:[^:]\{-}$')) - - if prop == 'azimuth' - let values = ["left-side", "far-left", "left", "center-left", "center", "center-right", "right", "far-right", "right-side", "behind", "leftwards", "rightwards"] - elseif prop == 'background-attachment' - let values = ["scroll", "fixed"] - elseif prop == 'background-color' - let values = ["transparent", "rgb(", "#"] - elseif prop == 'background-image' - let values = ["url(", "none"] - elseif prop == 'background-position' - let vals = matchstr(line, '.*:\s*\zs.*') - if vals =~ '^\([a-zA-Z]\+\)\?$' - let values = ["top", "center", "bottom"] - elseif vals =~ '^[a-zA-Z]\+\s\+\([a-zA-Z]\+\)\?$' - let values = ["left", "center", "right"] - else - return [] - endif - elseif prop == 'background-repeat' - let values = ["repeat", "repeat-x", "repeat-y", "no-repeat"] - elseif prop == 'background' - let values = ["url(", "scroll", "fixed", "transparent", "rgb(", "#", "none", "top", "center", "bottom" , "left", "right", "repeat", "repeat-x", "repeat-y", "no-repeat"] - elseif prop == 'border-collapse' - let values = ["collapse", "separate"] - elseif prop == 'border-color' - let values = ["rgb(", "#", "transparent"] - elseif prop == 'border-spacing' + let line = a:base +endif + +let res = [] +let res2 = [] +let borders = {} + +" Check last occurrence of sequence + +let openbrace = strridx(line, '{') +let closebrace = strridx(line, '}') +let colon = strridx(line, ':') +let semicolon = strridx(line, ';') +let opencomm = strridx(line, '/*') +let closecomm = strridx(line, '*/') +let style = strridx(line, 'style\s*=') +let atrule = strridx(line, '@') +let exclam = strridx(line, '!') + +if openbrace > -1 + let borders[openbrace] = "openbrace" +endif +if closebrace > -1 + let borders[closebrace] = "closebrace" +endif +if colon > -1 + let borders[colon] = "colon" +endif +if semicolon > -1 + let borders[semicolon] = "semicolon" +endif +if opencomm > -1 + let borders[opencomm] = "opencomm" +endif +if closecomm > -1 + let borders[closecomm] = "closecomm" +endif +if style > -1 + let borders[style] = "style" +endif +if atrule > -1 + let borders[atrule] = "atrule" +endif +if exclam > -1 + let borders[exclam] = "exclam" +endif + + +if len(borders) == 0 || borders[max(keys(borders))] =~ '^\%(openbrace\|semicolon\|opencomm\|closecomm\|style\)$' + " Complete properties + + let values = split("azimuth background background-attachment background-color background-image background-position background-repeat border bottom border-collapse border-color border-spacing border-style border-top border-right border-bottom border-left border-top-color border-right-color border-bottom-color border-left-color border-top-style border-right-style border-bottom-style border-left-style border-top-width border-right-width border-bottom-width border-left-width border-width caption-side clear clip color content counter-increment counter-reset cue cue-after cue-before cursor display direction elevation empty-cells float font font-family font-size font-style font-variant font-weight height left letter-spacing line-height list-style list-style-image list-style-position list-style-type margin margin-right margin-left margin-top margin-bottom max-height max-width min-height min-width orphans outline outline-color outline-style outline-width overflow padding padding-top padding-right padding-bottom padding-left page-break-after page-break-before page-break-inside pause pause-after pause-before pitch pitch-range play-during position quotes right richness speak speak-header speak-numeral speak-punctuation speech-rate stress table-layout text-align text-decoration text-indent text-transform top unicode-bidi vertical-align visibility voice-family volume white-space width widows word-spacing z-index") + + let entered_property = matchstr(line, '.\{-}\zs[a-zA-Z-]*$') + + for m in values + if m =~? '^'.entered_property + call add(res, m . ':') + elseif m =~? entered_property + call add(res2, m . ':') + endif + endfor + + return res + res2 + +elseif borders[max(keys(borders))] == 'colon' + " Get name of property + let prop = tolower(matchstr(line, '\zs[a-zA-Z-]*\ze\s*:[^:]\{-}$')) + + if prop == 'azimuth' + let values = ["left-side", "far-left", "left", "center-left", "center", "center-right", "right", "far-right", "right-side", "behind", "leftwards", "rightwards"] + elseif prop == 'background-attachment' + let values = ["scroll", "fixed"] + elseif prop == 'background-color' + let values = ["transparent", "rgb(", "#"] + elseif prop == 'background-image' + let values = ["url(", "none"] + elseif prop == 'background-position' + let vals = matchstr(line, '.*:\s*\zs.*') + if vals =~ '^\%([a-zA-Z]\+\)\?$' + let values = ["top", "center", "bottom"] + elseif vals =~ '^[a-zA-Z]\+\s\+\%([a-zA-Z]\+\)\?$' + let values = ["left", "center", "right"] + else return [] - elseif prop == 'border-style' + endif + elseif prop == 'background-repeat' + let values = ["repeat", "repeat-x", "repeat-y", "no-repeat"] + elseif prop == 'background' + let values = ["url(", "scroll", "fixed", "transparent", "rgb(", "#", "none", "top", "center", "bottom" , "left", "right", "repeat", "repeat-x", "repeat-y", "no-repeat"] + elseif prop == 'border-collapse' + let values = ["collapse", "separate"] + elseif prop == 'border-color' + let values = ["rgb(", "#", "transparent"] + elseif prop == 'border-spacing' + return [] + elseif prop == 'border-style' + let values = ["none", "hidden", "dotted", "dashed", "solid", "double", "groove", "ridge", "inset", "outset"] + elseif prop =~ 'border-\%(top\|right\|bottom\|left\)$' + let vals = matchstr(line, '.*:\s*\zs.*') + if vals =~ '^\%([a-zA-Z0-9.]\+\)\?$' + let values = ["thin", "thick", "medium"] + elseif vals =~ '^[a-zA-Z0-9.]\+\s\+\%([a-zA-Z]\+\)\?$' let values = ["none", "hidden", "dotted", "dashed", "solid", "double", "groove", "ridge", "inset", "outset"] - elseif prop =~ 'border-\(top\|right\|bottom\|left\)$' - let vals = matchstr(line, '.*:\s*\zs.*') - if vals =~ '^\([a-zA-Z0-9.]\+\)\?$' - let values = ["thin", "thick", "medium"] - elseif vals =~ '^[a-zA-Z0-9.]\+\s\+\([a-zA-Z]\+\)\?$' - let values = ["none", "hidden", "dotted", "dashed", "solid", "double", "groove", "ridge", "inset", "outset"] - elseif vals =~ '^[a-zA-Z0-9.]\+\s\+[a-zA-Z]\+\s\+\([a-zA-Z(]\+\)\?$' - let values = ["rgb(", "#", "transparent"] - else - return [] - endif - elseif prop =~ 'border-\(top\|right\|bottom\|left\)-color' + elseif vals =~ '^[a-zA-Z0-9.]\+\s\+[a-zA-Z]\+\s\+\%([a-zA-Z(]\+\)\?$' let values = ["rgb(", "#", "transparent"] - elseif prop =~ 'border-\(top\|right\|bottom\|left\)-style' - let values = ["none", "hidden", "dotted", "dashed", "solid", "double", "groove", "ridge", "inset", "outset"] - elseif prop =~ 'border-\(top\|right\|bottom\|left\)-width' - let values = ["thin", "thick", "medium"] - elseif prop == 'border-width' - let values = ["thin", "thick", "medium"] - elseif prop == 'border' - let vals = matchstr(line, '.*:\s*\zs.*') - if vals =~ '^\([a-zA-Z0-9.]\+\)\?$' - let values = ["thin", "thick", "medium"] - elseif vals =~ '^[a-zA-Z0-9.]\+\s\+\([a-zA-Z]\+\)\?$' - let values = ["none", "hidden", "dotted", "dashed", "solid", "double", "groove", "ridge", "inset", "outset"] - elseif vals =~ '^[a-zA-Z0-9.]\+\s\+[a-zA-Z]\+\s\+\([a-zA-Z(]\+\)\?$' - let values = ["rgb(", "#", "transparent"] - else - return [] - endif - elseif prop == 'bottom' - let values = ["auto"] - elseif prop == 'caption-side' - let values = ["top", "bottom"] - elseif prop == 'clear' - let values = ["none", "left", "right", "both"] - elseif prop == 'clip' - let values = ["auto", "rect("] - elseif prop == 'color' - let values = ["rgb(", "#"] - elseif prop == 'content' - let values = ["normal", "attr(", "open-quote", "close-quote", "no-open-quote", "no-close-quote"] - elseif prop =~ 'counter-\(increment\|reset\)$' - let values = ["none"] - elseif prop =~ '^\(cue-after\|cue-before\|cue\)$' - let values = ["url(", "none"] - elseif prop == 'cursor' - let values = ["url(", "auto", "crosshair", "default", "pointer", "move", "e-resize", "ne-resize", "nw-resize", "n-resize", "se-resize", "sw-resize", "s-resize", "w-resize", "text", "wait", "help", "progress"] - elseif prop == 'direction' - let values = ["ltr", "rtl"] - elseif prop == 'display' - let values = ["inline", "block", "list-item", "run-in", "inline-block", "table", "inline-table", "table-row-group", "table-header-group", "table-footer-group", "table-row", "table-column-group", "table-column", "table-cell", "table-caption", "none"] - elseif prop == 'elevation' - let values = ["below", "level", "above", "higher", "lower"] - elseif prop == 'empty-cells' - let values = ["show", "hide"] - elseif prop == 'float' - let values = ["left", "right", "none"] - elseif prop == 'font-family' - let values = ["sans-serif", "serif", "monospace", "cursive", "fantasy"] - elseif prop == 'font-size' - let values = ["xx-small", "x-small", "small", "medium", "large", "x-large", "xx-large", "larger", "smaller"] - elseif prop == 'font-style' - let values = ["normal", "italic", "oblique"] - elseif prop == 'font-variant' - let values = ["normal", "small-caps"] - elseif prop == 'font-weight' - let values = ["normal", "bold", "bolder", "lighter", "100", "200", "300", "400", "500", "600", "700", "800", "900"] - elseif prop == 'font' - let values = ["normal", "italic", "oblique", "small-caps", "bold", "bolder", "lighter", "100", "200", "300", "400", "500", "600", "700", "800", "900", "xx-small", "x-small", "small", "medium", "large", "x-large", "xx-large", "larger", "smaller", "sans-serif", "serif", "monospace", "cursive", "fantasy", "caption", "icon", "menu", "message-box", "small-caption", "status-bar"] - elseif prop =~ '^\(height\|width\)$' - let values = ["auto"] - elseif prop =~ '^\(left\|rigth\)$' - let values = ["auto"] - elseif prop == 'letter-spacing' - let values = ["normal"] - elseif prop == 'line-height' - let values = ["normal"] - elseif prop == 'list-style-image' - let values = ["url(", "none"] - elseif prop == 'list-style-position' - let values = ["inside", "outside"] - elseif prop == 'list-style-type' - let values = ["disc", "circle", "square", "decimal", "decimal-leading-zero", "lower-roman", "upper-roman", "lower-latin", "upper-latin", "none"] - elseif prop == 'list-style' + else return [] - elseif prop == 'margin' - let values = ["auto"] - elseif prop =~ 'margin-\(right\|left\|top\|bottom\)$' - let values = ["auto"] - elseif prop == 'max-height' - let values = ["auto"] - elseif prop == 'max-width' - let values = ["none"] - elseif prop == 'min-height' - let values = ["none"] - elseif prop == 'min-width' - let values = ["none"] - elseif prop == 'orphans' + endif + elseif prop =~ 'border-\%(top\|right\|bottom\|left\)-color' + let values = ["rgb(", "#", "transparent"] + elseif prop =~ 'border-\%(top\|right\|bottom\|left\)-style' + let values = ["none", "hidden", "dotted", "dashed", "solid", "double", "groove", "ridge", "inset", "outset"] + elseif prop =~ 'border-\%(top\|right\|bottom\|left\)-width' + let values = ["thin", "thick", "medium"] + elseif prop == 'border-width' + let values = ["thin", "thick", "medium"] + elseif prop == 'border' + let vals = matchstr(line, '.*:\s*\zs.*') + if vals =~ '^\%([a-zA-Z0-9.]\+\)\?$' + let values = ["thin", "thick", "medium"] + elseif vals =~ '^[a-zA-Z0-9.]\+\s\+\%([a-zA-Z]\+\)\?$' + let values = ["none", "hidden", "dotted", "dashed", "solid", "double", "groove", "ridge", "inset", "outset"] + elseif vals =~ '^[a-zA-Z0-9.]\+\s\+[a-zA-Z]\+\s\+\%([a-zA-Z(]\+\)\?$' + let values = ["rgb(", "#", "transparent"] + else return [] - elseif prop == 'outline-color' + endif + elseif prop == 'bottom' + let values = ["auto"] + elseif prop == 'caption-side' + let values = ["top", "bottom"] + elseif prop == 'clear' + let values = ["none", "left", "right", "both"] + elseif prop == 'clip' + let values = ["auto", "rect("] + elseif prop == 'color' + let values = ["rgb(", "#"] + elseif prop == 'content' + let values = ["normal", "attr(", "open-quote", "close-quote", "no-open-quote", "no-close-quote"] + elseif prop =~ 'counter-\%(increment\|reset\)$' + let values = ["none"] + elseif prop =~ '^\%(cue-after\|cue-before\|cue\)$' + let values = ["url(", "none"] + elseif prop == 'cursor' + let values = ["url(", "auto", "crosshair", "default", "pointer", "move", "e-resize", "ne-resize", "nw-resize", "n-resize", "se-resize", "sw-resize", "s-resize", "w-resize", "text", "wait", "help", "progress"] + elseif prop == 'direction' + let values = ["ltr", "rtl"] + elseif prop == 'display' + let values = ["inline", "block", "list-item", "run-in", "inline-block", "table", "inline-table", "table-row-group", "table-header-group", "table-footer-group", "table-row", "table-column-group", "table-column", "table-cell", "table-caption", "none"] + elseif prop == 'elevation' + let values = ["below", "level", "above", "higher", "lower"] + elseif prop == 'empty-cells' + let values = ["show", "hide"] + elseif prop == 'float' + let values = ["left", "right", "none"] + elseif prop == 'font-family' + let values = ["sans-serif", "serif", "monospace", "cursive", "fantasy"] + elseif prop == 'font-size' + let values = ["xx-small", "x-small", "small", "medium", "large", "x-large", "xx-large", "larger", "smaller"] + elseif prop == 'font-style' + let values = ["normal", "italic", "oblique"] + elseif prop == 'font-variant' + let values = ["normal", "small-caps"] + elseif prop == 'font-weight' + let values = ["normal", "bold", "bolder", "lighter", "100", "200", "300", "400", "500", "600", "700", "800", "900"] + elseif prop == 'font' + let values = ["normal", "italic", "oblique", "small-caps", "bold", "bolder", "lighter", "100", "200", "300", "400", "500", "600", "700", "800", "900", "xx-small", "x-small", "small", "medium", "large", "x-large", "xx-large", "larger", "smaller", "sans-serif", "serif", "monospace", "cursive", "fantasy", "caption", "icon", "menu", "message-box", "small-caption", "status-bar"] + elseif prop =~ '^\%(height\|width\)$' + let values = ["auto"] + elseif prop =~ '^\%(left\|rigth\)$' + let values = ["auto"] + elseif prop == 'letter-spacing' + let values = ["normal"] + elseif prop == 'line-height' + let values = ["normal"] + elseif prop == 'list-style-image' + let values = ["url(", "none"] + elseif prop == 'list-style-position' + let values = ["inside", "outside"] + elseif prop == 'list-style-type' + let values = ["disc", "circle", "square", "decimal", "decimal-leading-zero", "lower-roman", "upper-roman", "lower-latin", "upper-latin", "none"] + elseif prop == 'list-style' + return [] + elseif prop == 'margin' + let values = ["auto"] + elseif prop =~ 'margin-\%(right\|left\|top\|bottom\)$' + let values = ["auto"] + elseif prop == 'max-height' + let values = ["auto"] + elseif prop == 'max-width' + let values = ["none"] + elseif prop == 'min-height' + let values = ["none"] + elseif prop == 'min-width' + let values = ["none"] + elseif prop == 'orphans' + return [] + elseif prop == 'outline-color' + let values = ["rgb(", "#"] + elseif prop == 'outline-style' + let values = ["none", "hidden", "dotted", "dashed", "solid", "double", "groove", "ridge", "inset", "outset"] + elseif prop == 'outline-width' + let values = ["thin", "thick", "medium"] + elseif prop == 'outline' + let vals = matchstr(line, '.*:\s*\zs.*') + if vals =~ '^\%([a-zA-Z0-9,()#]\+\)\?$' let values = ["rgb(", "#"] - elseif prop == 'outline-style' + elseif vals =~ '^[a-zA-Z0-9,()#]\+\s\+\%([a-zA-Z]\+\)\?$' let values = ["none", "hidden", "dotted", "dashed", "solid", "double", "groove", "ridge", "inset", "outset"] - elseif prop == 'outline-width' + elseif vals =~ '^[a-zA-Z0-9,()#]\+\s\+[a-zA-Z]\+\s\+\%([a-zA-Z(]\+\)\?$' let values = ["thin", "thick", "medium"] - elseif prop == 'outline' - let vals = matchstr(line, '.*:\s*\zs.*') - if vals =~ '^\([a-zA-Z0-9,()#]\+\)\?$' - let values = ["rgb(", "#"] - elseif vals =~ '^[a-zA-Z0-9,()#]\+\s\+\([a-zA-Z]\+\)\?$' - let values = ["none", "hidden", "dotted", "dashed", "solid", "double", "groove", "ridge", "inset", "outset"] - elseif vals =~ '^[a-zA-Z0-9,()#]\+\s\+[a-zA-Z]\+\s\+\([a-zA-Z(]\+\)\?$' - let values = ["thin", "thick", "medium"] - else - return [] - endif - elseif prop == 'overflow' - let values = ["visible", "hidden", "scroll", "auto"] - elseif prop == 'padding' - return [] - elseif prop =~ 'padding-\(top\|right\|bottom\|left\)$' - return [] - elseif prop =~ 'page-break-\(after\|before\)$' - let values = ["auto", "always", "avoid", "left", "right"] - elseif prop == 'page-break-inside' - let values = ["auto", "avoid"] - elseif prop =~ 'pause-\(after\|before\)$' - return [] - elseif prop == 'pause' - return [] - elseif prop == 'pitch-range' - return [] - elseif prop == 'pitch' - let values = ["x-low", "low", "medium", "high", "x-high"] - elseif prop == 'play-during' - let values = ["url(", "mix", "repeat", "auto", "none"] - elseif prop == 'position' - let values = ["static", "relative", "absolute", "fixed"] - elseif prop == 'quotes' - let values = ["none"] - elseif prop == 'richness' - return [] - elseif prop == 'speak-header' - let values = ["once", "always"] - elseif prop == 'speak-numeral' - let values = ["digits", "continuous"] - elseif prop == 'speak-punctuation' - let values = ["code", "none"] - elseif prop == 'speak' - let values = ["normal", "none", "spell-out"] - elseif prop == 'speech-rate' - let values = ["x-slow", "slow", "medium", "fast", "x-fast", "faster", "slower"] - elseif prop == 'stress' - return [] - elseif prop == 'table-layout' - let values = ["auto", "fixed"] - elseif prop == 'text-align' - let values = ["left", "right", "center", "justify"] - elseif prop == 'text-decoration' - let values = ["none", "underline", "overline", "line-through", "blink"] - elseif prop == 'text-indent' - return [] - elseif prop == 'text-transform' - let values = ["capitalize", "uppercase", "lowercase", "none"] - elseif prop == 'top' - let values = ["auto"] - elseif prop == 'unicode-bidi' - let values = ["normal", "embed", "bidi-override"] - elseif prop == 'vertical-align' - let values = ["baseline", "sub", "super", "top", "text-top", "middle", "bottom", "text-bottom"] - elseif prop == 'visibility' - let values = ["visible", "hidden", "collapse"] - elseif prop == 'voice-family' - return [] - elseif prop == 'volume' - let values = ["silent", "x-soft", "soft", "medium", "loud", "x-loud"] - elseif prop == 'white-space' - let values = ["normal", "pre", "nowrap", "pre-wrap", "pre-line"] - elseif prop == 'widows' + else return [] - elseif prop == 'word-spacing' - let values = ["normal"] - elseif prop == 'z-index' - let values = ["auto"] + endif + elseif prop == 'overflow' + let values = ["visible", "hidden", "scroll", "auto"] + elseif prop == 'padding' + return [] + elseif prop =~ 'padding-\%(top\|right\|bottom\|left\)$' + return [] + elseif prop =~ 'page-break-\%(after\|before\)$' + let values = ["auto", "always", "avoid", "left", "right"] + elseif prop == 'page-break-inside' + let values = ["auto", "avoid"] + elseif prop =~ 'pause-\%(after\|before\)$' + return [] + elseif prop == 'pause' + return [] + elseif prop == 'pitch-range' + return [] + elseif prop == 'pitch' + let values = ["x-low", "low", "medium", "high", "x-high"] + elseif prop == 'play-during' + let values = ["url(", "mix", "repeat", "auto", "none"] + elseif prop == 'position' + let values = ["static", "relative", "absolute", "fixed"] + elseif prop == 'quotes' + let values = ["none"] + elseif prop == 'richness' + return [] + elseif prop == 'speak-header' + let values = ["once", "always"] + elseif prop == 'speak-numeral' + let values = ["digits", "continuous"] + elseif prop == 'speak-punctuation' + let values = ["code", "none"] + elseif prop == 'speak' + let values = ["normal", "none", "spell-out"] + elseif prop == 'speech-rate' + let values = ["x-slow", "slow", "medium", "fast", "x-fast", "faster", "slower"] + elseif prop == 'stress' + return [] + elseif prop == 'table-layout' + let values = ["auto", "fixed"] + elseif prop == 'text-align' + let values = ["left", "right", "center", "justify"] + elseif prop == 'text-decoration' + let values = ["none", "underline", "overline", "line-through", "blink"] + elseif prop == 'text-indent' + return [] + elseif prop == 'text-transform' + let values = ["capitalize", "uppercase", "lowercase", "none"] + elseif prop == 'top' + let values = ["auto"] + elseif prop == 'unicode-bidi' + let values = ["normal", "embed", "bidi-override"] + elseif prop == 'vertical-align' + let values = ["baseline", "sub", "super", "top", "text-top", "middle", "bottom", "text-bottom"] + elseif prop == 'visibility' + let values = ["visible", "hidden", "collapse"] + elseif prop == 'voice-family' + return [] + elseif prop == 'volume' + let values = ["silent", "x-soft", "soft", "medium", "loud", "x-loud"] + elseif prop == 'white-space' + let values = ["normal", "pre", "nowrap", "pre-wrap", "pre-line"] + elseif prop == 'widows' + return [] + elseif prop == 'word-spacing' + let values = ["normal"] + elseif prop == 'z-index' + let values = ["auto"] + else + " If no property match it is possible we are outside of {} and + " trying to complete pseudo-(class|element) + let element = tolower(matchstr(line, '\zs[a-zA-Z1-6]*\ze:[^:[:space:]]\{-}$')) + if stridx(',a,abbr,acronym,address,area,b,base,bdo,big,blockquote,body,br,button,caption,cite,code,col,colgroup,dd,del,dfn,div,dl,dt,em,fieldset,form,head,h1,h2,h3,h4,h5,h6,hr,html,i,img,input,ins,kbd,label,legend,li,link,map,meta,noscript,object,ol,optgroup,option,p,param,pre,q,samp,script,select,small,span,strong,style,sub,sup,table,tbody,td,textarea,tfoot,th,thead,title,tr,tt,ul,var,', ','.element.',') > -1 + let values = ["first-child", "link", "visited", "hover", "active", "focus", "lang", "first-line", "first-letter", "before", "after"] else - " If no property match it is possible we are outside of {} and - " trying to complete pseudo-(class|element) - let element = tolower(matchstr(line, '\zs[a-zA-Z1-6]*\ze:[^:[:space:]]\{-}$')) - if ",a,abbr,acronym,address,area,b,base,bdo,big,blockquote,body,br,button,caption,cite,code,col,colgroup,dd,del,dfn,div,dl,dt,em,fieldset,form,head,h1,h2,h3,h4,h5,h6,hr,html,i,img,input,ins,kbd,label,legend,li,link,map,meta,noscript,object,ol,optgroup,option,p,param,pre,q,samp,script,select,small,span,strong,style,sub,sup,table,tbody,td,textarea,tfoot,th,thead,title,tr,tt,ul,var," =~ ','.element.',' - let values = ["first-child", "link", "visited", "hover", "active", "focus", "lang", "first-line", "first-letter", "before", "after"] - else - return [] - endif + return [] endif + endif - " Complete values - let entered_value = matchstr(line, '.\{-}\zs[a-zA-Z0-9#,.(_-]*$') - - for m in values - if m =~? '^'.entered_value - call add(res, m) - elseif m =~? entered_value - call add(res2, m) - endif - endfor - - return res + res2 - - elseif borders[min(keys(borders))] == 'closebrace' + " Complete values + let entered_value = matchstr(line, '.\{-}\zs[a-zA-Z0-9#,.(_-]*$') - return [] + for m in values + if m =~? '^'.entered_value + call add(res, m) + elseif m =~? entered_value + call add(res2, m) + endif + endfor - elseif borders[min(keys(borders))] == 'exclam' + return res + res2 - " Complete values - let entered_imp = matchstr(line, '.\{-}!\s*\zs[a-zA-Z ]*$') +elseif borders[max(keys(borders))] == 'closebrace' - let values = ["important"] + return [] - for m in values - if m =~? '^'.entered_imp - call add(res, m) - endif - endfor +elseif borders[max(keys(borders))] == 'exclam' - return res + " Complete values + let entered_imp = matchstr(line, '.\{-}!\s*\zs[a-zA-Z ]*$') - elseif borders[min(keys(borders))] == 'atrule' + let values = ["important"] - let afterat = matchstr(line, '.*@\zs.*') + for m in values + if m =~? '^'.entered_imp + call add(res, m) + endif + endfor - if afterat =~ '\s' + return res - let atrulename = matchstr(line, '.*@\zs[a-zA-Z-]\+\ze') +elseif borders[max(keys(borders))] == 'atrule' - if atrulename == 'media' - let values = ["screen", "tty", "tv", "projection", "handheld", "print", "braille", "aural", "all"] + let afterat = matchstr(line, '.*@\zs.*') - let atruleafterbase = matchstr(line, '.*@media\s\+\ze.*$') - let entered_atruleafter = matchstr(line, '.*@media\s\+\zs.*$') + if afterat =~ '\s' - elseif atrulename == 'import' - let atruleafterbase = matchstr(line, '.*@import\s\+\ze.*$') - let entered_atruleafter = matchstr(line, '.*@import\s\+\zs.*$') + let atrulename = matchstr(line, '.*@\zs[a-zA-Z-]\+\ze') - if entered_atruleafter =~ "^[\"']" - let filestart = matchstr(entered_atruleafter, '^.\zs.*') - let files = split(glob(filestart.'*'), '\n') - let values = map(copy(files), '"\"".v:val') + if atrulename == 'media' + let values = ["screen", "tty", "tv", "projection", "handheld", "print", "braille", "aural", "all"] - elseif entered_atruleafter =~ "^url(" - let filestart = matchstr(entered_atruleafter, "^url([\"']\\?\\zs.*") - let files = split(glob(filestart.'*'), '\n') - let values = map(copy(files), '"url(".v:val') + let atruleafterbase = matchstr(line, '.*@media\s\+\ze.*$') + let entered_atruleafter = matchstr(line, '.*@media\s\+\zs.*$') - else - let values = ['"', 'url('] + elseif atrulename == 'import' + let atruleafterbase = matchstr(line, '.*@import\s\+\ze.*$') + let entered_atruleafter = matchstr(line, '.*@import\s\+\zs.*$') - endif + if entered_atruleafter =~ "^[\"']" + let filestart = matchstr(entered_atruleafter, '^.\zs.*') + let files = split(glob(filestart.'*'), '\n') + let values = map(copy(files), '"\"".v:val') + elseif entered_atruleafter =~ "^url(" + let filestart = matchstr(entered_atruleafter, "^url([\"']\\?\\zs.*") + let files = split(glob(filestart.'*'), '\n') + let values = map(copy(files), '"url(".v:val') + else - return [] + let values = ['"', 'url('] endif - for m in values - if m =~? '^'.entered_atruleafter - call add(res, m) - elseif m =~? entered_atruleafter - call add(res2, m) - endif - endfor - - return res + res2 + else + return [] endif - let values = ["charset", "page", "media", "import", "font-face"] - - let entered_atrule = matchstr(line, '.*@\zs[a-zA-Z-]*$') - for m in values - if m =~? '^'.entered_atrule - call add(res, m .' ') - elseif m =~? entered_atrule - call add(res2, m .' ') + if m =~? '^'.entered_atruleafter + call add(res, m) + elseif m =~? entered_atruleafter + call add(res2, m) endif endfor @@ -424,7 +409,22 @@ else endif - return [] + let values = ["charset", "page", "media", "import", "font-face"] + + let entered_atrule = matchstr(line, '.*@\zs[a-zA-Z-]*$') + + for m in values + if m =~? '^'.entered_atrule + call add(res, m .' ') + elseif m =~? entered_atrule + call add(res2, m .' ') + endif + endfor + + return res + res2 + +endif + +return [] - endif endfunction diff --git a/runtime/autoload/decada.vim b/runtime/autoload/decada.vim new file mode 100644 index 000000000..9f8aaf260 --- /dev/null +++ b/runtime/autoload/decada.vim @@ -0,0 +1,75 @@ +"------------------------------------------------------------------------------ +" Description: Vim Ada/Dec Ada compiler file +" Language: Ada (Dec Ada) +" $Id$ +" Copyright: Copyright (C) 2006 Martin Krischik +" Maintainer: Martin Krischik +" $Author$ +" $Date$ +" Version: 4.2 +" $Revision$ +" $HeadURL: https://svn.sourceforge.net/svnroot/gnuada/trunk/tools/vim/autoload/decada.vim $ +" History: 21.07.2006 MK New Dec Ada +" 15.10.2006 MK Bram's suggestion for runtime integration +" 05.11.2006 MK Bram suggested not to use include protection for +" autoload +" 05.11.2006 MK Bram suggested to save on spaces +" Help Page: compiler-decada +"------------------------------------------------------------------------------ + +if version < 700 + finish +endif + +function decada#Unit_Name () dict " {{{1 + " Convert filename into acs unit: + " 1: remove the file extenstion. + " 2: replace all double '_' or '-' with an dot (which denotes a separate) + " 3: remove a trailing '_' (wich denotes a specification) + return substitute (substitute (expand ("%:t:r"), '__\|-', ".", "g"), '_$', "", '') +endfunction decada#Unit_Name " }}}1 + +function decada#Make () dict " {{{1 + let l:make_prg = substitute (g:self.Make_Command, '%<', self.Unit_Name(), '') + let &errorformat = g:self.Error_Format + let &makeprg = l:make_prg + wall + make + copen + set wrap + wincmd W +endfunction decada#Build " }}}1 + +function decada#Set_Session (...) dict " {{{1 + if a:0 > 0 + call ada#Switch_Session (a:1) + elseif argc() == 0 && strlen (v:servername) > 0 + call ada#Switch_Session ( + \ expand('~')[0:-2] . ".vimfiles.session]" . + \ v:servername . ".vim") + endif + return +endfunction decada#Set_Session " }}}1 + +function decada#New () " }}}1 + let Retval = { + \ 'Make' : function ('decada#Make'), + \ 'Unit_Name' : function ('decada#Unit_Name'), + \ 'Set_Session' : function ('decada#Set_Session'), + \ 'Project_Dir' : '', + \ 'Make_Command' : 'ACS COMPILE /Wait /Log /NoPreLoad /Optimize=Development /Debug %<', + \ 'Error_Format' : '%+A%%ADAC-%t-%m,%C %#%m,%Zat line number %l in file %f,' . + \ '%+I%%ada-I-%m,%C %#%m,%Zat line number %l in file %f'} + + return Retval +endfunction decada#New " }}}1 + +finish " 1}}} + +"------------------------------------------------------------------------------ +" Copyright (C) 2006 Martin Krischik +" +" Vim is Charityware - see ":help license" or uganda.txt for licence details. +"------------------------------------------------------------------------------ +" vim: textwidth=78 wrap tabstop=8 shiftwidth=3 softtabstop=3 noexpandtab +" vim: foldmethod=marker diff --git a/runtime/autoload/getscript.vim b/runtime/autoload/getscript.vim new file mode 100644 index 000000000..bfe057cc3 --- /dev/null +++ b/runtime/autoload/getscript.vim @@ -0,0 +1,501 @@ +" --------------------------------------------------------------------- +" getscript.vim +" Author: Charles E. Campbell, Jr. +" Date: Nov 27, 2006 +" Version: 23 +" Installing: :help glvs-install +" Usage: :help glvs +" +" GetLatestVimScripts: 642 1 :AutoInstall: getscript.vim +" --------------------------------------------------------------------- +" Initialization: {{{1 +" if you're sourcing this file, surely you can't be +" expecting vim to be in its vi-compatible mode +if &cp + echoerr "GetLatestVimScripts is not vi-compatible; not loaded (you need to set nocp)" + finish +endif +let s:keepfo = &fo +let s:keepcpo = &cpo +set cpo&vim + +if exists("g:loaded_getscript") + finish +endif +let g:loaded_getscript= "v23" + +" --------------------------------------------------------------------- +" Global Variables: {{{1 +" allow user to change the command for obtaining scripts (does fetch work?) +if !exists("g:GetLatestVimScripts_wget") + if executable("wget") + let g:GetLatestVimScripts_wget= "wget" + elseif executable("curl") + let g:GetLatestVimScripts_wget= "curl" + else + let g:GetLatestVimScripts_wget = 'echo "GetLatestVimScripts needs wget or curl"' + let g:GetLatestVimScripts_options = "" + endif +endif + +" options that wget and curl require: +if !exists("g:GetLatestVimScripts_options") + if g:GetLatestVimScripts_wget == "wget" + let g:GetLatestVimScripts_options= "-q -O" + elseif g:GetLatestVimScripts_wget == "curl" + let g:GetLatestVimScripts_options= "-s -O" + else + let g:GetLatestVimScripts_options= "" + endif +endif + +" by default, allow autoinstall lines to work +if !exists("g:GetLatestVimScripts_allowautoinstall") + let g:GetLatestVimScripts_allowautoinstall= 1 +endif + +"" For debugging: +"let g:GetLatestVimScripts_wget = "echo" +"let g:GetLatestVimScripts_options = "options" + +" --------------------------------------------------------------------- +" Check If AutoInstall Capable: {{{1 +let s:autoinstall= "" +if g:GetLatestVimScripts_allowautoinstall + + if (has("win32") || has("gui_win32") || has("gui_win32s") || has("win16") || has("win64") || has("win32unix") || has("win95")) && &shell != "bash" + " windows (but not cygwin/bash) + let s:dotvim= "vimfiles" + if !exists("g:GetLatestVimScripts_mv") + let g:GetLatestVimScripts_mv= "ren" + endif + + else + " unix + let s:dotvim= ".vim" + if !exists("g:GetLatestVimScripts_mv") + let g:GetLatestVimScripts_mv= "mv" + endif + endif + + if exists('$HOME') && isdirectory(expand("$HOME")."/".s:dotvim) + let s:autoinstall= $HOME."/".s:dotvim + endif +" call Decho("s:autoinstall<".s:autoinstall.">") +"else "Decho +" call Decho("g:GetLatestVimScripts_allowautoinstall=".g:GetLatestVimScripts_allowautoinstall.": :AutoInstall: disabled") +endif + +" --------------------------------------------------------------------- +" Public Interface: {{{1 +com! -nargs=0 GetLatestVimScripts call getscript#GetLatestVimScripts() +com! -nargs=0 GetScript call getscript#GetLatestVimScripts() +silent! com -nargs=0 GLVS call getscript#GetLatestVimScripts() + +" --------------------------------------------------------------------- +" GetOneScript: (Get Latest Vim Script) this function operates {{{1 +" on the current line, interpreting two numbers and text as +" ScriptID, SourceID, and Filename. +" It downloads any scripts that have newer versions from vim.sf.net. +fun! s:GetOneScript(...) +" call Dfunc("GetOneScript()") + + " set options to allow progress to be shown on screen + let t_ti= &t_ti + let t_te= &t_te + let rs = &rs + set t_ti= t_te= nors + + " put current line on top-of-screen and interpret it into + " a script identifer : used to obtain webpage + " source identifier : used to identify current version + " and an associated comment: used to report on what's being considered + if a:0 >= 3 + let scriptid = a:1 + let srcid = a:2 + let fname = a:3 + let cmmnt = "" +" call Decho("scriptid<".scriptid.">") +" call Decho("srcid <".srcid.">") +" call Decho("fname <".fname.">") + else + let curline = getline(".") + if curline =~ '^\s*#' +" call Dret("GetOneScript : skipping a pure comment line") + return + endif + let parsepat = '^\s*\(\d\+\)\s\+\(\d\+\)\s\+\(.\{-}\)\(\s*#.*\)\=$' + try + let scriptid = substitute(curline,parsepat,'\1','e') + catch /^Vim\%((\a\+)\)\=:E486/ + let scriptid= 0 + endtry + try + let srcid = substitute(curline,parsepat,'\2','e') + catch /^Vim\%((\a\+)\)\=:E486/ + let srcid= 0 + endtry + try + let fname= substitute(curline,parsepat,'\3','e') + catch /^Vim\%((\a\+)\)\=:E486/ + let fname= "" + endtry + try + let cmmnt= substitute(curline,parsepat,'\4','e') + catch /^Vim\%((\a\+)\)\=:E486/ + let cmmnt= "" + endtry +" call Decho("curline <".curline.">") +" call Decho("parsepat<".parsepat.">") +" call Decho("scriptid<".scriptid.">") +" call Decho("srcid <".srcid.">") +" call Decho("fname <".fname.">") + endif + + if scriptid == 0 || srcid == 0 + " When looking for :AutoInstall: lines, skip scripts that + " have 0 0 scriptname +" call Dret("GetOneScript : skipping a scriptid==srcid==0 line") + return + endif + + let doautoinstall= 0 + if fname =~ ":AutoInstall:" +" call Decho("fname<".fname."> has :AutoInstall:...") + let aicmmnt= substitute(fname,'\s\+:AutoInstall:\s\+',' ','') +" call Decho("aicmmnt<".aicmmnt."> s:autoinstall=".s:autoinstall) + if s:autoinstall != "" + let doautoinstall = g:GetLatestVimScripts_allowautoinstall + endif + else + let aicmmnt= fname + endif +" call Decho("aicmmnt<".aicmmnt.">: doautoinstall=".doautoinstall) + + exe "norm z\<CR>" + redraw! +" call Decho('considering <'.aicmmnt.'> scriptid='.scriptid.' srcid='.srcid) + echomsg 'considering <'.aicmmnt.'> scriptid='.scriptid.' srcid='.srcid + + " grab a copy of the plugin's vim.sf.net webpage + let scriptaddr = 'http://vim.sf.net/script.php?script_id='.scriptid + let tmpfile = tempname() + let v:errmsg = "" + + " make three tries at downloading the description + let itry= 1 + while itry <= 3 +" call Decho("try#".itry." to download description of <".aicmmnt."> with addr=".scriptaddr) + if has("win32") || has("win16") || has("win95") +" call Decho("silent !".g:GetLatestVimScripts_wget." ".g:GetLatestVimScripts_options." ".tmpfile.' "'.scriptaddr.'"') + exe "silent !".g:GetLatestVimScripts_wget." ".g:GetLatestVimScripts_options." ".tmpfile.' "'.scriptaddr.'"' + else +" call Decho("silent !".g:GetLatestVimScripts_wget." ".g:GetLatestVimScripts_options." ".tmpfile." '".scriptaddr."'") + exe "silent !".g:GetLatestVimScripts_wget." ".g:GetLatestVimScripts_options." ".tmpfile." '".scriptaddr."'" + endif + if itry == 1 + exe "silent vsplit ".tmpfile + else + silent! e % + endif + + " find the latest source-id in the plugin's webpage + silent! 1 + let findpkg= search('Click on the package to download','W') + if findpkg > 0 + break + endif + let itry= itry + 1 + endwhile +" call Decho(" --- end downloading tries while loop --- itry=".itry) + + " testing: did finding /Click on the package.../ fail? + if findpkg == 0 || itry >= 4 + silent q! + call delete(tmpfile) + " restore options + let &t_ti = t_ti + let &t_te = t_te + let &rs = rs + let s:downerrors = s:downerrors + 1 +" call Decho("***warning*** couldn'".'t find "Click on the package..." in description page for <'.aicmmnt.">") + echomsg "***warning*** couldn'".'t find "Click on the package..." in description page for <'.aicmmnt.">" +" call Dret("GetOneScript : srch for /Click on the package/ failed") + return + endif +" call Decho('found "Click on the package to download"') + + let findsrcid= search('src_id=','W') + if findsrcid == 0 + silent q! + call delete(tmpfile) + " restore options + let &t_ti = t_ti + let &t_te = t_te + let &rs = rs + let s:downerrors = s:downerrors + 1 +" call Decho("***warning*** couldn'".'t find "src_id=" in description page for <'.aicmmnt.">") + echomsg "***warning*** couldn'".'t find "src_id=" in description page for <'.aicmmnt.">" +" call Dret("GetOneScript : srch for /src_id/ failed") + return + endif +" call Decho('found "src_id=" in description page') + + let srcidpat = '^\s*<td class.*src_id=\(\d\+\)">\([^<]\+\)<.*$' + let latestsrcid= substitute(getline("."),srcidpat,'\1','') + let fname = substitute(getline("."),srcidpat,'\2','') +" call Decho("srcidpat<".srcidpat."> latestsrcid<".latestsrcid."> fname<".fname.">") + silent q! + call delete(tmpfile) + + " convert the strings-of-numbers into numbers + let srcid = srcid + 0 + let latestsrcid = latestsrcid + 0 +" call Decho("srcid=".srcid." latestsrcid=".latestsrcid." fname<".fname.">") + + " has the plugin's most-recent srcid increased, which indicates + " that it has been updated + if latestsrcid > srcid + let s:downloads= s:downloads + 1 + if fname == bufname("%") + " GetLatestVimScript has to be careful about downloading itself + let fname= "NEW_".fname + endif + + " the plugin has been updated since we last obtained it, so download a new copy +" call Decho("...downloading new <".fname.">") + echomsg "...downloading new <".fname.">" + if has("win32") || has("gui_win32") || has("gui_win32s") || has("win16") || has("win64") || has("win32unix") || has("win95") +" call Decho("windows: silent !".g:GetLatestVimScripts_wget." ".g:GetLatestVimScripts_options." ".fname.' "'.'http://vim.sf.net/scripts/download_script.php?src_id='.latestsrcid.'"') + exe "silent !".g:GetLatestVimScripts_wget." ".g:GetLatestVimScripts_options." ".fname.' "'.'http://vim.sf.net/scripts/download_script.php?src_id='.latestsrcid.'"' + else +" call Decho("unix: silent !".g:GetLatestVimScripts_wget." ".g:GetLatestVimScripts_options." ".fname." '".'http://vim.sf.net/scripts/download_script.php?src_id='.latestsrcid."'") + exe "silent !".g:GetLatestVimScripts_wget." ".g:GetLatestVimScripts_options." ".fname." '".'http://vim.sf.net/scripts/download_script.php?src_id='.latestsrcid."'" + endif + + " AutoInstall: only if doautoinstall is so indicating + if doautoinstall +" call Decho("attempting to do autoinstall: getcwd<".getcwd()."> filereadable(".fname.")=".filereadable(fname)) + if filereadable(fname) +" call Decho("move <".fname."> to ".s:autoinstall) +" call Decho("DISABLED for testing") + exe "silent !".g:GetLatestVimScripts_mv." ".fname." ".s:autoinstall + let curdir= escape(substitute(getcwd(),'\','/','ge'),"|[]*'\" #") + exe "cd ".s:autoinstall + if fname =~ '\.bz2$' +" call Decho("attempt to bunzip2 ".fname) + exe "silent !bunzip2 ".fname + let fname= substitute(fname,'\.bz2$','','') + elseif fname =~ '\.gz$' +" call Decho("attempt to gunzip ".fname) + exe "silent !gunzip ".fname + let fname= substitute(fname,'\.gz$','','') + endif + if fname =~ '\.zip$' +" call Decho("attempt to unzip ".fname) + exe "silent !unzip -o".fname + elseif fname =~ '\.tar$' +" call Decho("attempt to untar ".fname) + exe "silent !tar -xvf ".fname + elseif fname =~ '\.vba$' +" call Decho("attempt to handle a vimball: ".fname) + 1split + exe "e ".fname + so % + q + endif + if fname =~ '.vim$' +" call Decho("attempt to simply move ".fname." to plugin") + exe "silent !".g:GetLatestVimScripts_mv." ".fname." plugin" + endif + let docdir= substitute(&rtp,',.*','','e')."/doc" +" call Decho("helptags docdir<".docdir.">") + exe "helptags ".docdir + exe "cd ".curdir + endif + endif + + " update the data in the <GetLatestVimScripts.dat> file + let modline=scriptid." ".latestsrcid." ".fname.cmmnt + call setline(line("."),modline) +" call Decho("modline<".modline."> (updated GetLatestVimScripts.dat file)") + endif + + " restore options + let &t_ti= t_ti + let &t_te= t_te + let &rs = rs + +" call Dret("GetOneScript") +endfun + +" --------------------------------------------------------------------- +" GetLatestVimScripts: this function gets the latest versions of {{{1 +" scripts based on the list in +" (first dir in runtimepath)/GetLatest/GetLatestVimScripts.dat +fun! getscript#GetLatestVimScripts() +" call Dfunc("GetLatestVimScripts() autoinstall<".s:autoinstall.">") + +" insure that wget is executable + if executable(g:GetLatestVimScripts_wget) != 1 + echoerr "GetLatestVimScripts needs ".g:GetLatestVimScripts_wget." which apparently is not available on your system" +" call Dret("GetLatestVimScripts : wget not executable/availble") + return + endif + + " Find the .../GetLatest subdirectory under the runtimepath + for datadir in split(&rtp,',') + [''] + if isdirectory(datadir."/GetLatest") +" call Decho("found directory<".datadir.">") + let datadir= datadir . "/GetLatest" + break + endif + if filereadable(datadir."GetLatestVimScripts.dat") +" call Decho("found ".datadir."/GetLatestVimScripts.dat") + break + endif + endfor + " Sanity checks: readability and writability + if datadir == "" + echoerr 'Missing "GetLatest/" on your runtimepath - see :help glvs-dist-install' +" call Dret("GetLatestVimScripts : unable to find a GetLatest subdirectory") + return + endif + + if filewritable(datadir) != 2 + echoerr "(getLatestVimScripts) Your ".datadir." isn't writable" +" call Dret("GetLatestVimScripts : non-writable directory<".datadir.">") + return + endif + let datafile= datadir."/GetLatestVimScripts.dat" + if !filereadable(datafile) + echoerr "Your data file<".datafile."> isn't readable" +" call Dret("GetLatestVimScripts : non-readable datafile<".datafile.">") + return + endif + if !filewritable(datafile) + echoerr "Your data file<".datafile."> isn't writable" +" call Dret("GetLatestVimScripts : non-writable datafile<".datafile.">") + return + endif +" call Decho("datadir <".datadir.">") +" call Decho("datafile <".datafile.">") + + " don't let any events interfere (like winmanager's, taglist's, etc) + let eikeep= &ei + set ei=all + + " record current directory, change to datadir, open split window with + " datafile + let origdir= getcwd() + exe "cd ".escape(substitute(datadir,'\','/','ge'),"|[]*'\" #") + split + exe "e ".escape(substitute(datafile,'\','/','ge'),"|[]*'\" #") + res 1000 + let s:downloads = 0 + let s:downerrors= 0 + + " Check on dependencies mentioned in plugins +" call Decho(" ") +" call Decho("searching plugins for GetLatestVimScripts dependencies") + let lastline = line("$") + let plugins = globpath(&rtp,"plugin/*.vim") + let foundscript = 0 + +" call Decho("plugins<".plugins."> lastline#".lastline) + while plugins != "" + let plugin = substitute(plugins,'\n.*$','','e') + let plugins= (plugins =~ '\n')? substitute(plugins,'^.\{-}\n\(.*\)$','\1','e') : "" + $ +" call Decho(".dependency checking<".plugin."> line$=".line("$")) + exe "silent r ".plugin + while search('^"\s\+GetLatestVimScripts:\s\+\d\+\s\+\d\+','W') != 0 + let newscript= substitute(getline("."),'^"\s\+GetLatestVimScripts:\s\+\d\+\s\+\d\+\s\+\(.*\)$','\1','e') + let llp1 = lastline+1 + + if newscript !~ '^"' + " found a "GetLatestVimScripts: # #" line in the script; check if its already in the datafile + let curline = line(".") + let noai_script = substitute(newscript,'\s*:AutoInstall:\s*','','e') + exe llp1 + let srchline = search('\<'.noai_script.'\>','bW') +" call Decho("..newscript<".newscript."> noai_script<".noai_script."> srch=".srchline." lastline=".lastline) + + if srchline == 0 + " found a new script to permanently include in the datafile + let keep_rega = @a + let @a = substitute(getline(curline),'^"\s\+GetLatestVimScripts:\s\+','','') + exe lastline."put a" + echomsg "Appending <".@a."> to ".datafile." for ".newscript +" call Decho("..APPEND (".noai_script.")<".@a."> to GetLatestVimScripts.dat") + let @a = keep_rega + let lastline = llp1 + let curline = curline + 1 + let foundscript = foundscript + 1 +" else " Decho +" call Decho("..found <".noai_script."> (already in datafile at line#".srchline.")") + endif + + let curline = curline + 1 + exe curline + endif + + endwhile + let llp1= lastline + 1 +" call Decho(".deleting lines: ".llp1.",$d") + exe "silent! ".llp1.",$d" + endwhile + + if foundscript == 0 + set nomod + endif + + " Check on out-of-date scripts using GetLatest/GetLatestVimScripts.dat + set lz +" call Decho(" --- end of dependency checking loop --- ") +" call Decho("call GetOneScript on lines at end of datafile<".datafile.">") + 1 + /^-----/,$g/^\s*\d/call <SID>GetOneScript() + + " Final report (an echomsg) + try + silent! ?^-------? + catch /^Vim\%((\a\+)\)\=:E114/ +" call Dret("GetLatestVimScripts : nothing done!") + return + endtry + exe "norm! kz\<CR>" + redraw! + let s:msg = "" + if s:downloads == 1 + let s:msg = "Downloaded one updated script to <".datadir.">" + elseif s:downloads == 2 + let s:msg= "Downloaded two updated scripts to <".datadir.">" + elseif s:downloads > 1 + let s:msg= "Downloaded ".s:downloads." updated scripts to <".datadir.">" + else + let s:msg= "Everything was already current" + endif + if s:downerrors > 0 + let s:msg= s:msg." (".s:downerrors." downloading errors)" + endif + echomsg s:msg + " save the file + if &mod + silent! w! + endif + q + + " restore events and current directory + exe "cd ".escape(substitute(origdir,'\','/','ge'),"|[]*'\" #") + let &ei= eikeep + set nolz +" call Dret("GetLatestVimScripts : did ".s:downloads." downloads") +endfun +" --------------------------------------------------------------------- + +" Restore Options: {{{1 +let &fo = s:keepfo +let &cpo= s:keepcpo + +" vim: ts=8 sts=2 fdm=marker nowrap diff --git a/runtime/autoload/netrw.vim b/runtime/autoload/netrw.vim index a2f7efc02..6e80a6926 100644 --- a/runtime/autoload/netrw.vim +++ b/runtime/autoload/netrw.vim @@ -1,10 +1,10 @@ -" netrw.vim: Handles file transfer and remote directory listing across a network -" AUTOLOAD PORTION -" Date: May 02, 2006 -" Version: 98 -" Maintainer: Charles E Campbell, Jr <drchipNOSPAM at campbellfamily dot biz> +" netrw.vim: Handles file transfer and remote directory listing across +" AUTOLOAD SECTION +" Date: Mar 21, 2007 +" Version: 108 +" Maintainer: Charles E Campbell, Jr <NdrOchip@ScampbellPfamily.AbizM-NOSPAM> " GetLatestVimScripts: 1075 1 :AutoInstall: netrw.vim -" Copyright: Copyright (C) 1999-2005 Charles E. Campbell, Jr. {{{1 +" Copyright: Copyright (C) 1999-2007 Charles E. Campbell, Jr. {{{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, @@ -14,29 +14,53 @@ " in no event will the copyright holder be liable for any damages " resulting from the use of this software. " of this software. +" COMBAK: worked with tmpfile s:GetTempname() in NetRead() NetWrite() +" !!NEEDS DEBUGGING && TESTING!!! +"redraw!|call inputsave()|call input("Press <cr> to continue")|call inputrestore() " " But be doers of the Word, and not only hearers, deluding your own selves {{{1 " (James 1:22 RSV) " =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- - -" Exception for &cp: {{{1 +" Load Once: {{{1 if &cp || exists("g:loaded_netrw") finish endif -let g:loaded_netrw = "v98" +if !exists("s:NOTE") + let s:NOTE = 0 + let s:WARNING = 1 + let s:ERROR = 2 +endif +let g:loaded_netrw = "v108" if v:version < 700 - echohl WarningMsg | echo "***netrw*** you need vim version 7.0 or later for version ".g:loaded_netrw." of netrw" | echohl None + call netrw#ErrorMsg(s:WARNING,"you need vim version 7.0 or later for version ".g:loaded_netrw." of netrw",1) finish endif let s:keepcpo= &cpo -set cpo&vim -" call Decho("doing autoload/netrw.vim") +setlocal cpo&vim +"DechoTabOn +"call Decho("doing autoload/netrw.vim version ".g:loaded_netrw) " ====================== " Netrw Variables: {{{1 " ====================== " --------------------------------------------------------------------- +" Netrw Constants: {{{2 +if !exists("g:NETRW_BOOKMARKMAX") + let g:NETRW_BOOKMARKMAX= 0 +endif +if !exists("g:NETRW_DIRHIST_CNT") + let g:NETRW_DIRHIST_CNT= 0 +endif +if !exists("s:LONGLIST") + let s:THINLIST = 0 + let s:LONGLIST = 1 + let s:WIDELIST = 2 + let s:TREELIST = 3 + let s:MAXLIST = 4 +endif + +" --------------------------------------------------------------------- " Default values for netrw's global protocol variables {{{2 if !exists("g:netrw_dav_cmd") let g:netrw_dav_cmd = "cadaver" @@ -52,7 +76,9 @@ if !exists("g:netrw_ftp_cmd") let g:netrw_ftp_cmd = "ftp" endif if !exists("g:netrw_http_cmd") - if executable("wget") + if executable("curl") + let g:netrw_http_cmd = "curl -o" + elseif executable("wget") let g:netrw_http_cmd = "wget -q -O" elseif executable("fetch") let g:netrw_http_cmd = "fetch -o" @@ -82,7 +108,7 @@ if (has("win32") || has("win95") || has("win64") || has("win16")) \ && executable( $SystemRoot .'/system32/rcp.exe') let s:netrw_has_nt_rcp = 1 let s:netrw_rcpmode = '-b' - else +else let s:netrw_has_nt_rcp = 0 let s:netrw_rcpmode = '' endif @@ -91,17 +117,20 @@ endif " Default values for netrw's global variables {{{2 " Default values - a-c ---------- {{{3 if !exists("g:netrw_alto") - let g:netrw_alto= 0 + let g:netrw_alto= &sb endif if !exists("g:netrw_altv") - let g:netrw_altv= 0 + let g:netrw_altv= &spr endif if !exists("g:netrw_browse_split") let g:netrw_browse_split= 0 endif +if !exists("g:netrw_chgwin") + let g:netrw_chgwin = -1 +endif if !exists("g:netrw_cygwin") if has("win32") || has("win95") || has("win64") || has("win16") - if &shell == "bash" + if &shell =~ '\%(\<bash\>\|\<zsh\>\)\%(\.exe\)\=$' let g:netrw_cygwin= 1 else let g:netrw_cygwin= 0 @@ -109,6 +138,8 @@ if !exists("g:netrw_cygwin") else let g:netrw_cygwin= 0 endif +else + let g:netrw_cygwin= 0 endif " Default values - d-f ---------- {{{3 if !exists("g:NETRW_DIRHIST_CNT") @@ -121,10 +152,14 @@ if !exists("g:netrw_ftp_browse_reject") let g:netrw_ftp_browse_reject='^total\s\+\d\+$\|^Trying\s\+\d\+.*$\|^KERBEROS_V\d rejected\|^Security extensions not\|No such file\|: connect to address [0-9a-fA-F:]*: No route to host$' endif if !exists("g:netrw_ftp_list_cmd") - if has("unix") || exists("g:netrw_cygwin") - let g:netrw_ftp_list_cmd= "ls -lF" + if has("unix") || (exists("g:netrw_cygwin") && g:netrw_cygwin) + let g:netrw_ftp_list_cmd = "ls -lF" + let g:netrw_ftp_timelist_cmd = "ls -tlF" + let g:netrw_ftp_sizelist_cmd = "ls -slF" else - let g:netrw_ftp_list_cmd= "dir" + let g:netrw_ftp_list_cmd = "dir" + let g:netrw_ftp_timelist_cmd = "dir" + let g:netrw_ftp_sizelist_cmd = "dir" endif endif if !exists("g:netrw_ftpmode") @@ -134,15 +169,28 @@ endif if !exists("g:netrw_hide") let g:netrw_hide= 1 endif +if !exists("g:netrw_ignorenetrc") + if &shell =~ '\c\<\%(cmd\|4nt\)\.exe$' + let g:netrw_ignorenetrc= 1 + else + let g:netrw_ignorenetrc= 0 + endif +endif if !exists("g:netrw_keepdir") let g:netrw_keepdir= 1 endif if !exists("g:netrw_list_cmd") - if executable(g:netrw_ssh_cmd) + if g:netrw_scp_cmd =~ '^pscp' && executable("pscp") + " provide a 'pscp' listing command + if (has("win32") || has("win95") || has("win64") || has("win16")) && filereadable("c:\\private.ppk") + let g:netrw_scp_cmd ="pscp -i C:\\private.ppk" + endif + let g:netrw_list_cmd= g:netrw_scp_cmd." -ls USEPORT HOSTNAME:" + elseif executable(g:netrw_ssh_cmd) " provide a default listing command - let g:netrw_list_cmd= g:netrw_ssh_cmd." HOSTNAME ls -FLa" + let g:netrw_list_cmd= g:netrw_ssh_cmd." USEPORT HOSTNAME ls -FLa" else -" call Decho(g:netrw_ssh_cmd." is not executable, can't do remote directory exploring") +" call Decho(g:netrw_ssh_cmd." is not executable") let g:netrw_list_cmd= "" endif endif @@ -156,34 +204,37 @@ endif if !exists("g:netrw_local_rmdir") let g:netrw_local_rmdir= "rmdir" endif -if !exists("g:netrw_longlist") - let g:netrw_longlist= 0 +if !exists("g:netrw_liststyle") + let g:netrw_liststyle= s:THINLIST endif -if g:netrw_longlist < 0 || g:netrw_longlist > 2 +if g:netrw_liststyle < 0 || g:netrw_liststyle >= s:MAXLIST " sanity check - let g:netrw_longlist= 0 + let g:netrw_liststyle= s:THINLIST endif -if g:netrw_longlist == 1 +if g:netrw_liststyle == s:LONGLIST && g:netrw_scp_cmd !~ '^pscp' let g:netrw_list_cmd= g:netrw_list_cmd." -l" endif " Default values - m-r ---------- {{{3 if !exists("g:netrw_maxfilenamelen") let g:netrw_maxfilenamelen= 32 endif +if !exists("g:netrw_menu") + let g:netrw_menu= 1 +endif if !exists("g:netrw_mkdir_cmd") - let g:netrw_mkdir_cmd= g:netrw_ssh_cmd." HOSTNAME mkdir" + let g:netrw_mkdir_cmd= g:netrw_ssh_cmd." USEPORT HOSTNAME mkdir" endif if !exists("g:netrw_rename_cmd") - let g:netrw_rename_cmd= g:netrw_ssh_cmd." HOSTNAME mv" + let g:netrw_rename_cmd= g:netrw_ssh_cmd." USEPORT HOSTNAME mv" endif if !exists("g:netrw_rm_cmd") - let g:netrw_rm_cmd = g:netrw_ssh_cmd." HOSTNAME rm" + let g:netrw_rm_cmd = g:netrw_ssh_cmd." USEPORT HOSTNAME rm" endif if !exists("g:netrw_rmdir_cmd") - let g:netrw_rmdir_cmd = g:netrw_ssh_cmd." HOSTNAME rmdir" + let g:netrw_rmdir_cmd = g:netrw_ssh_cmd." USEPORT HOSTNAME rmdir" endif if !exists("g:netrw_rmf_cmd") - let g:netrw_rmf_cmd = g:netrw_ssh_cmd." HOSTNAME rm -f" + let g:netrw_rmf_cmd = g:netrw_ssh_cmd." USEPORT HOSTNAME rm -f" endif " Default values - s ---------- {{{3 if exists("g:netrw_silent") && g:netrw_silent != 0 @@ -194,6 +245,20 @@ endif if !exists("g:netrw_fastbrowse") let g:netrw_fastbrowse= 1 endif +if !exists("g:netrw_shq") + if exists("&shq") && &shq != "" + let g:netrw_shq= &shq + elseif has("win32") || has("win95") || has("win64") || has("win16") + if g:netrw_cygwin + let g:netrw_shq= "'" + else + let g:netrw_shq= '"' + endif + else + let g:netrw_shq= "'" + endif +" call Decho("g:netrw_shq<".g:netrw_shq.">") +endif if !exists("g:netrw_sort_by") " alternatives: date size let g:netrw_sort_by= "name" @@ -203,15 +268,25 @@ if !exists("g:netrw_sort_direction") let g:netrw_sort_direction= "normal" endif if !exists("g:netrw_sort_sequence") - let g:netrw_sort_sequence= '[\/]$,*,\.bak$,\.o$,\.h$,\.info$,\.swp$,\.obj$' + let g:netrw_sort_sequence= '[\/]$,\.h$,\.c$,\.cpp$,\.[a-np-z]$,*,\.info$,\.swp$,\.o$\.obj$,\.bak$' endif if !exists("g:netrw_ssh_browse_reject") let g:netrw_ssh_browse_reject='^total\s\+\d\+$' endif +if !has("patch192") + if !exists("g:netrw_use_noswf") + let g:netrw_use_noswf= 1 + endif +else + let g:netrw_use_noswf= 0 +endif " Default values - t-w ---------- {{{3 if !exists("g:netrw_timefmt") let g:netrw_timefmt= "%c" endif +if !exists("g:NetrwTopLvlMenu") + let g:NetrwTopLvlMenu= "Netrw." +endif if !exists("g:netrw_win95ftp") let g:netrw_win95ftp= 1 endif @@ -221,11 +296,7 @@ endif " --------------------------------------------------------------------- " Default values for netrw's script variables: {{{2 if !exists("s:netrw_cd_escape") - if has("win32") || has("win95") || has("win64") || has("win16") - let s:netrw_cd_escape="#% " - else let s:netrw_cd_escape="[]#*$%'\" ?`!&();<>\\" - endif endif if !exists("g:netrw_fname_escape") let g:netrw_fname_escape= ' ?&;' @@ -234,11 +305,7 @@ if !exists("g:netrw_tmpfile_escape") let g:netrw_tmpfile_escape= ' ?&;' endif if !exists("s:netrw_glob_escape") - if has("win32") || has("win95") || has("win64") || has("win16") - let s:netrw_glob_escape= "" - else let s:netrw_glob_escape= '[]*?`{~$' - endif endif " BufEnter event ignored by decho when following variable is true @@ -253,7 +320,7 @@ endif " ------------------------------------------------------------------------ " NetSavePosn: saves position of cursor on screen {{{2 fun! netrw#NetSavePosn() -" call Dfunc("NetSavePosn()") +" call Dfunc("netrw#NetSavePosn()") " Save current line and column let w:netrw_winnr= winnr() let w:netrw_line = line(".") @@ -264,55 +331,188 @@ fun! netrw#NetSavePosn() let w:netrw_hline= line(".") call netrw#NetRestorePosn() -" call Dret("NetSavePosn : winnr=".w:netrw_winnr." line=".w:netrw_line." col=".w:netrw_col." hline=".w:netrw_hline) +" call Dret("netrw#NetSavePosn : winnr=".w:netrw_winnr." line=".w:netrw_line." col=".w:netrw_col." hline=".w:netrw_hline) endfun " ------------------------------------------------------------------------ " NetRestorePosn: restores the cursor and file position as saved by NetSavePosn() {{{2 fun! netrw#NetRestorePosn() -" call Dfunc("NetRestorePosn() winnr=".w:netrw_winnr." line=".w:netrw_line." col=".w:netrw_col." hline=".w:netrw_hline) +" call Dfunc("netrw#NetRestorePosn() winnr=".(exists("w:netrw_winnr")? w:netrw_winnr : -1)." line=".(exists("w:netrw_line")? w:netrw_line : -1)." col=".(exists("w:netrw_col")? w:netrw_col : -1)." hline=".(exists("w:netrw_hline")? w:netrw_hline : -1)) let eikeep= &ei set ei=all + if expand("%") == "NetrwMessage" + exe s:winBeforeErr."wincmd w" + endif " restore window -" call Decho("restore window: exe silent! ".w:netrw_winnr."wincmd w") - exe "silent! ".w:netrw_winnr."wincmd w" -" if v:shell_error == 0 -" " as suggested by Bram M: redraw on no error -" " allows protocol error messages to remain visible -" redraw! -" endif + if exists("w:netrw_winnr") +" call Decho("restore window: exe silent! ".w:netrw_winnr."wincmd w") + exe "silent! ".w:netrw_winnr."wincmd w" + endif + if v:shell_error == 0 + " as suggested by Bram M: redraw on no error + " allows protocol error messages to remain visible + redraw! + endif " restore top-of-screen line -" call Decho("restore topofscreen: exe norm! ".w:netrw_hline."G0z") - exe "norm! ".w:netrw_hline."G0z\<CR>" + if exists("w:netrw_hline") +" call Decho("restore topofscreen: exe norm! ".w:netrw_hline."G0z") + exe "norm! ".w:netrw_hline."G0z\<CR>" + endif " restore position -" call Decho("restore posn: exe norm! ".w:netrw_line."G0".w:netrw_col."|") - exe "norm! ".w:netrw_line."G0".w:netrw_col."\<bar>" + if exists("w:netrw_line") && exists("w:netrw_col") +" call Decho("restore posn: exe norm! ".w:netrw_line."G0".w:netrw_col."|") + exe "norm! ".w:netrw_line."G0".w:netrw_col."\<bar>" + endif let &ei= eikeep -" call Dret("NetRestorePosn") +" call Dret("netrw#NetRestorePosn") endfun " =============================== +" NetOptionSave: save options and set to "standard" form {{{2 +fun! s:NetOptionSave() +" call Dfunc("s:NetOptionSave()") + if !exists("w:netrw_optionsave") + let w:netrw_optionsave= 1 + else +" call Dret("s:NetOptionSave : netoptionsave=".w:netrw_optionsave) + return + endif + + " Save current settings and current directory + let s:yykeep = @@ + if exists("&l:acd") + let w:netrw_acdkeep = &l:acd + endif + let w:netrw_aikeep = &l:ai + let w:netrw_awkeep = &l:aw + let w:netrw_cikeep = &l:ci + let w:netrw_cinkeep = &l:cin + let w:netrw_cinokeep = &l:cino + let w:netrw_comkeep = &l:com + let w:netrw_cpokeep = &l:cpo + if g:netrw_keepdir + let w:netrw_dirkeep = getcwd() + endif + let w:netrw_fokeep = &l:fo " formatoptions + let w:netrw_gdkeep = &l:gd " gdefault + let w:netrw_hidkeep = &l:hidden + let w:netrw_magickeep = &l:magic + let w:netrw_repkeep = &l:report + let w:netrw_spellkeep = &l:spell + let w:netrw_twkeep = &l:tw " textwidth + let w:netrw_wigkeep = &l:wig " wildignore + if has("win32") && !has("win95") + let w:netrw_swfkeep= &l:swf " swapfile + endif + call s:NetrwSafeOptions() + if &go =~ 'a' | silent! let w:netrw_regstar = @* | endif + silent! let w:netrw_regslash= @/ + +" call Dret("s:NetOptionSave") +endfun + +" ------------------------------------------------------------------------ +" NetOptionRestore: restore options {{{2 +fun! s:NetOptionRestore() +" call Dfunc("s:NetOptionRestore()") + if !exists("w:netrw_optionsave") +" call Dret("s:NetOptionRestore : w:netrw_optionsave doesn't exist") + return + endif + unlet w:netrw_optionsave + + if exists("&acd") + if exists("w:netrw_acdkeep") |let &l:acd = w:netrw_acdkeep |unlet w:netrw_acdkeep |endif + endif + if exists("w:netrw_aikeep") |let &l:ai = w:netrw_aikeep |unlet w:netrw_aikeep |endif + if exists("w:netrw_awkeep") |let &l:aw = w:netrw_awkeep |unlet w:netrw_awkeep |endif + if exists("w:netrw_cikeep") |let &l:ci = w:netrw_cikeep |unlet w:netrw_cikeep |endif + if exists("w:netrw_cinkeep") |let &l:cin = w:netrw_cinkeep |unlet w:netrw_cinkeep |endif + if exists("w:netrw_cinokeep") |let &l:cino = w:netrw_cinokeep |unlet w:netrw_cinokeep |endif + if exists("w:netrw_comkeep") |let &l:com = w:netrw_comkeep |unlet w:netrw_comkeep |endif + if exists("w:netrw_cpokeep") |let &l:cpo = w:netrw_cpokeep |unlet w:netrw_cpokeep |endif + if exists("w:netrw_dirkeep") |exe "lcd ".w:netrw_dirkeep |unlet w:netrw_dirkeep |endif + if exists("w:netrw_fokeep") |let &l:fo = w:netrw_fokeep |unlet w:netrw_fokeep |endif + if exists("w:netrw_gdkeep") |let &l:gd = w:netrw_gdkeep |unlet w:netrw_gdkeep |endif + if exists("w:netrw_hidkeep") |let &l:hidden = w:netrw_hidkeep |unlet w:netrw_hidkeep |endif + if exists("w:netrw_magic") |let &l:magic = w:netrw_magic |unlet w:netrw_magic |endif + if exists("w:netrw_repkeep") |let &l:report = w:netrw_repkeep |unlet w:netrw_repkeep |endif + if exists("w:netrw_spellkeep")|let &l:spell = w:netrw_spellkeep |unlet w:netrw_spellkeep|endif + if exists("w:netrw_twkeep") |let &l:tw = w:netrw_twkeep |unlet w:netrw_twkeep |endif + if exists("w:netrw_wigkeep") |let &l:wig = w:netrw_wigkeep |unlet w:netrw_wigkeep |endif + if exists("s:yykeep") |let @@ = s:yykeep |unlet s:yykeep |endif + if exists("w:netrw_swfkeep") + if &directory == "" + " user hasn't specified a swapfile directory; + " netrw will temporarily set the swapfile directory + " to the current directory as returned by getcwd(). + let &l:directory = getcwd() + silent! let &l:swf = w:netrw_swfkeep + setlocal directory= + unlet w:netrw_swfkeep + elseif &l:swf != w:netrw_swfkeep + " following line causes a Press ENTER in windows -- can't seem to work around it!!! (COMBAK) + silent! let &l:swf= w:netrw_swfkeep + unlet w:netrw_swfkeep + endif + endif + if exists("w:netrw_regstar") |silent! let @*= w:netrw_regstar |unlet w:netrw_regstar |endif + if exists("w:netrw_regslash")|silent! let @/= w:netrw_regslash|unlet w:netrw_regslash|endif + +" call Dret("s:NetOptionRestore : restored user options") +endfun + +" --------------------------------------------------------------------- +" NetrwSafeOptions: sets options to help netrw do its job {{{2 +fun! s:NetrwSafeOptions() +" call Dfunc("s:NetrwSafeOptions()") + setlocal cino= + setlocal com= + setlocal cpo-=aA + if exists("&acd") + setlocal noacd nocin noai noci magic nospell nohid wig= noaw + setlocal fo=nroql2 + else + setlocal nocin noai noci magic nospell nohid wig= noaw + setlocal fo=nroql2 + endif + setlocal tw=0 + setlocal report=10000 + if g:netrw_use_noswf && has("win32") && !has("win95") + setlocal noswf + endif +" call Dret("s:NetrwSafeOptions") +endfun + +" ------------------------------------------------------------------------ " Netrw Transfer Functions: {{{1 " =============================== " ------------------------------------------------------------------------ " NetRead: responsible for reading a file over the net {{{2 +" mode: =0 read remote file and insert before current line +" =1 read remote file and insert after current line +" =2 replace with remote file +" =3 obtain file, but leave in temporary format fun! netrw#NetRead(mode,...) -" call Dfunc("NetRead(mode=".a:mode.",...) a:0=".a:0) +" call Dfunc("netrw#NetRead(mode=".a:mode.",...) a:0=".a:0." ".g:loaded_netrw) - " save options + " save options {{{3 call s:NetOptionSave() + " interpret mode into a readcmd {{{3 if a:mode == 0 " read remote file before current line let readcmd = "0r" elseif a:mode == 1 " read file after current line let readcmd = "r" elseif a:mode == 2 " replace with remote file let readcmd = "%r" + elseif a:mode == 3 " skip read of file (leave as temporary) + let readcmd = "t" else exe a:mode let readcmd = "r" @@ -320,18 +520,12 @@ fun! netrw#NetRead(mode,...) let ichoice = (a:0 == 0)? 0 : 1 " call Decho("readcmd<".readcmd."> ichoice=".ichoice) - " get name of a temporary file and set up shell-quoting character {{{3 - let tmpfile= tempname() -" call Decho("tmpfile<".tmpfile.">") - let tmpfile= escape(substitute(tmpfile,'\','/','ge'),g:netrw_tmpfile_escape) -" call Decho("tmpfile<".tmpfile.">") - if !isdirectory(substitute(tmpfile,'[^/]\+$','','e')) - echohl Error | echo "***netrw*** your <".substitute(tmpfile,'[^/]\+$','','e')."> directory is missing!" | echohl None - call inputsave()|call input("Press <cr> to continue")|call inputrestore() -" call Dret("NetRead :1 getcwd<".getcwd().">") + " Get Temporary Filename {{{3 + let tmpfile= s:GetTempfile("") + if tmpfile == "" +" call Dret("netrw#NetRead : unable to get a tempfile!") return endif -" call Decho("tmpfile<".tmpfile.">") while ichoice <= a:0 @@ -359,12 +553,13 @@ fun! netrw#NetRead(mode,...) echomsg ':Nread rsync://machine[:port]/path uses rsync' echomsg ':Nread scp://[user@]machine[[:#]port]/path uses scp' echomsg ':Nread sftp://[user@]machine[[:#]port]/path uses sftp' + sleep 4 break - elseif match(choice,"^\"") != -1 + elseif match(choice,'^"') != -1 " Reconstruct Choice if choice starts with '"' " call Decho("reconstructing choice") - if match(choice,"\"$") != -1 + if match(choice,'"$') != -1 " case "..." let choice=strpart(choice,1,strlen(choice)-2) else @@ -372,15 +567,14 @@ fun! netrw#NetRead(mode,...) let choice = strpart(choice,1,strlen(choice)-1) let wholechoice = "" - while match(choice,"\"$") == -1 + while match(choice,'"$') == -1 let wholechoice = wholechoice . " " . choice let ichoice = ichoice + 1 if ichoice > a:0 if !exists("g:netrw_quiet") - echohl Error | echo "***netrw*** Unbalanced string in filename '". wholechoice ."'" | echohl None - call inputsave()|call input("Press <cr> to continue")|call inputrestore() + call netrw#ErrorMsg(s:ERROR,"Unbalanced string in filename '". wholechoice ."'",3) endif -" call Dret("NetRead :2 getcwd<".getcwd().">") +" call Dret("netrw#NetRead :2 getcwd<".getcwd().">") return endif let choice= a:{ichoice} @@ -393,36 +587,19 @@ fun! netrw#NetRead(mode,...) " call Decho("choice<" . choice . ">") let ichoice= ichoice + 1 - " fix up windows urls - if has("win32") || has("win95") || has("win64") || has("win16") - let choice = substitute(choice,'\\','/','ge') -" call Decho("fixing up windows url to <".choice."> tmpfile<".tmpfile) - - if !g:netrw_keepdir - exe 'lcd ' . fnamemodify(tmpfile,':h') - endif - let tmpfile = fnamemodify(tmpfile,':t') - endif - " Determine method of read (ftp, rcp, etc) {{{3 call s:NetMethod(choice) + let tmpfile= s:GetTempfile(b:netrw_fname) " apply correct suffix " Check if NetBrowse() should be handling this request " call Decho("checking if NetBrowse() should handle choice<".choice."> with netrw_list_cmd<".g:netrw_list_cmd.">") - if choice =~ "^.*[\/]$" + if choice =~ "^.*[\/]$" && b:netrw_method != 5 && choice !~ '^http://' " call Decho("yes, choice matches '^.*[\/]$'") - keepjumps call s:NetBrowse(choice) -" call Dret("NetRead :3 getcwd<".getcwd().">") + keepjumps call s:NetBrowse(0,choice) +" call Dret("netrw#NetRead :3 getcwd<".getcwd().">") return endif - " use filename's suffix for the temporary file - if b:netrw_fname =~ '\.[^./]\+$' - let suffix = substitute(b:netrw_fname,'^.*\(\.[^./]\+\)$','\1','e') - let tmpfile= substitute(tmpfile,"$",suffix,'e') -" call Decho("chgd tmpfile<".tmpfile."> (added ".suffix." suffix) netrw_fname<".b:netrw_fname.">") - endif - " ============ " Perform Protocol-Based Read {{{3 " =========================== @@ -466,6 +643,10 @@ fun! netrw#NetRead(mode,...) setlocal ff=unix exe "put ='".g:netrw_ftpmode."'" " call Decho("filter input: ".getline(".")) + if exists("g:netrw_ftpextracmd") + exe "put ='".g:netrw_ftpextracmd."'" +" call Decho("filter input: ".getline(".")) + endif exe "put ='".'get \"'.netrw_fname.'\" '.tmpfile."'" " call Decho("filter input: ".getline(".")) if exists("g:netrw_port") && g:netrw_port != "" @@ -478,9 +659,8 @@ fun! netrw#NetRead(mode,...) " If the result of the ftp operation isn't blank, show an error message (tnx to Doug Claar) if getline(1) !~ "^$" && !exists("g:netrw_quiet") && getline(1) !~ '^Trying ' let debugkeep= &debug - set debug=msg - echohl Error | echo "***netrw*** ".getline(1) | echohl None - call inputsave()|call input("Press <cr> to continue")|call inputrestore() + setlocal debug=msg + call netrw#ErrorMsg(s:ERROR,getline(1),4) let &debug= debugkeep endif bd! @@ -517,8 +697,12 @@ fun! netrw#NetRead(mode,...) put =g:netrw_ftpmode " call Decho("filter input: ".getline(".")) endif - put ='get \"'.netrw_fname.'\" '.tmpfile + if exists("g:netrw_ftpextracmd") + exe "put ='".g:netrw_ftpextracmd."'" " call Decho("filter input: ".getline(".")) + endif + put ='get \"'.netrw_fname.'\" '.tmpfile +" call Decho("filter input: ".getline(".")) " perform ftp: " -i : turns off interactive prompting from ftp @@ -531,12 +715,11 @@ fun! netrw#NetRead(mode,...) if getline(1) !~ "^$" " call Decho("error<".getline(1).">") if !exists("g:netrw_quiet") - echohl Error | echo "***netrw*** ".getline(1) | echohl None - call inputsave()|call input("Press <cr> to continue")|call inputrestore() + call netrw#ErrorMsg(s:ERROR,getline(1),5) endif endif bd! - let result = s:NetGetFile(readcmd, tmpfile, b:netrw_method) + let result = s:NetGetFile(readcmd, tmpfile, b:netrw_method) let b:netrw_lastfile = choice "......................................... @@ -548,14 +731,8 @@ fun! netrw#NetRead(mode,...) else let useport= "" endif - if g:netrw_cygwin == 1 - let cygtmpfile=substitute(tmpfile,'^\(\a\):','/cygdrive/\1/','e') -" call Decho("executing: !".g:netrw_scp_cmd.useport." '".g:netrw_machine.":".escape(b:netrw_fname,g:netrw_fname_escape)."' ".cygtmpfile) - exe g:netrw_silentxfer."!".g:netrw_scp_cmd.useport." '".g:netrw_machine.":".escape(b:netrw_fname,g:netrw_fname_escape)."' ".cygtmpfile - else -" call Decho("executing: !".g:netrw_scp_cmd.useport." '".g:netrw_machine.":".escape(b:netrw_fname,g:netrw_fname_escape)."' ".tmpfile) - exe g:netrw_silentxfer."!".g:netrw_scp_cmd.useport." '".g:netrw_machine.":".escape(b:netrw_fname,g:netrw_fname_escape)."' ".tmpfile - endif +" call Decho("executing: !".g:netrw_scp_cmd.useport." '".g:netrw_machine.":".escape(b:netrw_fname,g:netrw_fname_escape)."' ".tmpfile) + exe g:netrw_silentxfer."!".g:netrw_scp_cmd.useport." ".g:netrw_shq.g:netrw_machine.":".escape(b:netrw_fname,g:netrw_fname_escape).g:netrw_shq." ".tmpfile let result = s:NetGetFile(readcmd, tmpfile, b:netrw_method) let b:netrw_lastfile = choice @@ -565,10 +742,9 @@ fun! netrw#NetRead(mode,...) " call Decho("read via http (method #5)") if g:netrw_http_cmd == "" if !exists("g:netrw_quiet") - echohl Error | echo "***netrw*** neither wget nor fetch command is available" | echohl None - call inputsave()|call input("Press <cr> to continue")|call inputrestore() + call netrw#ErrorMsg(s:ERROR,"neither the wget nor the fetch command is available",6) endif -" call Dret("NetRead :4 getcwd<".getcwd().">") +" call Dret("netrw#NetRead :4 getcwd<".getcwd().">") return endif @@ -592,6 +768,7 @@ fun! netrw#NetRead(mode,...) exe 'norm! 1G/<\s*a\s*name=\s*"'.netrw_tag.'"/'."\<CR>" endif let b:netrw_lastfile = choice + setlocal ro "......................................... " cadaver: NetRead Method #6 {{{3 @@ -608,13 +785,7 @@ fun! netrw#NetRead(mode,...) put ='open '.g:netrw_machine endif put ='user '.g:netrw_uid.' '.g:netrw_passwd - - if g:netrw_cygwin == 1 - let cygtmpfile=substitute(tmpfile,'^\(\a\):','/cygdrive/\1/','e') - put ='get '.netrw_fname.' '.cygtmpfile - else - put ='get '.netrw_fname.' '.tmpfile - endif + put ='get '.netrw_fname.' '.tmpfile put ='quit' " perform cadaver operation: @@ -630,14 +801,8 @@ fun! netrw#NetRead(mode,...) elseif b:netrw_method == 7 " call Decho("read via rsync (method #7)") let netrw_fname= escape(b:netrw_fname,g:netrw_fname_escape) - if g:netrw_cygwin == 1 - let cygtmpfile=substitute(tmpfile,'^\(\a\):','/cygdrive/\1/','e') -" call Decho("executing: !".g:netrw_rsync_cmd." ".g:netrw_machine.":".netrw_fname." ".cygtmpfile) - exe g:netrw_silentxfer."!".g:netrw_rsync_cmd." ".g:netrw_machine.":".netrw_fname." ".cygtmpfile - else -" call Decho("executing: !".g:netrw_rsync_cmd." ".g:netrw_machine.":".netrw_fname." ".tmpfile) - exe g:netrw_silentxfer."!".g:netrw_rsync_cmd." ".g:netrw_machine.":".netrw_fname." ".tmpfile - endif +" call Decho("executing: !".g:netrw_rsync_cmd." ".g:netrw_machine.":".netrw_fname." ".tmpfile) + exe g:netrw_silentxfer."!".g:netrw_rsync_cmd." ".g:netrw_machine.":".netrw_fname." ".tmpfile let result = s:NetGetFile(readcmd,tmpfile, b:netrw_method) let b:netrw_lastfile = choice @@ -645,11 +810,11 @@ fun! netrw#NetRead(mode,...) " fetch: NetRead Method #8 {{{3 " fetch://[user@]host[:http]/path elseif b:netrw_method == 8 +" call Decho("read via fetch (method #8)") let netrw_fname= escape(b:netrw_fname,g:netrw_fname_escape) if g:netrw_fetch_cmd == "" if !exists("g:netrw_quiet") - echohl Error | echo "***netrw*** fetch command not available" | echohl None - call inputsave()|call input("Press <cr> to continue")|call inputrestore() + call netrw#ErrorMsg(s:ERROR,"fetch command not available",7) endif " call Dret("NetRead") endif @@ -670,154 +835,53 @@ fun! netrw#NetRead(mode,...) let result = s:NetGetFile(readcmd,tmpfile, b:netrw_method) let b:netrw_lastfile = choice + setlocal ro "......................................... " sftp: NetRead Method #9 {{{3 elseif b:netrw_method == 9 -" call Decho("read via sftp (method #4)") +" call Decho("read via sftp (method #9)") let netrw_fname= escape(b:netrw_fname,g:netrw_fname_escape) - if g:netrw_cygwin == 1 - let cygtmpfile=substitute(tmpfile,'^\(\a\):','/cygdrive/\1/','e') -" call Decho("!".g:netrw_sftp_cmd." ".g:netrw_machine.":".netrw_fname." ".cygtmpfile) -" call Decho("executing: !".g:netrw_sftp_cmd." ".g:netrw_machine.":".netrw_fname." ".cygtmpfile) - exe "!".g:netrw_sftp_cmd." ".g:netrw_machine.":".netrw_fname." ".cygtmpfile - else -" call Decho("executing: !".g:netrw_sftp_cmd." ".g:netrw_machine.":".netrw_fname." ".tmpfile) - exe g:netrw_silentxfer."!".g:netrw_sftp_cmd." ".g:netrw_machine.":".netrw_fname." ".tmpfile - endif +" call Decho("executing: !".g:netrw_sftp_cmd." ".g:netrw_machine.":".netrw_fname." ".tmpfile) + exe g:netrw_silentxfer."!".g:netrw_sftp_cmd." ".g:netrw_machine.":".netrw_fname." ".tmpfile let result = s:NetGetFile(readcmd, tmpfile, b:netrw_method) let b:netrw_lastfile = choice "......................................... " Complain {{{3 else - echo "***warning*** unable to comply with your request<" . choice . ">" + call netrw#ErrorMsg(s:WARNING,"unable to comply with your request<" . choice . ">",8) endif endwhile " cleanup {{{3 -" call Decho("cleanup") if exists("b:netrw_method") +" call Decho("cleanup b:netrw_method and b:netrw_fname") unlet b:netrw_method unlet b:netrw_fname endif - call s:NetOptionRestore() - -" call Dret("NetRead :5 getcwd<".getcwd().">") -endfun - -" ------------------------------------------------------------------------ -" NetGetFile: Function to read temporary file "tfile" with command "readcmd". {{{2 -" readcmd == %r : replace buffer with newly read file -" == 0r : read file at top of buffer -" == r : read file after current line -fun! s:NetGetFile(readcmd, tfile, method) -" call Dfunc("NetGetFile(readcmd<".a:readcmd.">,tfile<".a:tfile."> method<".a:method.">)") - - " get name of remote filename (ie. url and all) - let rfile= bufname("%") -" call Decho("rfile<".rfile.">") - - if exists("*NetReadFixup") - " for the use of NetReadFixup (not otherwise used internally) - let line2= line("$") + if s:FileReadable(tmpfile) && tmpfile !~ '.tar.bz2$' && tmpfile !~ '.tar.gz$' && tmpfile !~ '.zip' && tmpfile !~ '.tar' && readcmd != 't' +" call Decho("cleanup by deleting tmpfile<".tmpfile.">") + call s:System("delete",tmpfile) endif + call s:NetOptionRestore() - " transform paths from / to \ for Windows (except for cygwin) - if &term == "win32" - if g:netrw_cygwin - let tfile= a:tfile -" call Decho("(win32 && cygwin) tfile<".tfile.">") - else - let tfile= substitute(a:tfile,'/','\\\\','ge') -" call Decho("(win32 && !cygwin) tfile<".tfile.">") - endif - else - let tfile= a:tfile -" call Decho("tfile=a:tfile<".tfile.">") - endif - - if a:readcmd[0] == '%' - " get file into buffer - -" call Dredir("ls!","starting buffer list") - - " rename the current buffer to the temp file (ie. tfile) - keepalt exe "file ".tfile -" call Dredir("ls!","after renaming current buffer to <".tfile.">") - - " edit temporary file (ie. read the temporary file in) - if rfile =~ '\.zip$' - call zip#Browse(tfile) - elseif rfile =~ '\.tar$' - call tar#Browse(tfile) - else -" call Decho("edit temporary file") - e - endif - - " rename buffer back to remote filename - keepalt exe "file ".escape(rfile,' ') - filetype detect -" call Dredir("ls!","renamed buffer back to remote filename<".rfile."> : expand(%)<".expand("%").">") - let line1 = 1 - let line2 = line("$") - - elseif filereadable(tfile) - " read file after current line - let curline = line(".") - let lastline= line("$") -" call Decho("exe<".a:readcmd." ".v:cmdarg." ".tfile."> line#".curline) - exe a:readcmd." ".v:cmdarg." ".tfile - let line1= curline + 1 - let line2= line("$") - lastline + 1 - - else - " not readable - echohl WarningMsg | echo "***netrw*** file <".tfile."> not readable"| echohl None - call inputsave()|call input("Press <cr> to continue")|call inputrestore() -" call Dret("NetGetFile : tfile<".tfile."> not readable") - return - endif - - " User-provided (ie. optional) fix-it-up command - if exists("*NetReadFixup") -" call Decho("calling NetReadFixup(method<".a:method."> line1=".line1." line2=".line2.")") - call NetReadFixup(a:method, line1, line2) -" else " Decho -" call Decho("NetReadFixup() not called, doesn't exist (line1=".line1." line2=".line2.")") - endif - - " update the Buffers menu - if has("gui") && has("gui_running") - silent! emenu Buffers.Refresh\ menu - endif - -" call Decho("readcmd<".a:readcmd."> cmdarg<".v:cmdarg."> tfile<".a:tfile."> readable=".filereadable(a:tfile)) - - " make sure file is being displayed - redraw! -" call Dret("NetGetFile") +" call Dret("netrw#NetRead :5 getcwd<".getcwd().">") endfun " ------------------------------------------------------------------------ " NetWrite: responsible for writing a file over the net {{{2 fun! netrw#NetWrite(...) range -" call Dfunc("NetWrite(a:0=".a:0.")") +" call Dfunc("netrw#NetWrite(a:0=".a:0.") ".g:loaded_netrw) " option handling let mod= 0 call s:NetOptionSave() " Get Temporary Filename {{{3 - let tmpfile= tempname() -" call Decho("tmpfile<".tmpfile."> (raw)") - let tmpfile= escape(substitute(tmpfile,'\','/','ge'),g:netrw_tmpfile_escape) -" call Decho("tmpfile<".tmpfile."> (escaped)") - if !isdirectory(substitute(tmpfile,'[^/]\+$','','e')) - echohl Error | echo "***netrw*** your <".substitute(tmpfile,'[^/]\+$','','e')."> directory is missing!" - call inputsave()|call input("Press <cr> to continue")|call inputrestore() -" call Dret("NetWrite") + let tmpfile= s:GetTempfile("") + if tmpfile == "" +" call Dret("netrw#NetWrite : unable to get a tempfile!") return endif @@ -827,20 +891,36 @@ fun! netrw#NetWrite(...) range let ichoice = 1 endif + let curbufname= expand("%") +" call Decho("curbufname<".curbufname.">") if &binary - " for binary writes, write entire file. Line numbers don't really make sense. - " Supports the writing of tar and zip files. -" call Decho("silent exe w! ".v:cmdarg." ".tmpfile) + " For binary writes, always write entire file. + " (line numbers don't really make sense for that). + " Also supports the writing of tar and zip files. +" call Decho("(write entire file) silent exe w! ".v:cmdarg." ".tmpfile) silent exe "w! ".v:cmdarg." ".tmpfile + elseif g:netrw_cygwin + " write (selected portion of) file to temporary + let cygtmpfile= substitute(tmpfile,'/cygdrive/\(.\)','\1:','') +" call Decho("(write selected portion) silent exe ".a:firstline."," . a:lastline . "w! ".v:cmdarg." ".cygtmpfile) + silent exe a:firstline."," . a:lastline . "w! ".v:cmdarg." ".cygtmpfile else " write (selected portion of) file to temporary -" call Decho("silent exe ".a:firstline."," . a:lastline . "w! ".v:cmdarg." ".tmpfile) +" call Decho("(write selected portion) silent exe ".a:firstline."," . a:lastline . "w! ".v:cmdarg." ".tmpfile) silent exe a:firstline."," . a:lastline . "w! ".v:cmdarg." ".tmpfile endif + if curbufname == "" + " if the file is [No Name], and one attempts to Nwrite it, the buffer takes + " on the temporary file's name. Deletion of the temporary file during + " cleanup then causes an error message. + 0file! + endif + + " While choice loop: {{{3 while ichoice <= a:0 - " Process arguments: {{{3 + " Process arguments: {{{4 " attempt to repeat with previous host-file-etc if exists("b:netrw_lastfile") && a:0 == 0 " call Decho("using b:netrw_lastfile<" . b:netrw_lastfile . ">") @@ -862,6 +942,7 @@ fun! netrw#NetWrite(...) range echomsg ':Nwrite rsync://[user@]machine/path uses rsync' echomsg ':Nwrite scp://[user@]machine[[:#]port]/path uses scp' echomsg ':Nwrite sftp://[user@]machine/path uses sftp' + sleep 4 break elseif match(choice,"^\"") != -1 @@ -878,10 +959,9 @@ fun! netrw#NetWrite(...) range let ichoice = ichoice + 1 if choice > a:0 if !exists("g:netrw_quiet") - echohl Error | echo "***netrw*** Unbalanced string in filename '". wholechoice ."'" | echohl None - call inputsave()|call input("Press <cr> to continue")|call inputrestore() + call netrw#ErrorMsg(s:ERROR,"Unbalanced string in filename '". wholechoice ."'",13) endif -" call Dret("NetWrite") +" call Dret("netrw#NetWrite") return endif let choice= a:{ichoice} @@ -890,30 +970,21 @@ fun! netrw#NetWrite(...) range endif endif endif -" call Decho("choice<" . choice . ">") let ichoice= ichoice + 1 +" call Decho("choice<" . choice . "> ichoice=".ichoice) - " fix up windows urls - if has("win32") || has("win95") || has("win64") || has("win16") - let choice= substitute(choice,'\\','/','ge') - if !g:netrw_keepdir - exe 'lcd ' . fnamemodify(tmpfile,':h') - endif - let tmpfile = fnamemodify(tmpfile,':t') - endif - - " Determine method of read (ftp, rcp, etc) {{{3 + " Determine method of write (ftp, rcp, etc) {{{4 call s:NetMethod(choice) " ============= - " Perform Protocol-Based Write {{{3 + " Perform Protocol-Based Write {{{4 " ============================ if exists("g:netrw_silent") && g:netrw_silent == 0 && &ch >= 1 echo "(netrw) Processing your write request..." endif "......................................... - " rcp: NetWrite Method #1 {{{3 + " rcp: NetWrite Method #1 {{{4 if b:netrw_method == 1 " call Decho("write via rcp (method #1)") if s:netrw_has_nt_rcp == 1 @@ -930,19 +1001,24 @@ fun! netrw#NetWrite(...) range endif endif let netrw_fname= escape(b:netrw_fname,g:netrw_fname_escape) -" call Decho("executing: !".g:netrw_rcp_cmd." ".s:netrw_rcpmode." ".tmpfile." ".uid_machine.":".netrw_fname) - exe g:netrw_silentxfer."!".g:netrw_rcp_cmd." ".s:netrw_rcpmode." ".tmpfile." ".uid_machine.":".netrw_fname +" call Decho("executing: !".g:netrw_rcp_cmd." ".s:netrw_rcpmode." ".g:netrw_shq.tmpfile.g:netrw_shq." ".uid_machine.":".netrw_fname) + exe g:netrw_silentxfer."!".g:netrw_rcp_cmd." ".s:netrw_rcpmode." ".g:netrw_shq.tmpfile.g:netrw_shq." ".uid_machine.":".netrw_fname let b:netrw_lastfile = choice "......................................... - " ftp + <.netrc>: NetWrite Method #2 {{{3 + " ftp + <.netrc>: NetWrite Method #2 {{{4 elseif b:netrw_method == 2 +" call Decho("write via ftp+.netrc (method #2)") let netrw_fname= b:netrw_fname new setlocal ff=unix exe "put ='".g:netrw_ftpmode."'" " call Decho(" filter input: ".getline(".")) - exe "put ='"."put ".tmpfile.' \"'.netrw_fname.'\"'."'" + if exists("g:netrw_ftpextracmd") + exe "put ='".g:netrw_ftpextracmd."'" +" call Decho("filter input: ".getline(".")) + endif + exe "put ='".'put \"'.tmpfile.'\" \"'.netrw_fname.'\"'."'" " call Decho(" filter input: ".getline(".")) if exists("g:netrw_port") && g:netrw_port != "" " call Decho("executing: %!".g:netrw_ftp_cmd." -i ".g:netrw_machine." ".g:netrw_port) @@ -954,8 +1030,7 @@ fun! netrw#NetWrite(...) range " If the result of the ftp operation isn't blank, show an error message (tnx to Doug Claar) if getline(1) !~ "^$" if !exists("g:netrw_quiet") - echohl Error | echo "***netrw*** ".getline(1) | echohl None - call inputsave()|call input("Press <cr> to continue")|call inputrestore() + call netrw#ErrorMsg(s:ERROR,getline(1),14) endif let mod=1 endif @@ -963,8 +1038,10 @@ fun! netrw#NetWrite(...) range let b:netrw_lastfile = choice "......................................... - " ftp + machine, id, passwd, filename: NetWrite Method #3 {{{3 + " ftp + machine, id, passwd, filename: NetWrite Method #3 {{{4 elseif b:netrw_method == 3 + " Construct execution string (four lines) which will be passed through filter +" call Decho("read via ftp+mipf (method #3)") let netrw_fname= b:netrw_fname new setlocal ff=unix @@ -984,7 +1061,7 @@ fun! netrw#NetWrite(...) range put ='user \"'.g:netrw_uid.'\" \"'.g:netrw_passwd.'\"' " call Decho("filter input: ".getline(".")) endif - put ='put '.tmpfile.' \"'.netrw_fname.'\"' + put ='put \"'.tmpfile.'\" \"'.netrw_fname.'\"' " call Decho("filter input: ".getline(".")) " save choice/id/password for future use let b:netrw_lastfile = choice @@ -999,42 +1076,36 @@ fun! netrw#NetWrite(...) range " If the result of the ftp operation isn't blank, show an error message (tnx to Doug Claar) if getline(1) !~ "^$" if !exists("g:netrw_quiet") - echohl Error | echo "***netrw*** ".getline(1) | echohl None - call inputsave()|call input("Press <cr> to continue")|call inputrestore() + call netrw#ErrorMsg(s:ERROR,getline(1),15) endif let mod=1 endif bd! "......................................... - " scp: NetWrite Method #4 {{{3 + " scp: NetWrite Method #4 {{{4 elseif b:netrw_method == 4 +" call Decho("write via scp (method #4)") let netrw_fname= escape(b:netrw_fname,g:netrw_fname_escape) if exists("g:netrw_port") && g:netrw_port != "" let useport= " -P ".g:netrw_port else let useport= "" endif - if g:netrw_cygwin == 1 - let cygtmpfile=substitute(tmpfile,'^\(\a\):','/cygdrive/\1/','e') -" call Decho("executing: !".g:netrw_scp_cmd.useport." ".cygtmpfile." '".g:netrw_machine.":".netrw_fname."'") - exe g:netrw_silentxfer."!".g:netrw_scp_cmd.useport." ".cygtmpfile." '".g:netrw_machine.":".netrw_fname."'" - else -" call Decho("executing: !".g:netrw_scp_cmd.useport." ".tmpfile." '".g:netrw_machine.":".netrw_fname."'") - exe g:netrw_silentxfer."!".g:netrw_scp_cmd.useport." ".tmpfile." '".g:netrw_machine.":".netrw_fname."'" - endif +" call Decho("exe ".g:netrw_silentxfer."!".g:netrw_scp_cmd.useport." ".g:netrw_shq.tmpfile.g:netrw_shq." ".g:netrw_shq.g:netrw_machine.":".netrw_fname.g:netrw_shq) + exe g:netrw_silentxfer."!".g:netrw_scp_cmd.useport." ".g:netrw_shq.tmpfile.g:netrw_shq." ".g:netrw_shq.g:netrw_machine.":".netrw_fname.g:netrw_shq let b:netrw_lastfile = choice "......................................... - " http: NetWrite Method #5 {{{3 + " http: NetWrite Method #5 {{{4 elseif b:netrw_method == 5 +" call Decho("write via http (method #5)") if !exists("g:netrw_quiet") - echohl Error | echo "***netrw*** currently <netrw.vim> does not support writing using http:" | echohl None - call inputsave()|call input("Press <cr> to continue")|call inputrestore() + call netrw#ErrorMsg(s:ERROR,"currently <netrw.vim> does not support writing using http:",16) endif "......................................... - " dav: NetWrite Method #6 (cadaver) {{{3 + " dav: NetWrite Method #6 (cadaver) {{{4 elseif b:netrw_method == 6 " call Decho("write via cadaver (method #6)") @@ -1048,13 +1119,7 @@ fun! netrw#NetWrite(...) range put ='open '.g:netrw_machine endif put ='user '.g:netrw_uid.' '.g:netrw_passwd - - if g:netrw_cygwin == 1 - let cygtmpfile=substitute(tmpfile,'^\(\a\):','/cygdrive/\1/','e') - put ='put '.cygtmpfile.' '.netrw_fname - else - put ='put '.tmpfile.' '.netrw_fname - endif + put ='put '.tmpfile.' '.netrw_fname " perform cadaver operation: norm! 1Gdd @@ -1064,22 +1129,18 @@ fun! netrw#NetWrite(...) range let b:netrw_lastfile = choice "......................................... - " rsync: NetWrite Method #7 {{{3 + " rsync: NetWrite Method #7 {{{4 elseif b:netrw_method == 7 +" call Decho("write via rsync (method #7)") let netrw_fname= escape(b:netrw_fname,g:netrw_fname_escape) - if g:netrw_cygwin == 1 - let cygtmpfile=substitute(tmpfile,'^\(\a\):','/cygdrive/\1/','e') -" call Decho("executing: !".g:netrw_rsync_cmd." ".cygtmpfile." ".g:netrw_machine.":".netrw_fname) - exe g:netrw_silentxfer."!".g:netrw_rsync_cmd." ".cygtmpfile." ".g:netrw_machine.":".netrw_fname - else -" call Decho("executing: !".g:netrw_rsync_cmd." ".tmpfile." ".g:netrw_machine.":".netrw_fname) - exe g:netrw_silentxfer."!".g:netrw_rsync_cmd." ".tmpfile." ".g:netrw_machine.":".netrw_fname - endif +" call Decho("executing: !".g:netrw_rsync_cmd." ".tmpfile." ".g:netrw_machine.":".netrw_fname) + exe g:netrw_silentxfer."!".g:netrw_rsync_cmd." ".tmpfile." ".g:netrw_machine.":".netrw_fname let b:netrw_lastfile = choice "......................................... - " sftp: NetWrite Method #9 {{{3 + " sftp: NetWrite Method #9 {{{4 elseif b:netrw_method == 9 +" call Decho("read via sftp (method #9)") let netrw_fname= escape(b:netrw_fname,g:netrw_fname_escape) if exists("g:netrw_uid") && ( g:netrw_uid != "" ) let uid_machine = g:netrw_uid .'@'. g:netrw_machine @@ -1088,7 +1149,8 @@ fun! netrw#NetWrite(...) range endif new setlocal ff=unix - put ='put '.tmpfile.' '.netrw_fname + put ='put \"'.escape(tmpfile,'\').'\" '.netrw_fname +" call Decho("filter input: ".getline(".")) norm! 1Gdd " call Decho("executing: %!".g:netrw_sftp_cmd.' '.uid_machine) exe g:netrw_silentxfer."%!".g:netrw_sftp_cmd.' '.uid_machine @@ -1096,266 +1158,845 @@ fun! netrw#NetWrite(...) range let b:netrw_lastfile= choice "......................................... - " Complain {{{3 + " Complain {{{4 else - echo "***warning*** unable to comply with your request<" . choice . ">" + call netrw#ErrorMsg(s:WARNING,"unable to comply with your request<" . choice . ">",17) endif endwhile - " cleanup {{{3 + " Cleanup: {{{3 " call Decho("cleanup") - let result=delete(tmpfile) + if s:FileReadable(tmpfile) +" call Decho("tmpfile<".tmpfile."> readable, will now delete it") + call s:System("delete",tmpfile) + endif call s:NetOptionRestore() if a:firstline == 1 && a:lastline == line("$") - let &mod= mod " usually equivalent to set nomod + " restore modifiability; usually equivalent to set nomod + let &mod= mod endif -" call Dret("NetWrite") +" call Dret("netrw#NetWrite") endfun -" =========================================== -" Remote Directory Browsing Support: {{{1 -" =========================================== - " --------------------------------------------------------------------- -" NetBrowse: This function uses the command in g:netrw_list_cmd to get a list {{{2 -" of the contents of a remote directory. It is assumed that the -" g:netrw_list_cmd has a string, HOSTNAME, that needs to be substituted -" with the requested remote hostname first. -fun! s:NetBrowse(dirname) - if !exists("w:netrw_longlist")|let w:netrw_longlist= g:netrw_longlist|endif -" call Dfunc("NetBrowse(dirname<".a:dirname.">) longlist=".w:netrw_longlist) +" NetSource: source a remotely hosted vim script {{{2 +" uses NetRead to get a copy of the file into a temporarily file, +" then sources that file, +" then removes that file. +fun! netrw#NetSource(...) +" call Dfunc("netrw#NetSource() a:0=".a:0) + if a:0 > 0 && a:1 == '?' + " give help + echomsg 'NetSource Usage:' + echomsg ':Nsource dav://machine[:port]/path uses cadaver' + echomsg ':Nsource fetch://machine/path uses fetch' + echomsg ':Nsource ftp://[user@]machine[:port]/path uses ftp autodetects <.netrc>' + echomsg ':Nsource http://[user@]machine/path uses http wget' + echomsg ':Nsource rcp://[user@]machine/path uses rcp' + echomsg ':Nsource rsync://machine[:port]/path uses rsync' + echomsg ':Nsource scp://[user@]machine[[:#]port]/path uses scp' + echomsg ':Nsource sftp://[user@]machine[[:#]port]/path uses sftp' + sleep 4 + else + let i= 1 + while i <= a:0 + call netrw#NetRead(3,a:{i}) +" call Decho("s:netread_tmpfile<".s:netrw_tmpfile.">") + if s:FileReadable(s:netrw_tmpfile) +" call Decho("exe so ".s:netrw_tmpfile) + exe "so ".s:netrw_tmpfile + call delete(s:netrw_tmpfile) + unlet s:netrw_tmpfile + else + call netrw#ErrorMsg(s:ERROR,"unable to source <".a:{i}.">!",48) + endif + let i= i + 1 + endwhile + endif +" call Dret("netrw#NetSource") +endfun - if exists("s:netrw_skipbrowse") - unlet s:netrw_skipbrowse -" call Dret("NetBrowse") +" =========================================== +" NetGetFile: Function to read temporary file "tfile" with command "readcmd". {{{2 +" readcmd == %r : replace buffer with newly read file +" == 0r : read file at top of buffer +" == r : read file after current line +" == t : leave file in temporary form (ie. don't read into buffer) +fun! s:NetGetFile(readcmd, tfile, method) +" call Dfunc("NetGetFile(readcmd<".a:readcmd.">,tfile<".a:tfile."> method<".a:method.">)") + + " readcmd=='t': simply do nothing + if a:readcmd == 't' +" call Dret("NetGetFile : skip read of <".a:tfile.">") return endif - call s:NetOptionSave() + " get name of remote filename (ie. url and all) + let rfile= bufname("%") +" call Decho("rfile<".rfile.">") - " sanity check - if exists("b:netrw_method") && b:netrw_method =~ '[235]' -" call Decho("b:netrw_method=".b:netrw_method) - if !executable("ftp") - if !exists("g:netrw_quiet") - echohl Error | echo "***netrw*** this system doesn't support remote directory listing via ftp" | echohl None - call inputsave()|call input("Press <cr> to continue")|call inputrestore() - endif - call s:NetOptionRestore() -" call Dret("NetBrowse") - return + if exists("*NetReadFixup") + " for the use of NetReadFixup (not otherwise used internally) + let line2= line("$") + endif + + if a:readcmd[0] == '%' + " get file into buffer +" call Decho("get file into buffer") + + " rename the current buffer to the temp file (ie. tfile) + if g:netrw_cygwin + let tfile= substitute(a:tfile,'/cygdrive/\(.\)','\1:','') + else + let tfile= a:tfile endif - elseif !exists("g:netrw_list_cmd") || g:netrw_list_cmd == '' - if !exists("g:netrw_quiet") - echohl Error | echo "***netrw*** this system doesn't support remote directory listing via ".g:netrw_list_cmd | echohl None - call inputsave()|call input("Press <cr> to continue")|call inputrestore() +" call Decho("keepalt exe file ".tfile) + keepalt exe "silent! keepalt file ".tfile + + " edit temporary file (ie. read the temporary file in) + if rfile =~ '\.zip$' +" call Decho("handling remote zip file with zip#Browse(tfile<".tfile.">)") + call zip#Browse(tfile) + elseif rfile =~ '\.tar$' +" call Decho("handling remote tar file with tar#Browse(tfile<".tfile.">)") + call tar#Browse(tfile) + elseif rfile =~ '\.tar\.gz' +" call Decho("handling remote gzip-compressed tar file") + call tar#Browse(tfile) + elseif rfile =~ '\.tar\.bz2' +" call Decho("handling remote bz2-compressed tar file") + call tar#Browse(tfile) + else +" call Decho("edit temporary file") + e! endif - call s:NetOptionRestore() -" call Dret("NetBrowse") + " rename buffer back to remote filename + exe "silent! keepalt file ".escape(rfile,' ') + filetype detect +" call Dredir("renamed buffer back to remote filename<".rfile."> : expand(%)<".expand("%").">","ls!") + let line1 = 1 + let line2 = line("$") + + elseif s:FileReadable(a:tfile) + " read file after current line +" call Decho("read file<".a:tfile."> after current line") + let curline = line(".") + let lastline= line("$") +" call Decho("exe<".a:readcmd." ".v:cmdarg." ".a:tfile."> line#".curline) + exe a:readcmd." ".v:cmdarg." ".a:tfile + let line1= curline + 1 + let line2= line("$") - lastline + 1 + + else + " not readable +" call Decho("tfile<".a:tfile."> not readable") + call netrw#ErrorMsg(s:WARNING,"file <".a:tfile."> not readable",9) +" call Dret("NetGetFile : tfile<".a:tfile."> not readable") return endif - " use buffer-oriented WinVars if buffer ones exist but window ones don't - call s:UseBufWinVars() + " User-provided (ie. optional) fix-it-up command + if exists("*NetReadFixup") +" call Decho("calling NetReadFixup(method<".a:method."> line1=".line1." line2=".line2.")") + call NetReadFixup(a:method, line1, line2) +" else " Decho +" call Decho("NetReadFixup() not called, doesn't exist (line1=".line1." line2=".line2.")") + endif - " set up menus - let b:netrw_browser_active= 1 - call s:NetMenu(1) + " update the Buffers menu + if has("gui") && has("gui_running") + silent! emenu Buffers.Refresh\ menu + endif - " make this buffer modifiable - setlocal ma nonu nowrap +" call Decho("readcmd<".a:readcmd."> cmdarg<".v:cmdarg."> tfile<".a:tfile."> readable=".s:FileReadable(a:tfile)) - " analyze a:dirname and g:netrw_list_cmd - let dirpat = '^\(\w\{-}\)://\(\w\+@\)\=\([^/]\+\)/\(.*\)$' - let dirname = substitute(a:dirname,'\\','/','ge') -" call Decho("dirname<".dirname.">") - if dirname !~ dirpat - if !exists("g:netrw_quiet") - echohl Error | echo "***netrw*** netrw doesn't understand your dirname<".dirname.">" | echohl None - call inputsave()|call input("Press <cr> to continue")|call inputrestore() + " make sure file is being displayed + redraw! +" call Dret("NetGetFile") +endfun + +" ------------------------------------------------------------------------ +" NetMethod: determine method of transfer {{{2 +" method == 1: rcp +" 2: ftp + <.netrc> +" 3: ftp + machine, id, password, and [path]filename +" 4: scp +" 5: http (wget) +" 6: cadaver +" 7: rsync +" 8: fetch +" 9: sftp +fun! s:NetMethod(choice) " globals: method machine id passwd fname +" call Dfunc("NetMethod(a:choice<".a:choice.">)") + + " initialization + let b:netrw_method = 0 + let g:netrw_machine = "" + let b:netrw_fname = "" + let g:netrw_port = "" + let g:netrw_choice = a:choice + + " Patterns: + " mipf : a:machine a:id password filename Use ftp + " mf : a:machine filename Use ftp + <.netrc> or g:netrw_uid g:netrw_passwd + " ftpurm : ftp://[user@]host[[#:]port]/filename Use ftp + <.netrc> or g:netrw_uid g:netrw_passwd + " rcpurm : rcp://[user@]host/filename Use rcp + " rcphf : [user@]host:filename Use rcp + " scpurm : scp://[user@]host[[#:]port]/filename Use scp + " httpurm : http://[user@]host/filename Use wget + " davurm : [s]dav://host[:port]/path Use cadaver + " rsyncurm : rsync://host[:port]/path Use rsync + " fetchurm : fetch://[user@]host[:http]/filename Use fetch (defaults to ftp, override for http) + " sftpurm : sftp://[user@]host/filename Use scp + let mipf = '^\(\S\+\)\s\+\(\S\+\)\s\+\(\S\+\)\s\+\(\S\+\)$' + let mf = '^\(\S\+\)\s\+\(\S\+\)$' + let ftpurm = '^ftp://\(\([^/@]\{-}\)@\)\=\([^/#:]\{-}\)\([#:]\d\+\)\=/\(.*\)$' + let rcpurm = '^rcp://\%(\([^/@]\{-}\)@\)\=\([^/]\{-}\)/\(.*\)$' + let rcphf = '^\(\(\h\w*\)@\)\=\(\h\w*\):\([^@]\+\)$' + let scpurm = '^scp://\([^/#:]\+\)\%([#:]\(\d\+\)\)\=/\(.*\)$' + let httpurm = '^http://\([^/]\{-}\)\(/.*\)\=$' + let davurm = '^s\=dav://\([^/]\+\)/\(.*/\)\([-_.~[:alnum:]]\+\)$' + let rsyncurm = '^rsync://\([^/]\{-}\)/\(.*\)\=$' + let fetchurm = '^fetch://\(\([^/@]\{-}\)@\)\=\([^/#:]\{-}\)\(:http\)\=/\(.*\)$' + let sftpurm = '^sftp://\([^/]\{-}\)/\(.*\)\=$' + +" call Decho("determine method:") + " Determine Method + " rcp://user@hostname/...path-to-file + if match(a:choice,rcpurm) == 0 +" call Decho("rcp://...") + let b:netrw_method = 1 + let userid = substitute(a:choice,rcpurm,'\1',"") + let g:netrw_machine = substitute(a:choice,rcpurm,'\2',"") + let b:netrw_fname = substitute(a:choice,rcpurm,'\3',"") + if userid != "" + let g:netrw_uid= userid endif - call s:NetOptionRestore() -" call Dret("NetBrowse : badly formatted dirname<".dirname.">") - return - endif - let method = substitute(dirname,dirpat,'\1','') - let user = substitute(dirname,dirpat,'\2','') - let machine = substitute(dirname,dirpat,'\3','') - let path = substitute(dirname,dirpat,'\4','') - let fname = substitute(dirname,'^.*/\ze.','','') -" call Decho("set up method <".method .">") -" call Decho("set up user <".user .">") -" call Decho("set up machine<".machine.">") -" call Decho("set up path <".path .">") -" call Decho("set up fname <".fname .">") + " scp://user@hostname/...path-to-file + elseif match(a:choice,scpurm) == 0 +" call Decho("scp://...") + let b:netrw_method = 4 + let g:netrw_machine = substitute(a:choice,scpurm,'\1',"") + let g:netrw_port = substitute(a:choice,scpurm,'\2',"") + let b:netrw_fname = substitute(a:choice,scpurm,'\3',"") + + " http://user@hostname/...path-to-file + elseif match(a:choice,httpurm) == 0 +" call Decho("http://...") + let b:netrw_method = 5 + let g:netrw_machine= substitute(a:choice,httpurm,'\1',"") + let b:netrw_fname = substitute(a:choice,httpurm,'\2',"") + + " dav://hostname[:port]/..path-to-file.. + elseif match(a:choice,davurm) == 0 +" call Decho("dav://...") + let b:netrw_method= 6 + if a:choice =~ '^s' + let g:netrw_machine= 'https://'.substitute(a:choice,davurm,'\1/\2',"") + else + let g:netrw_machine= 'http://'.substitute(a:choice,davurm,'\1/\2',"") + endif + let b:netrw_fname = substitute(a:choice,davurm,'\3',"") + + " rsync://user@hostname/...path-to-file + elseif match(a:choice,rsyncurm) == 0 +" call Decho("rsync://...") + let b:netrw_method = 7 + let g:netrw_machine= substitute(a:choice,rsyncurm,'\1',"") + let b:netrw_fname = substitute(a:choice,rsyncurm,'\2',"") + + " ftp://[user@]hostname[[:#]port]/...path-to-file + elseif match(a:choice,ftpurm) == 0 +" call Decho("ftp://...") + let userid = substitute(a:choice,ftpurm,'\2',"") + let g:netrw_machine= substitute(a:choice,ftpurm,'\3',"") + let g:netrw_port = substitute(a:choice,ftpurm,'\4',"") + let b:netrw_fname = substitute(a:choice,ftpurm,'\5',"") + if userid != "" + let g:netrw_uid= userid + endif + if exists("g:netrw_uid") && exists("g:netrw_passwd") + let b:netrw_method = 3 + else + if s:FileReadable(expand("$HOME/.netrc")) && !g:netrw_ignorenetrc + let b:netrw_method= 2 + else + if !exists("g:netrw_uid") || g:netrw_uid == "" + call NetUserPass() + elseif !exists("g:netrw_passwd") || g:netrw_passwd == "" + call NetUserPass(g:netrw_uid) + " else just use current g:netrw_uid and g:netrw_passwd + endif + let b:netrw_method= 3 + endif + endif + + elseif match(a:choice,fetchurm) == 0 +" call Decho("fetch://...") + let b:netrw_method = 8 + let g:netrw_userid = substitute(a:choice,fetchurm,'\2',"") + let g:netrw_machine= substitute(a:choice,fetchurm,'\3',"") + let b:netrw_option = substitute(a:choice,fetchurm,'\4',"") + let b:netrw_fname = substitute(a:choice,fetchurm,'\5',"") + + " Issue an ftp : "machine id password [path/]filename" + elseif match(a:choice,mipf) == 0 +" call Decho("(ftp) host id pass file") + let b:netrw_method = 3 + let g:netrw_machine = substitute(a:choice,mipf,'\1',"") + let g:netrw_uid = substitute(a:choice,mipf,'\2',"") + let g:netrw_passwd = substitute(a:choice,mipf,'\3',"") + let b:netrw_fname = substitute(a:choice,mipf,'\4',"") + + " Issue an ftp: "hostname [path/]filename" + elseif match(a:choice,mf) == 0 +" call Decho("(ftp) host file") + if exists("g:netrw_uid") && exists("g:netrw_passwd") + let b:netrw_method = 3 + let g:netrw_machine = substitute(a:choice,mf,'\1',"") + let b:netrw_fname = substitute(a:choice,mf,'\2',"") + + elseif s:FileReadable(expand("$HOME/.netrc")) + let b:netrw_method = 2 + let g:netrw_machine = substitute(a:choice,mf,'\1',"") + let b:netrw_fname = substitute(a:choice,mf,'\2',"") + endif + + " sftp://user@hostname/...path-to-file + elseif match(a:choice,sftpurm) == 0 +" call Decho("sftp://...") + let b:netrw_method = 9 + let g:netrw_machine= substitute(a:choice,sftpurm,'\1',"") + let b:netrw_fname = substitute(a:choice,sftpurm,'\2',"") + + " Issue an rcp: hostname:filename" (this one should be last) + elseif match(a:choice,rcphf) == 0 +" call Decho("(rcp) [user@]host:file) rcphf<".rcphf.">") + let b:netrw_method = 1 + let userid = substitute(a:choice,rcphf,'\2',"") + let g:netrw_machine= substitute(a:choice,rcphf,'\3',"") + let b:netrw_fname = substitute(a:choice,rcphf,'\4',"") +" call Decho('\1<'.substitute(a:choice,rcphf,'\1',"").">") +" call Decho('\2<'.substitute(a:choice,rcphf,'\2',"").">") +" call Decho('\3<'.substitute(a:choice,rcphf,'\3',"").">") +" call Decho('\4<'.substitute(a:choice,rcphf,'\4',"").">") + if userid != "" + let g:netrw_uid= userid + endif - if method == "ftp" || method == "http" - let method = "ftp" - let listcmd = g:netrw_ftp_list_cmd else - let listcmd = substitute(g:netrw_list_cmd,'\<HOSTNAME\>',user.machine,'') + if !exists("g:netrw_quiet") + call netrw#ErrorMsg(s:WARNING,"cannot determine method",45) + endif + let b:netrw_method = -1 endif - if exists("b:netrw_method") -" call Decho("setting w:netrw_method<".b:netrw_method.">") - let w:netrw_method= b:netrw_method + " remove any leading [:#] from port number + if g:netrw_port != "" + let g:netrw_port = substitute(g:netrw_port,'[#:]\+','','') endif - " optionally sort by time (-t) or by size (-S) - if listcmd == "dir" && g:netrw_sort_by =~ "^[ts]" - echohl WarningMsg | echo "***netrw*** windows' ftp doesn't support time/size sorts (get cygwin, set g:netrw_cygwin)" | echohl None - call inputsave()|call input("Press <cr> to continue")|call inputrestore() - else - if g:netrw_sort_by =~ "^t" - let listcmd= listcmd."t" - elseif g:netrw_sort_by =~ "^s" - let listcmd= listcmd."S" +" call Decho("a:choice <".a:choice.">") +" call Decho("b:netrw_method <".b:netrw_method.">") +" call Decho("g:netrw_machine<".g:netrw_machine.">") +" call Decho("g:netrw_port <".g:netrw_port.">") +" if exists("g:netrw_uid") "Decho +" call Decho("g:netrw_uid <".g:netrw_uid.">") +" endif "Decho +" if exists("g:netrw_passwd") "Decho +" call Decho("g:netrw_passwd <".g:netrw_passwd.">") +" endif "Decho +" call Decho("b:netrw_fname <".b:netrw_fname.">") +" call Dret("NetMethod : b:netrw_method=".b:netrw_method) +endfun + +" ------------------------------------------------------------------------ +" NetReadFixup: this sort of function is typically written by the user {{{2 +" to handle extra junk that their system's ftp dumps +" into the transfer. This function is provided as an +" example and as a fix for a Windows 95 problem: in my +" experience, win95's ftp always dumped four blank lines +" at the end of the transfer. +if has("win95") && exists("g:netrw_win95ftp") && g:netrw_win95ftp + fun! NetReadFixup(method, line1, line2) +" call Dfunc("NetReadFixup(method<".a:method."> line1=".a:line1." line2=".a:line2.")") + if method == 3 " ftp (no <.netrc>) + let fourblanklines= line2 - 3 + silent fourblanklines.",".line2."g/^\s*/d" endif +" call Dret("NetReadFixup") + endfun +endif - " optionally sort in reverse - if g:netrw_sort_direction =~ "^r" && listcmd == "dir" - let listcmd= listcmd."r" +" --------------------------------------------------------------------- +" NetUserPass: set username and password for subsequent ftp transfer {{{2 +" Usage: :call NetUserPass() -- will prompt for userid and password +" :call NetUserPass("uid") -- will prompt for password +" :call NetUserPass("uid","password") -- sets global userid and password +fun! NetUserPass(...) + + " get/set userid + if a:0 == 0 +" call Dfunc("NetUserPass(a:0<".a:0.">)") + if !exists("g:netrw_uid") || g:netrw_uid == "" + " via prompt + let g:netrw_uid= input('Enter username: ') + endif + else " from command line +" call Dfunc("NetUserPass(a:1<".a:1.">) {") + let g:netrw_uid= a:1 + endif + + " get password + if a:0 <= 1 " via prompt +" call Decho("a:0=".a:0." case <=1:") + let g:netrw_passwd= inputsecret("Enter Password: ") + else " from command line +" call Decho("a:0=".a:0." case >1: a:2<".a:2.">") + let g:netrw_passwd=a:2 + endif + +" call Dret("NetUserPass") +endfun + +" =========================================== +" Shared Browsing Support: {{{1 +" =========================================== + +" --------------------------------------------------------------------- +" s:BrowserMaps: {{{2 +fun! s:BrowserMaps(islocal) +" call Dfunc("s:BrowserMaps(islocal=".a:islocal.") b:netrw_curdir<".b:netrw_curdir.">") + if a:islocal + nnoremap <buffer> <silent> <cr> :call netrw#LocalBrowseCheck(<SID>NetBrowseChgDir(1,<SID>NetGetWord()))<cr> + nnoremap <buffer> <silent> <leftmouse> <leftmouse>:call netrw#LocalBrowseCheck(<SID>NetBrowseChgDir(1,<SID>NetGetWord()))<cr> + nnoremap <buffer> <silent> <c-l> :call <SID>NetRefresh(1,<SID>NetBrowseChgDir(1,'./'))<cr> + nnoremap <buffer> <silent> - :exe "norm! 0"<bar>call netrw#LocalBrowseCheck(<SID>NetBrowseChgDir(1,'../'))<cr> + nnoremap <buffer> <silent> a :call <SID>NetHide(1)<cr> + nnoremap <buffer> <silent> mb :<c-u>call <SID>NetBookmarkDir(0,b:netrw_curdir)<cr> + nnoremap <buffer> <silent> gb :<c-u>call <SID>NetBookmarkDir(1,b:netrw_curdir)<cr> + nnoremap <buffer> <silent> c :exe "cd ".b:netrw_curdir<cr> + nnoremap <buffer> <silent> C :let g:netrw_chgwin= winnr()<cr> + nnoremap <buffer> <silent> d :call <SID>NetMakeDir("")<cr> + nnoremap <buffer> <silent> <c-h> :call <SID>NetHideEdit(1)<cr> + nnoremap <buffer> <silent> i :call <SID>NetListStyle(1)<cr> + nnoremap <buffer> <silent> o :call <SID>NetSplit(3)<cr> + nnoremap <buffer> <silent> O :call <SID>LocalObtain()<cr> + nnoremap <buffer> <silent> p :call <SID>NetPreview(<SID>NetBrowseChgDir(1,<SID>NetGetWord(),1))<cr> + nnoremap <buffer> <silent> P :call <SID>NetPrevWinOpen(1)<cr> + nnoremap <buffer> <silent> q :<c-u>call <SID>NetBookmarkDir(2,b:netrw_curdir)<cr> + nnoremap <buffer> <silent> r :let g:netrw_sort_direction= (g:netrw_sort_direction =~ 'n')? 'r' : 'n'<bar>exe "norm! 0"<bar>call <SID>NetRefresh(1,<SID>NetBrowseChgDir(1,'./'))<cr> + nnoremap <buffer> <silent> s :call <SID>NetSortStyle(1)<cr> + nnoremap <buffer> <silent> S :call <SID>NetSortSequence(1)<cr> + nnoremap <buffer> <silent> t :call <SID>NetSplit(4)<cr> + nnoremap <buffer> <silent> u :<c-u>call <SID>NetBookmarkDir(4,expand("%"))<cr> + nnoremap <buffer> <silent> U :<c-u>call <SID>NetBookmarkDir(5,expand("%"))<cr> + nnoremap <buffer> <silent> v :call <SID>NetSplit(5)<cr> + nnoremap <buffer> <silent> x :call netrw#NetBrowseX(<SID>NetBrowseChgDir(1,<SID>NetGetWord(),0),0)"<cr> + if s:didstarstar || !mapcheck("<s-down>","n") + nnoremap <buffer> <silent> <s-down> :Nexplore<cr> endif + if s:didstarstar || !mapcheck("<s-up>","n") + nnoremap <buffer> <silent> <s-up> :Pexplore<cr> + endif + exe 'nnoremap <buffer> <silent> <del> :call <SID>LocalBrowseRm("'.b:netrw_curdir.'")<cr>' + exe 'vnoremap <buffer> <silent> <del> :call <SID>LocalBrowseRm("'.b:netrw_curdir.'")<cr>' + exe 'nnoremap <buffer> <silent> <rightmouse> <leftmouse>:call <SID>LocalBrowseRm("'.b:netrw_curdir.'")<cr>' + exe 'vnoremap <buffer> <silent> <rightmouse> <leftmouse>:call <SID>LocalBrowseRm("'.b:netrw_curdir.'")<cr>' + exe 'nnoremap <buffer> <silent> D :call <SID>LocalBrowseRm("'.b:netrw_curdir.'")<cr>' + exe 'vnoremap <buffer> <silent> D :call <SID>LocalBrowseRm("'.b:netrw_curdir.'")<cr>' + exe 'nnoremap <buffer> <silent> R :call <SID>LocalBrowseRename("'.b:netrw_curdir.'")<cr>' + exe 'vnoremap <buffer> <silent> R :call <SID>LocalBrowseRename("'.b:netrw_curdir.'")<cr>' + exe 'nnoremap <buffer> <silent> <Leader>m :call <SID>NetMakeDir("")<cr>' + nnoremap <buffer> <F1> :he netrw-dir<cr> + + else " remote + call s:RemotePathAnalysis(b:netrw_curdir) + nnoremap <buffer> <silent> <cr> :call <SID>NetBrowse(0,<SID>NetBrowseChgDir(0,<SID>NetGetWord()))<cr> + nnoremap <buffer> <silent> <leftmouse> <leftmouse>:call <SID>NetBrowse(0,<SID>NetBrowseChgDir(0,<SID>NetGetWord()))<cr> + nnoremap <buffer> <silent> <c-l> :call <SID>NetRefresh(0,<SID>NetBrowseChgDir(0,'./'))<cr> + nnoremap <buffer> <silent> - :exe "norm! 0"<bar>call <SID>NetBrowse(0,<SID>NetBrowseChgDir(0,'../'))<cr> + nnoremap <buffer> <silent> a :call <SID>NetHide(0)<cr> + nnoremap <buffer> <silent> mb :<c-u>call <SID>NetBookmarkDir(0,b:netrw_curdir)<cr> + nnoremap <buffer> <silent> gb :<c-u>call <SID>NetBookmarkDir(1,b:netrw_cur)<cr> + nnoremap <buffer> <silent> C :let g:netrw_chgwin= winnr()<cr> + nnoremap <buffer> <silent> <c-h> :call <SID>NetHideEdit(0)<cr> + nnoremap <buffer> <silent> i :call <SID>NetListStyle(0)<cr> + nnoremap <buffer> <silent> o :call <SID>NetSplit(0)<cr> + nnoremap <buffer> <silent> O :call netrw#NetObtain(0)<cr> + vnoremap <buffer> <silent> O :call netrw#NetObtain(1)<cr> + nnoremap <buffer> <silent> p :call <SID>NetPreview(<SID>NetBrowseChgDir(1,<SID>NetGetWord(),1))<cr> + nnoremap <buffer> <silent> P :call <SID>NetPrevWinOpen(0)<cr> + nnoremap <buffer> <silent> q :<c-u>call <SID>NetBookmarkDir(2,b:netrw_curdir)<cr> + nnoremap <buffer> <silent> r :let g:netrw_sort_direction= (g:netrw_sort_direction =~ 'n')? 'r' : 'n'<bar>exe "norm! 0"<bar>call <SID>NetBrowse(0,<SID>NetBrowseChgDir(0,'./'))<cr> + nnoremap <buffer> <silent> s :call <SID>NetSortStyle(0)<cr> + nnoremap <buffer> <silent> S :call <SID>NetSortSequence(0)<cr> + nnoremap <buffer> <silent> t :call <SID>NetSplit(1)<cr> + nnoremap <buffer> <silent> u :<c-u>call <SID>NetBookmarkDir(4,b:netrw_curdir)<cr> + nnoremap <buffer> <silent> U :<c-u>call <SID>NetBookmarkDir(5,b:netrw_curdir)<cr> + nnoremap <buffer> <silent> v :call <SID>NetSplit(2)<cr> + nnoremap <buffer> <silent> x :call netrw#NetBrowseX(<SID>NetBrowseChgDir(0,<SID>NetGetWord()),1)<cr> + exe 'nnoremap <buffer> <silent> <del> :call <SID>NetBrowseRm("'.s:user.s:machine.'","'.s:path.'")<cr>' + exe 'vnoremap <buffer> <silent> <del> :call <SID>NetBrowseRm("'.s:user.s:machine.'","'.s:path.'")<cr>' + exe 'nnoremap <buffer> <silent> <rightmouse> <leftmouse>:call <SID>NetBrowseRm("'.s:user.s:machine.'","'.s:path.'")<cr>' + exe 'vnoremap <buffer> <silent> <rightmouse> <leftmouse>:call <SID>NetBrowseRm("'.s:user.s:machine.'","'.s:path.'")<cr>' + exe 'nnoremap <buffer> <silent> d :call <SID>NetMakeDir("'.s:user.s:machine.'")<cr>' + exe 'nnoremap <buffer> <silent> D :call <SID>NetBrowseRm("'.s:user.s:machine.'","'.s:path.'")<cr>' + exe 'vnoremap <buffer> <silent> D :call <SID>NetBrowseRm("'.s:user.s:machine.'","'.s:path.'")<cr>' + exe 'nnoremap <buffer> <silent> R :call <SID>NetBrowseRename("'.s:user.s:machine.'","'.s:path.'")<cr>' + exe 'vnoremap <buffer> <silent> R :call <SID>NetBrowseRename("'.s:user.s:machine.'","'.s:path.'")<cr>' + nnoremap <buffer> <F1> :he netrw-browse-cmds<cr> endif +" call Dret("s:BrowserMaps") +endfun -" call Decho("set up listcmd<".listcmd.">") - if fname =~ '@$' && fname !~ '^"' -" call Decho("attempt transfer of symlink as file") - call s:NetBrowse(substitute(dirname,'@$','','e')) - redraw! - call s:NetOptionRestore() -" call Dret("NetBrowse : symlink") +" --------------------------------------------------------------------- +" s:NetBrowse: This function uses the command in g:netrw_list_cmd to get a list {{{2 +" of the contents of a remote directory. It is assumed that the +" g:netrw_list_cmd has a string, USEPORT HOSTNAME, that needs to be substituted +" with the requested remote hostname first. +fun! s:NetBrowse(islocal,dirname) + if !exists("w:netrw_liststyle")|let w:netrw_liststyle= g:netrw_liststyle|endif +" call Dfunc("NetBrowse(islocal=".a:islocal." dirname<".a:dirname.">) liststyle=".w:netrw_liststyle." ".g:loaded_netrw." buf#".bufnr("%")) +" call Dredir("ls!") + + if exists("s:netrw_skipbrowse") + unlet s:netrw_skipbrowse +" call Dret("NetBrowse : s:netrw_skipbrowse=".s:netrw_skipbrowse) return + endif + + call s:NetOptionSave() + + if a:islocal && exists("w:netrw_acdkeep") && w:netrw_acdkeep +" call Decho("handle w:netrw_acdkeep:") +" call Decho("cd ".escape(a:dirname,s:netrw_cd_escape)." (due to 'acd')") + exe 'cd '.escape(a:dirname,s:netrw_cd_escape) +" call Decho("getcwd<".getcwd().">") - elseif fname !~ '[\/]$' && fname !~ '^"' + elseif !a:islocal && a:dirname !~ '[\/]$' && a:dirname !~ '^"' " looks like a regular file, attempt transfer -" call Decho("attempt transfer as regular file<".dirname.">") +" call Decho("attempt transfer as regular file<".a:dirname.">") - " remove any filetype indicator from end of dirname, except for the - " "this is a directory" indicator (/). There shouldn't be one of those, - " anyway. - let path= substitute(path,'[*=@|]\r\=$','','e') + " remove any filetype indicator from end of dirname, except for the {{{3 + " "this is a directory" indicator (/). + " There shouldn't be one of those here, anyway. + let path= substitute(a:dirname,'[*=@|]\r\=$','','e') " call Decho("new path<".path.">") + call s:RemotePathAnalysis(a:dirname) - " remote-read the requested file into current buffer + " remote-read the requested file into current buffer {{{3 mark ' - keepjumps keepalt enew! - set ma -" call Decho("exe file ".method."://".user.machine."/".escape(path,s:netrw_cd_escape)) - exe "file ".method."://".user.machine."/".escape(path,s:netrw_cd_escape) - exe "silent doau BufReadPre ".fname - silent call netrw#NetRead(2,method."://".user.machine."/".path) - exe "silent doau BufReadPost ".fname - - " save certain window-oriented variables into buffer-oriented variables + call s:NetrwEnew(a:dirname) + let b:netrw_curdir= a:dirname + call s:NetrwSafeOptions() + setlocal ma noro +" call Decho("exe silent! keepalt file ".s:method."://".s:user.s:machine."/".escape(s:path,s:netrw_cd_escape)." (bt=".&bt.")") + exe "silent! keepalt file ".s:method."://".s:user.s:machine."/".escape(s:path,s:netrw_cd_escape) + exe "silent keepalt doau BufReadPre ".s:fname + silent call netrw#NetRead(2,s:method."://".s:user.s:machine."/".s:path) + exe "silent keepalt doau BufReadPost ".s:fname + + " save certain window-oriented variables into buffer-oriented variables {{{3 call s:SetBufWinVars() call s:NetOptionRestore() setlocal nomod nowrap -" call Dret("NetBrowse : file<".fname.">") +" call Dret("NetBrowse : file<".s:fname.">") return endif - " --------------------------------------------------------------------- - " Perform Directory Listing: -" call Decho("Perform directory listing...") - " set up new buffer and map - let bufname = method.'://'.user.machine.'/'.path - let bufnamenr = bufnr(bufname.'$') -" call Decho("bufname<".bufname."> bufnamenr=".bufnamenr) - mark ' - if bufnamenr != -1 - " buffer already exists, switch to it! -" call Decho("buffer already exists, switching to it") - exe "b ".bufnamenr - if line("$") >= 5 - call s:NetOptionRestore() -" call Dret("NetBrowse") + " use buffer-oriented WinVars if buffer ones exist but window ones don't {{{3 + call s:UseBufWinVars() + + " set up some variables {{{3 + let b:netrw_browser_active = 1 + let dirname = a:dirname + let s:last_sort_by = g:netrw_sort_by + + call s:NetMenu(1) " set up menu {{{3 + if s:NetGetBuffer(a:islocal,dirname) " set up buffer {{{3 +" call Dret("NetBrowse : re-using buffer") + return + endif + + " set b:netrw_curdir to the new directory name {{{3 +" call Decho("set b:netrw_curdir to the new directory name:") + let b:netrw_curdir= dirname + if b:netrw_curdir =~ '[/\\]$' + let b:netrw_curdir= substitute(b:netrw_curdir,'[/\\]$','','e') + endif + if b:netrw_curdir == '' + if has("amiga") + " On the Amiga, the empty string connotes the current directory + let b:netrw_curdir= getcwd() + else + " under unix, when the root directory is encountered, the result + " from the preceding substitute is an empty string. + let b:netrw_curdir= '/' + endif + endif + if !a:islocal && b:netrw_curdir !~ '/$' + let b:netrw_curdir= b:netrw_curdir.'/' + endif +" call Decho("b:netrw_curdir<".b:netrw_curdir.">") + + " ------------ + " (local only) {{{3 + " ------------ + if a:islocal +" call Decho("local only:") + + " Set up ShellCmdPost handling. Append current buffer to browselist + call s:LocalFastBrowser() + + " handle g:netrw_keepdir: set vim's current directory to netrw's notion of the current directory {{{3 + if !g:netrw_keepdir +" call Decho("handle keepdir:") +" call Decho('exe cd '.escape(b:netrw_curdir,s:netrw_cd_escape)) + try + exe 'cd '.escape(b:netrw_curdir,s:netrw_cd_escape) + catch /^Vim\%((\a\+)\)\=:E472/ + call netrw#ErrorMsg(s:ERROR,"unable to change directory to <".b:netrw_curdir."> (permissions?)",33) + if exists("w:netrw_prvdir") + let b:netrw_curdir= w:netrw_prvdir + else + call s:NetOptionRestore() + let b:netrw_curdir= dirname +" call Dret("NetBrowse : reusing buffer#".(exists("bufnum")? bufnum : 'N/A')."<".dirname."> getcwd<".getcwd().">") + return + endif + endtry + endif + + " -------------------------------- + " remote handling: {{{3 + " -------------------------------- + else +" call Decho("remote only:") + + " analyze a:dirname and g:netrw_list_cmd {{{4 +" call Decho("b:netrw_curdir<".(exists("b:netrw_curdir")? b:netrw_curdir : "doesn't exist")."> a:dirname<".a:dirname.">") + if a:dirname == "NetrwTreeListing" + let dirname= b:netrw_curdir +" call Decho("(dirname was NetrwTreeListing) dirname<".dirname.">") + elseif exists("w:netrw_liststyle") && w:netrw_liststyle == s:TREELIST && exists("b:netrw_curdir") + let dirname= substitute(b:netrw_curdir,'\\','/','g') + if dirname !~ '/$' + let dirname= dirname.'/' + endif + let b:netrw_curdir = dirname +" call Decho("(liststyle is TREELIST) dirname<".dirname.">") + else + let dirname = substitute(a:dirname,'\\','/','g') +" call Decho("(normal) dirname<".dirname.">") + endif + + let dirpat = '^\(\w\{-}\)://\(\w\+@\)\=\([^/]\+\)/\(.*\)$' + if dirname !~ dirpat + if !exists("g:netrw_quiet") + call netrw#ErrorMsg(s:ERROR,"netrw doesn't understand your dirname<".dirname.">",20) + endif + call s:NetOptionRestore() +" call Dret("NetBrowse : badly formatted dirname<".dirname.">") return endif + let b:netrw_curdir= dirname +" call Decho("b:netrw_curdir<".b:netrw_curdir."> (remote)") + endif " (additional remote handling) + + " ----------------------- + " Directory Listing: {{{3 + " ----------------------- + setlocal noro ma + call s:BrowserMaps(a:islocal) + call s:PerformListing(a:islocal) + +" call Dret("NetBrowse") + return +endfun + +" --------------------------------------------------------------------- +" s:NetGetBuffer: {{{2 +" returns 0=cleared buffer +" 1=re-used buffer +fun! s:NetGetBuffer(islocal,dirname) +" call Dfunc("s:NetGetBuffer(islocal=".a:islocal." dirname<".a:dirname.">)") + + " re-use buffer if possible {{{3 + if exists("w:netrw_liststyle") && w:netrw_liststyle == s:TREELIST + " find NetrwTreeList buffer if there is one + let dirname= "NetrwTreeListing" + let bufnum = bufnr('\<NetrwTreeListing\>') + if bufnum != -1 +" call Dret("s:NetGetBuffer : bufnum#".bufnum."<NetrwTreeListing>") + return + endif + else -" call Decho("generate a new buffer") - keepjumps keepalt enew! + " find buffer number of buffer named precisely the same as dirname {{{3 + let dirname= a:dirname +" call Decho("find buffer<".dirname.">'s number ") + let bufnum= bufnr(escape(dirname,'\')) +" call Decho("findbuf: bufnum=bufnr('".escape(dirname,'\')."')=".bufnum." (initial)") + let ibuf= 1 + if bufnum > 0 && bufname(bufnum) != dirname + let buflast = bufnr("$") +" call Decho("findbuf: buflast=".buflast) + while ibuf <= buflast + let bname= bufname(ibuf) +" call Decho("findbuf: ibuf=".ibuf. " bufname<".bufname(ibuf)."> dirname<".dirname.">") + if bname != '' && bname !~ '/' && dirname =~ '/'.bname.'$' | break | endif + if bname =~ '^'.dirname.'\=$' | break | endif + let ibuf= ibuf + 1 + endwhile + if ibuf > buflast + let bufnum= -1 + else + let bufnum= ibuf + endif +" call Decho("findbuf: bufnum=".bufnum." (final)") + endif endif - " rename file to reflect where its from - setlocal bt=nofile bh=wipe nobl noswf + " get enew buffer and name it -or- re-use buffer {{{3 + mark ' + if bufnum < 0 || !bufexists(bufnum) +" call Decho("get enew buffer") + call s:NetrwEnew(dirname) + call s:NetrwSafeOptions() + " name the buffer + if exists("w:netrw_liststyle") && w:netrw_liststyle == s:TREELIST + silent! keepalt file NetrwTreeListing + else + exe 'silent! keepalt file '.escape(dirname,s:netrw_cd_escape) + endif +" call Decho("named enew buffer<".expand("%").">") + + else " Re-use the buffer + +" call Decho("re-use buffer:") + let eikeep= &ei + set ei=all + if getline(2) =~ '^" Netrw Directory Listing' +" call Decho("re-use buffer#".bufnum."<".((bufnum > 0)? bufname(bufnum) : "")."> using: keepalt b ".bufnum) + exe "keepalt b ".bufnum + else +" call Decho("reusing buffer#".bufnum."<".((bufnum > 0)? bufname(bufnum) : "")."> using: b ".bufnum) + exe "b ".bufnum + endif + let &ei= eikeep + if line("$") <= 1 + call s:NetrwListSettings(a:islocal) +" call Dret("s:NetGetBuffer 0 : re-using buffer#".bufnr("%").", but its empty, so refresh it") + return 0 + elseif exists("w:netrw_liststyle") && w:netrw_liststyle == s:TREELIST +" call Decho("clear buffer<".expand("%")."> with :%d") + silent %d + call s:NetrwListSettings(a:islocal) +" call Dret("s:NetGetBuffer 0 : re-using buffer#".bufnr("%").", but treelist mode always needs a refresh") + return 0 + else +" call Dret("s:NetGetBuffer 1 : buf#".bufnr("%")) + return 1 + endif + endif + + " do netrw settings: make this buffer not-a-file, modifiable, not line-numbered, etc {{{3 + " fastbrowse Local Remote Hiding a buffer implies it may be re-used (fast) + " slow 0 D D Deleting a buffer implies it will not be re-used (slow) + " med 1 D H + " fast 2 H H + let fname= expand("%") + call s:NetrwListSettings(a:islocal) + exe "file ".escape(fname,' ') + + " delete all lines from buffer {{{3 +" call Decho("clear buffer<".expand("%")."> with :%d") + keepalt silent! %d + +" call Dret("s:NetGetBuffer 0 : buf#".bufnr("%")) + return 0 +endfun + +" --------------------------------------------------------------------- +" s:NetrwListSettings: {{{2 +fun! s:NetrwListSettings(islocal) +" call Dfunc("s:NetrwListSettings(islocal=".a:islocal.")") + let fname= bufname("%") + setlocal bt=nofile nobl ma nonu nowrap noro + exe "file ".escape(fname,' ') + if g:netrw_use_noswf + setlocal noswf + endif +"call Dredir("ls!") +" call Decho("exe setlocal ts=".g:netrw_maxfilenamelen) exe "setlocal ts=".g:netrw_maxfilenamelen -" call Decho("exe file ".escape(bufname,s:netrw_cd_escape)) - exe 'file '.escape(bufname,s:netrw_cd_escape) -" call Decho("renaming file to bufname<".bufname.">") - setlocal bt=nofile nobl nonu noswf - if g:netrw_fastbrowse >= 1 + if g:netrw_fastbrowse > a:islocal setlocal bh=hide else setlocal bh=delete endif +" call Dret("s:NetrwListSettings") +endfun + +" --------------------------------------------------------------------- +" s:PerformListing: {{{2 +fun! s:PerformListing(islocal) +" call Dfunc("s:PerformListing(islocal=".a:islocal.")") + +" if exists("g:netrw_silent") && g:netrw_silent == 0 && &ch >= 1 " Decho +" call Decho("(netrw) Processing your browsing request...") +" endif " Decho + +" call Decho('w:netrw_liststyle='.(exists("w:netrw_liststyle")? w:netrw_liststyle : 'n/a')) + if exists("w:netrw_liststyle") && w:netrw_liststyle == s:TREELIST && exists("w:netrw_treedict") + " force a refresh for tree listings +" call Decho("clear buffer<".expand("%")."> with :%d") + setlocal ma noro + keepjumps %d + endif " save current directory on directory history list - call s:NetBookmarkDir(3,expand("%")) - - " set up buffer-local mappings -" call Decho("set up buffer-local mappings") - nnoremap <buffer> <silent> <cr> :call <SID>NetBrowse(<SID>NetBrowseChgDir(expand("%"),<SID>NetGetWord()))<cr> - nnoremap <buffer> <silent> <c-l> :call <SID>NetRefresh(<SID>NetBrowseChgDir(expand("%"),'./'),0)<cr> - nnoremap <buffer> <silent> - :exe "norm! 0"<bar>call <SID>NetBrowse(<SID>NetBrowseChgDir(expand("%"),'../'))<cr> - nnoremap <buffer> <silent> a :let g:netrw_hide=(g:netrw_hide+1)%3<bar>exe "norm! 0"<bar>call <SID>NetBrowse(<SID>NetBrowseChgDir(expand("%"),'./'))<cr> - if w:netrw_longlist != 2 - nnoremap <buffer> <silent> b :<c-u>call <SID>NetBookmarkDir(0,expand("%"))<cr> - nnoremap <buffer> <silent> B :<c-u>call <SID>NetBookmarkDir(1,expand("%"))<cr> - endif - nnoremap <buffer> <silent> Nb :<c-u>call <SID>NetBookmarkDir(0,expand("%"))<cr> - nnoremap <buffer> <silent> NB :<c-u>call <SID>NetBookmarkDir(0,expand("%"))<cr> - nnoremap <buffer> <silent> <c-h> :call <SID>NetHideEdit(0)<cr> - nnoremap <buffer> <silent> i :call <SID>NetLongList(0)<cr> - nnoremap <buffer> <silent> o :call <SID>NetSplit(0)<cr> - nnoremap <buffer> <silent> O :call netrw#NetObtain()<cr> - nnoremap <buffer> <silent> P :call <SID>NetPrevWinOpen(0)<cr> - nnoremap <buffer> <silent> q :<c-u>call <SID>NetBookmarkDir(2,expand("%"))<cr> - nnoremap <buffer> <silent> r :let g:netrw_sort_direction= (g:netrw_sort_direction =~ 'n')? 'r' : 'n'<bar>exe "norm! 0"<bar>call <SID>NetBrowse(<SID>NetBrowseChgDir(expand("%"),'./'))<cr> - nnoremap <buffer> <silent> s :call <SID>NetSaveWordPosn()<bar>let g:netrw_sort_by= (g:netrw_sort_by =~ 'n')? 'time' : (g:netrw_sort_by =~ 't')? 'size' : 'name'<bar>exe "norm! 0"<bar>call <SID>NetBrowse(<SID>NetBrowseChgDir(expand("%"),'./'))<bar>call <SID>NetRestoreWordPosn()<cr> - nnoremap <buffer> <silent> S :call <SID>NetSortSequence(0)<cr> - nnoremap <buffer> <silent> u :<c-u>call <SID>NetBookmarkDir(4,expand("%"))<cr> - nnoremap <buffer> <silent> U :<c-u>call <SID>NetBookmarkDir(5,expand("%"))<cr> - nnoremap <buffer> <silent> v :call <SID>NetSplit(1)<cr> - nnoremap <buffer> <silent> x :call netrw#NetBrowseX(<SID>NetBrowseChgDir(expand("%"),<SID>NetGetWord()),1)<cr> - nnoremap <buffer> <silent> <2-leftmouse> :call <SID>NetBrowse(<SID>NetBrowseChgDir(expand("%"),<SID>NetGetWord()))<cr> - exe 'nnoremap <buffer> <silent> <del> :call <SID>NetBrowseRm("'.user.machine.'","'.path.'")<cr>' - exe 'vnoremap <buffer> <silent> <del> :call <SID>NetBrowseRm("'.user.machine.'","'.path.'")<cr>' - exe 'nnoremap <buffer> <silent> d :call <SID>NetMakeDir("'.user.machine.'")<cr>' - exe 'nnoremap <buffer> <silent> D :call <SID>NetBrowseRm("'.user.machine.'","'.path.'")<cr>' - exe 'vnoremap <buffer> <silent> D :call <SID>NetBrowseRm("'.user.machine.'","'.path.'")<cr>' - exe 'nnoremap <buffer> <silent> R :call <SID>NetBrowseRename("'.user.machine.'","'.path.'")<cr>' - exe 'vnoremap <buffer> <silent> R :call <SID>NetBrowseRename("'.user.machine.'","'.path.'")<cr>' - nnoremap <buffer> <F1> :he netrw-browse-cmds<cr> - setlocal ma nonu nowrap - - " Set up the banner -" call Decho("set up the banner: sortby<".g:netrw_sort_by."> method<".method."> direction<".g:netrw_sort_direction.">") - keepjumps put ='\" ===========================================================================' - keepjumps put ='\" Netrw Remote Directory Listing (netrw '.g:loaded_netrw.')' - keepjumps put ='\" '.bufname - let w:netrw_bannercnt = 7 - let sortby = g:netrw_sort_by + call s:NetBookmarkDir(3,b:netrw_curdir) + + " Set up the banner {{{3 +" call Decho("set up banner") + keepjumps put ='\" ============================================================================' + keepjumps put ='\" Netrw Directory Listing (netrw '.g:loaded_netrw.')' + keepjumps put ='\" '.b:netrw_curdir + keepjumps 1d + let w:netrw_bannercnt= 3 + exe w:netrw_bannercnt + + let sortby= g:netrw_sort_by if g:netrw_sort_direction =~ "^r" - let sortby = sortby." reversed" + let sortby= sortby." reversed" endif + " Sorted by... {{{3 +" call Decho("handle specified sorting: g:netrw_sort_by<".g:netrw_sort_by.">") if g:netrw_sort_by =~ "^n" +" call Decho("directories will be sorted by name") " sorted by name - let w:netrw_bannercnt= w:netrw_bannercnt + 1 keepjumps put ='\" Sorted by '.sortby keepjumps put ='\" Sort sequence: '.g:netrw_sort_sequence + let w:netrw_bannercnt= w:netrw_bannercnt + 2 else +" call Decho("directories will be sorted by size or time") " sorted by size or date keepjumps put ='\" Sorted by '.sortby + let w:netrw_bannercnt= w:netrw_bannercnt + 1 endif + exe w:netrw_bannercnt + + " Hiding... -or- Showing... {{{3 +" call Decho("handle hiding/showing (g:netrw_hide=".g:netrw_list_hide." g:netrw_list_hide<".g:netrw_list_hide.">)") if g:netrw_list_hide != "" && g:netrw_hide -" call Decho("g:netrw_hide=".g:netrw_hide) if g:netrw_hide == 1 keepjumps put ='\" Hiding: '.g:netrw_list_hide else @@ -1363,211 +2004,528 @@ fun! s:NetBrowse(dirname) endif let w:netrw_bannercnt= w:netrw_bannercnt + 1 endif + exe w:netrw_bannercnt keepjumps put ='\" Quick Help: <F1>:help -:go up dir D:delete R:rename s:sort-by x:exec' - keepjumps put ='\" ===========================================================================' - - " remote read the requested directory listing - " Use ftp if that was the file-transfer method selected, otherwise use ssh - " Note that not all ftp servers honor the options for ls - if method == "ftp" - " use ftp to get remote file listing -" call Decho("use ftp to get remote file listing") - call s:NetBrowseFtpCmd(path,listcmd) - keepjumps 1d - - if w:netrw_longlist == 0 || w:netrw_longlist == 2 - " shorten the listing -" call Decho("generate short listing") - exe "keepjumps ".w:netrw_bannercnt - - " cleanup - if g:netrw_ftp_browse_reject != "" - exe "silent! g/".g:netrw_ftp_browse_reject."/keepjumps d" - endif - silent! keepjumps %s/\r$//e - - " if there's no ../ listed, then put ./ and ../ in - let line1= line(".") - keepjumps 1 - silent keepjumps call search('^\.\.\/\%(\s\|$\)','W') - let line2= line(".") - if line2 == 0 - keepjumps put='../' - keepjumps put='./' - endif - exe "keepjumps ".line1 - keepjumps norm! 0 - - " more cleanup - exe 'silent! keepjumps '.w:netrw_bannercnt.',$s/^\(\%(\S\+\s\+\)\{7}\S\+\)\s\+\(\S.*\)$/\2/e' - exe "silent! keepjumps ".w:netrw_bannercnt.',$g/ -> /s# -> .*/$#/#e' - exe "silent! keepjumps ".w:netrw_bannercnt.',$g/ -> /s# -> .*$#/#e' - endif + keepjumps put ='\" ============================================================================' + let w:netrw_bannercnt= w:netrw_bannercnt + 2 - else - " use ssh to get remote file listing -" call Decho("use ssh to get remote file listing") - let shq= &shq? &shq : ( &sxq? &sxq : "'") -" call Decho("exe silent r! ".listcmd." '".shq.escape(path,s:netrw_cd_escape).shq."'") - exe "silent r! ".listcmd." ".shq.escape(path,s:netrw_cd_escape).shq - keepjumps 1d - " cleanup - if g:netrw_ftp_browse_reject != "" - exe "silent! g/".g:netrw_ssh_browse_reject."/keepjumps d" - endif - endif + " bannercnt should index the line just after the banner + let w:netrw_bannercnt= w:netrw_bannercnt + 1 + exe w:netrw_bannercnt +" call Decho("bannercnt=".w:netrw_bannercnt." (should index line just after banner) line($)=".line("$")) - " set up syntax highlighting + " set up syntax highlighting {{{3 +" call Decho("set up syntax highlighting") if has("syntax") setlocal ft=netrw if !exists("g:syntax_on") || !g:syntax_on setlocal ft= - " Ugly workaround -- when syntax highlighting is off and laststatus==2, - " sometimes the laststatus highlight bleeds into the entire display. - " Only seems to happen with remote browsing. Weird. - redraw endif endif - " manipulate the directory listing (hide, sort) + " get list of files + if a:islocal + call s:LocalListing() + else " remote + call s:RemoteListing() + endif +" call Decho("w:netrw_bannercnt=".w:netrw_bannercnt." (banner complete)") + + " manipulate the directory listing (hide, sort) {{{3 if line("$") >= w:netrw_bannercnt +" call Decho("manipulate directory listing (hide)") +" call Decho("g:netrw_hide=".g:netrw_hide." g:netrw_list_hide<".g:netrw_list_hide.">") if g:netrw_hide && g:netrw_list_hide != "" - call s:NetrwListHide() + call s:NetListHide() endif - - if w:netrw_longlist == 1 - " do a long listing; these substitutions need to be done prior to sorting -" call Decho("manipulate long listing") - - if method == "ftp" - " cleanup - exe "keepjumps ".w:netrw_bannercnt - while getline(".") =~ g:netrw_ftp_browse_reject - keepjumps d - endwhile - " if there's no ../ listed, then put ./ and ../ in - let line1= line(".") - keepjumps 1 - silent keepjumps call search('^\.\.\/\%(\s\|$\)','W') - let line2= line(".") - if line2 == 0 - exe 'keepjumps '.w:netrw_bannercnt."put='./'" - exe 'keepjumps '.w:netrw_bannercnt."put='../'" - endif - exe "keepjumps ".line1 - keepjumps norm! 0 - endif - - exe 'silent keepjumps '.w:netrw_bannercnt.',$s/ -> .*$//e' - exe 'silent keepjumps '.w:netrw_bannercnt.',$s/^\(\%(\S\+\s\+\)\{7}\S\+\)\s\+\(\S.*\)$/\2\t\1/e' - exe 'silent keepjumps '.w:netrw_bannercnt - endif - if line("$") >= w:netrw_bannercnt +" call Decho("manipulate directory listing (sort) : g:netrw_sort_by<".g:netrw_sort_by.">") + if g:netrw_sort_by =~ "^n" + " sort by name call s:SetSort() - if g:netrw_sort_direction =~ 'n' - exe 'silent keepjumps '.w:netrw_bannercnt.',$sort' - else - exe 'silent keepjumps '.w:netrw_bannercnt.',$sort!' + + if w:netrw_bannercnt < line("$") +" call Decho("g:netrw_sort_direction=".g:netrw_sort_direction." (bannercnt=".w:netrw_bannercnt.")") + if g:netrw_sort_direction =~ 'n' + " normal direction sorting + exe 'silent keepjumps '.w:netrw_bannercnt.',$sort' + else + " reverse direction sorting + exe 'silent keepjumps '.w:netrw_bannercnt.',$sort!' + endif endif " remove priority pattern prefix +" call Decho("remove priority pattern prefix") exe 'silent keepjumps '.w:netrw_bannercnt.',$s/^\d\{3}\///e' + + elseif a:islocal + if w:netrw_bannercnt < line("$") +" call Decho("g:netrw_sort_direction=".g:netrw_sort_direction) + if g:netrw_sort_direction =~ 'n' +" call Decho('exe silent keepjumps '.w:netrw_bannercnt.',$sort') + exe 'silent keepjumps '.w:netrw_bannercnt.',$sort' + else +" call Decho('exe silent keepjumps '.w:netrw_bannercnt.',$sort!') + exe 'silent keepjumps '.w:netrw_bannercnt.',$sort!' + endif + endif + exe 'silent keepjumps '.w:netrw_bannercnt.',$s/^\d\{-}\///e' endif - if w:netrw_longlist == 1 - " shorten the list to keep its width <= winwidth characters - exe "silent keepjumps ".w:netrw_bannercnt.',$s/\t[-dstrwx]\+/\t/e' - endif + + elseif g:netrw_sort_direction =~ 'r' +" call Decho('reverse the sorted listing') + exe 'silent keepjumps '.w:netrw_bannercnt.'g/^/m '.w:netrw_bannercnt endif endif - call s:NetrwWideListing() - if line("$") >= w:netrw_bannercnt + " convert to wide/tree listing {{{3 +" call Decho("modify display if wide/tree listing style") + call s:NetWideListing() + call s:NetTreeListing(b:netrw_curdir) + + if exists("w:netrw_bannercnt") && line("$") > w:netrw_bannercnt " place cursor on the top-left corner of the file listing - exe "keepjumps ".w:netrw_bannercnt +" call Decho("place cursor on top-left corner of file listing") + exe 'silent '.w:netrw_bannercnt norm! 0 endif + " record previous current directory + let w:netrw_prvdir= b:netrw_curdir +" call Decho("record netrw_prvdir<".w:netrw_prvdir.">") + + " save certain window-oriented variables into buffer-oriented variables {{{3 + call s:SetBufWinVars() call s:NetOptionRestore() - setlocal nomod noma nonu -" call Dret("NetBrowse") - return + " set display to netrw display settings +" call Decho("set display to netrw display settings (noma nomod etc)") + setlocal noma nomod nonu nobl nowrap ro + if exists("s:treecurpos") + call setpos('.',s:treecurpos) + unlet s:treecurpos + endif + +" call Dret("s:PerformListing : curpos<".string(getpos(".")).">") endfun " --------------------------------------------------------------------- -" NetBrowseChgDir: {{{2 -fun! s:NetBrowseChgDir(dirname,newdir) -" call Dfunc("NetBrowseChgDir(dirname<".a:dirname."> newdir<".a:newdir.">)") +" s:NetBrowseChgDir: constructs a new directory based on the current {{{2 +" directory and a new directory name +fun! s:NetBrowseChgDir(islocal,newdir,...) +" call Dfunc("s:NetBrowseChgDir(islocal=".a:islocal."> newdir<".a:newdir.">) a:0=".a:0." curpos<".string(getpos("."))."> b:netrw_curdir<".(exists("b:netrw_curdir")? b:netrw_curdir : "").">") - let dirname= a:dirname - let newdir = a:newdir + if !exists("b:netrw_curdir") +" call Decho("(NetBrowseChgDir) b:netrw_curdir doesn't exist!") + echoerr "(NetBrowseChgDir) b:netrw_curdir doesn't exist!" +" call Dret("s:NetBrowseChgDir") + return + endif + + call netrw#NetSavePosn() + let nbcd_curpos = getpos('.') + let dirname = substitute(b:netrw_curdir,'\\','/','ge') + let newdir = a:newdir + + " set up o/s-dependent directory recognition pattern + if has("amiga") + let dirpat= '[\/:]$' + else + let dirpat= '[\/]$' + endif +" call Decho("dirname<".dirname."> dirpat<".dirpat.">") + + if dirname !~ dirpat + " apparently vim is "recognizing" that it is in a directory and + " is removing the trailing "/". Bad idea, so I have to put it back. + let dirname= dirname.'/' +" call Decho("adjusting dirname<".dirname.">") + endif - if newdir !~ '[\/]$' + if newdir !~ dirpat " handling a file - let dirname= dirname.newdir - let didfile= 0 - if g:netrw_browse_split == 1 - new - wincmd _ - elseif g:netrw_browse_split == 2 - rightb vert new - wincmd | +" call Decho('case "handling a file": newdir<'.newdir.'> !~ dirpat<'.dirpat.">") + if exists("w:netrw_liststyle") && w:netrw_liststyle == s:TREELIST && exists("w:netrw_treedict") && newdir !~ '^\(/\|\a:\)' + let dirname= s:NetTreeDir().newdir +" call Decho("tree listing") + elseif newdir =~ '^\(/\|\a:\)' + let dirname= newdir else - " handling a file, didn't split, so possibly remove menu - call s:NetMenu(0) + let dirname= s:ComposePath(dirname,newdir) + endif +" call Decho("handling a file: dirname<".dirname."> (a:0=".a:0.")") + " this lets NetBrowseX avoid the edit + if a:0 < 1 +" call Decho("dirname<".dirname."> netrw_cd_escape<".s:netrw_cd_escape."> browse_split=".g:netrw_browse_split) +" call Decho("about to edit<".escape(dirname,s:netrw_cd_escape)."> didsplit=".(exists("s:didsplit")? s:didsplit : "doesn't exist")) + if !exists("s:didsplit") + if g:netrw_browse_split == 1 + new + wincmd _ + elseif g:netrw_browse_split == 2 + rightb vert new + wincmd | + elseif g:netrw_browse_split == 3 + tabnew + else + " handling a file, didn't split, so remove menu +" call Decho("handling a file+didn't split, so remove menu") + call s:NetMenu(0) + " optional change to window + if g:netrw_chgwin >= 1 + exe g:netrw_chgwin."wincmd w" + endif + endif + endif + " edit the file + " its local only: LocalBrowseCheck() doesn't edit a file, but NetBrowse() will + if a:islocal +" call Decho("edit file: exe e! ".escape(dirname,s:netrw_cd_escape)) + exe "e! ".escape(dirname,s:netrw_cd_escape) + endif + setlocal ma nomod noro endif -" call Decho("handling a file: dirname<".dirname.">") + + elseif newdir =~ '^/' + " just go to the new directory spec +" call Decho('case "just go to new directory spec": newdir<'.newdir.'>') + let dirname= newdir elseif newdir == './' " refresh the directory list -" call Decho("refresh directory listing") - setlocal ma nobl - if g:netrw_fastbrowse >= 1 - setlocal bh=hide - else - setlocal bh=delete - endif - %d +" call Decho('case "refresh directory listing": newdir == "./"') elseif newdir == '../' " go up one directory - let trailer= substitute(a:dirname,'^\(\w\+://\%(\w\+@\)\=\w\+/\)\(.*\)$','\2','') +" call Decho('case "go up one directory": newdir == "../"') + + if w:netrw_liststyle == s:TREELIST && exists("w:netrw_treedict") + " force a refresh +" call Decho("clear buffer<".expand("%")."> with :%d") + setlocal noro ma + keepjumps %d + endif + + if has("amiga") + " amiga +" call Decho('case "go up one directory": newdir == "../" and amiga') + if a:islocal + let dirname= substitute(dirname,'^\(.*[/:]\)\([^/]\+$\)','\1','') + let dirname= substitute(dirname,'/$','','') + else + let dirname= substitute(dirname,'^\(.*[/:]\)\([^/]\+/$\)','\1','') + endif +" call Decho("amiga: dirname<".dirname."> (go up one dir)") + + else + " unix or cygwin +" call Decho('case "go up one directory": newdir == "../" and unix or cygwin') + if a:islocal + let dirname= substitute(dirname,'^\(.*\)/\([^/]\+\)/$','\1','') + if dirname == "" + let dirname= '/' + endif + else + let dirname= substitute(dirname,'^\(\a\+://.\{-}/\{1,2}\)\(.\{-}\)\([^/]\+\)/$','\1\2','') + endif +" call Decho("unix: dirname<".dirname."> (go up one dir)") + endif + + elseif w:netrw_liststyle == s:TREELIST && exists("w:netrw_treedict") +" call Decho('case liststyle is TREELIST and w:netrw_treedict exists') + " force a refresh (for TREELIST, wait for NetTreeDir() to force the refresh) + setlocal noro ma + if !(exists("w:netrw_liststyle") && w:netrw_liststyle == s:TREELIST && exists("b:netrw_curdir")) +" call Decho("clear buffer<".expand("%")."> with :%d") + keepjumps %d + endif + let treedir = s:NetTreeDir() + let s:treecurpos = nbcd_curpos + let haskey= 0 +" call Decho("w:netrw_treedict<".string(w:netrw_treedict).">") + + " search treedict for tree dir as-is + if has_key(w:netrw_treedict,treedir) +" call Decho('....searched for treedir<'.treedir.'> : found it!') + let haskey= 1 + else +" call Decho('....searched for treedir<'.treedir.'> : not found') + endif - if trailer =~ '^\%(\.\./\)*$' - " tack on a ../" - let dirname= dirname.'../' + " search treedict for treedir with a / appended + if !haskey && treedir !~ '/$' + if has_key(w:netrw_treedict,treedir."/") + let treedir= treedir."/" +" call Decho('....searched.for treedir<'.treedir.'> found it!') + let haskey = 1 + else +" call Decho('....searched for treedir<'.treedir.'/> : not found') + endif + endif + + " search treedict for treedir with any trailing / elided + if !haskey && treedir =~ '/$' + let treedir= substitute(treedir,'/$','','') + if has_key(w:netrw_treedict,treedir) +" call Decho('....searched.for treedir<'.treedir.'> found it!') + let haskey = 1 + else +" call Decho('....searched for treedir<'.treedir.'> : not found') + endif + endif + if haskey + " close tree listing for selected subdirectory +" call Decho("closing selected subdirectory<".dirname.">") + call remove(w:netrw_treedict,treedir) +" call Decho("removed entry<".dirname."> from treedict") +" call Decho("yielding treedict<".string(w:netrw_treedict).">") + let dirname= w:netrw_treetop else - " strip off a directory name from dirname - let dirname= substitute(dirname,'^\(.*/\)[^/]\+/','\1','') + " go down one directory + let dirname= substitute(treedir,'/*$','/','') +" call Decho("go down one dir: treedir<".treedir.">") endif -" call Decho("go up one dir: dirname<".dirname."> trailer<".trailer.">") else " go down one directory - let dirname= dirname.newdir + let dirname= s:ComposePath(dirname,newdir) " call Decho("go down one dir: dirname<".dirname."> newdir<".newdir.">") endif -" call Dret("NetBrowseChgDir <".dirname.">") +" call Dret("s:NetBrowseChgDir <".dirname."> : curpos<".string(getpos(".")).">") return dirname endfun " --------------------------------------------------------------------- +" s:NetHide: this function is invoked by the "a" map for browsing {{{2 +" and switches the hiding mode +fun! s:NetHide(islocal) +" call Dfunc("NetHide(islocal=".a:islocal.")") + let g:netrw_hide=(g:netrw_hide+1)%3 + exe "norm! 0" + if g:netrw_hide && g:netrw_list_hide == "" + call netrw#ErrorMsg(s:WARNING,"your hiding list is empty!",49) +" call Dret("NetHide") + return + endif + call netrw#NetSavePosn() + call s:NetRefresh(a:islocal,s:NetBrowseChgDir(a:islocal,'./')) +" call Dret("NetHide") +endfun + +" --------------------------------------------------------------------- + +" =========================================== +" s:NetPreview: {{{2 +fun! s:NetPreview(path) range +" call Dfunc("NetPreview(path<".a:path.">)") + if has("quickfix") + if !isdirectory(a:path) + exe "pedit ".escape(a:path,g:netrw_fname_escape) + elseif !exists("g:netrw_quiet") + call netrw#ErrorMsg(s:WARNING,"sorry, cannot preview a directory such as <".a:path.">",38) + endif + elseif !exists("g:netrw_quiet") + call netrw#ErrorMsg(s:WARNING,"sorry, to preview your vim needs the quickfix feature compiled in",39) + endif +" call Dret("NetPreview") +endfun + +" --------------------------------------------------------------------- +" s:NetSortStyle: change sorting style (name - time - size) and refresh display {{{2 +fun! s:NetSortStyle(islocal) +" call Dfunc("s:NetSortStyle(islocal=".a:islocal.") netrw_sort_by<".g:netrw_sort_by.">") + call s:NetSaveWordPosn() + + let g:netrw_sort_by= (g:netrw_sort_by =~ 'n')? 'time' : (g:netrw_sort_by =~ 't')? 'size' : 'name' + norm! 0 + call netrw#NetSavePosn() + call s:NetRefresh(a:islocal,s:NetBrowseChgDir(a:islocal,'./')) + +" call Dret("s:NetSortStyle : netrw_sort_by<".g:netrw_sort_by.">") +endfun + +" --------------------------------------------------------------------- +" Remote Directory Browsing Support: {{{1 +" =========================================== + +" --------------------------------------------------------------------- +" s:RemoteListing: {{{2 +fun! s:RemoteListing() +" call Dfunc("s:RemoteListing() b:netrw_curdir<".b:netrw_curdir.">)") + + call s:RemotePathAnalysis(b:netrw_curdir) + + " sanity check: + if exists("b:netrw_method") && b:netrw_method =~ '[235]' +" call Decho("b:netrw_method=".b:netrw_method) + if !executable("ftp") + if !exists("g:netrw_quiet") + call netrw#ErrorMsg(s:ERROR,"this system doesn't support remote directory listing via ftp",18) + endif + call s:NetOptionRestore() +" call Dret("s:RemoteListing") + return + endif + + elseif !exists("g:netrw_list_cmd") || g:netrw_list_cmd == '' + if !exists("g:netrw_quiet") + if g:netrw_list_cmd == "" + call netrw#ErrorMsg(s:ERROR,g:netrw_ssh_cmd." is not executable on your system",47) + else + call netrw#ErrorMsg(s:ERROR,"this system doesn't support remote directory listing via ".g:netrw_list_cmd,19) + endif + endif + + call s:NetOptionRestore() +" call Dret("s:RemoteListing") + return + endif " (remote handling sanity check) + + if exists("b:netrw_method") +" call Decho("setting w:netrw_method<".b:netrw_method.">") + let w:netrw_method= b:netrw_method + endif + + if s:method == "ftp" + " use ftp to get remote file listing +" call Decho("use ftp to get remote file listing") + let s:method = "ftp" + let listcmd = g:netrw_ftp_list_cmd + if g:netrw_sort_by =~ '^t' + let listcmd= g:netrw_ftp_timelist_cmd + elseif g:netrw_sort_by =~ '^s' + let listcmd= g:netrw_ftp_sizelist_cmd + endif +" call Decho("listcmd<".listcmd."> (using g:netrw_ftp_list_cmd)") + call s:NetBrowseFtpCmd(s:path,listcmd) +" exe "keepjumps ".w:netrw_bannercnt.',$g/^./call Decho("raw listing: ".getline("."))' + + if w:netrw_liststyle == s:THINLIST || w:netrw_liststyle == s:WIDELIST || w:netrw_liststyle == s:TREELIST + " shorten the listing +" call Decho("generate short listing") + exe "keepjumps ".w:netrw_bannercnt + + " cleanup + if g:netrw_ftp_browse_reject != "" + exe "silent! g/".g:netrw_ftp_browse_reject."/keepjumps d" + endif + silent! keepjumps %s/\r$//e + + " if there's no ../ listed, then put ./ and ../ in + let line1= line(".") + exe "keepjumps ".w:netrw_bannercnt + let line2= search('^\.\.\/\%(\s\|$\)','cnW') + if line2 == 0 +" call Decho("netrw is putting ./ and ../ into listing") + keepjumps put='../' + keepjumps put='./' + endif + exe "keepjumps ".line1 + keepjumps norm! 0 + +" call Decho("line1=".line1." line2=".line2." line(.)=".line(".")) + if search('^\d\{2}-\d\{2}-\d\{2}\s','n') " M$ ftp site cleanup +" call Decho("M$ ftp cleanup") + exe 'silent! keepjumps '.w:netrw_bannercnt.',$s/^\d\{2}-\d\{2}-\d\{2}\s\+\d\+:\d\+[AaPp][Mm]\s\+\%(<DIR>\|\d\+\)\s\+//' + else " normal ftp cleanup +" call Decho("normal ftp cleanup") + exe 'silent! keepjumps '.w:netrw_bannercnt.',$s/^\(\%(\S\+\s\+\)\{7}\S\+\)\s\+\(\S.*\)$/\2/e' + exe "silent! keepjumps ".w:netrw_bannercnt.',$g/ -> /s# -> .*/$#/#e' + exe "silent! keepjumps ".w:netrw_bannercnt.',$g/ -> /s# -> .*$#/#e' + endif + endif + + else + " use ssh to get remote file listing {{{3 +" call Decho("use ssh to get remote file listing: s:netrw_shq<".g:netrw_shq."> s:path<".s:path."> s:netrw_cd_escape<".s:netrw_cd_escape.">") + let listcmd= s:MakeSshCmd(g:netrw_list_cmd) +" call Decho("listcmd<".listcmd."> (using g:netrw_list_cmd)") + if g:netrw_scp_cmd =~ '^pscp' +" call Decho("1: exe silent r! ".listcmd.g:netrw_shq.s:path.g:netrw_shq) + exe "silent r! ".listcmd.g:netrw_shq.s:path.g:netrw_shq + " remove rubbish and adjust listing format of 'pscp' to 'ssh ls -FLa' like + g/^Listing directory/d + g/^d[-rwx][-rwx][-rwx]/s+$+/+e + silent g/^l[-rwx][-rwx][-rwx]/s+$+@+e + if g:netrw_liststyle != s:LONGLIST + g/^[dlsp-][-rwx][-rwx][-rwx]/s/^.*\s\(\S\+\)$/\1/e + endif + else + if s:path == "" +" call Decho("2: exe silent r! ".listcmd) + exe "silent r! ".listcmd + else +" call Decho("3: exe silent r! ".listcmd." ".g:netrw_shq.s:path.g:netrw_shq) + exe "silent r! ".listcmd." ".g:netrw_shq.s:path.g:netrw_shq + endif + endif + + " cleanup + if g:netrw_ftp_browse_reject != "" +" call Decho("(cleanup) exe silent! g/".g:netrw_ssh_browse_reject."/keepjumps d") + exe "silent! g/".g:netrw_ssh_browse_reject."/keepjumps d" + endif + endif + + if w:netrw_liststyle == s:LONGLIST + " do a long listing; these substitutions need to be done prior to sorting {{{3 +" call Decho("fix long listing:") + + if s:method == "ftp" + " cleanup + exe "keepjumps ".w:netrw_bannercnt + while getline(".") =~ g:netrw_ftp_browse_reject + keepjumps d + endwhile + " if there's no ../ listed, then put ./ and ../ in + let line1= line(".") + keepjumps 1 + silent keepjumps call search('^\.\.\/\%(\s\|$\)','W') + let line2= line(".") + if line2 == 0 + exe 'keepjumps '.w:netrw_bannercnt."put='./'" + if b:netrw_curdir != '/' + exe 'keepjumps '.w:netrw_bannercnt."put='../'" + endif + endif + exe "keepjumps ".line1 + keepjumps norm! 0 + endif + + if search('^\d\{2}-\d\{2}-\d\{2}\s','n') " M$ ftp site cleanup +" call Decho("M$ ftp site listing cleanup") + exe 'silent! keepjumps '.w:netrw_bannercnt.',$s/^\(\d\{2}-\d\{2}-\d\{2}\s\+\d\+:\d\+[AaPp][Mm]\s\+\%(<DIR>\|\d\+\)\s\+\)\(\w.*\)$/\2\t\1/' + elseif exists("w:netrw_bannercnt") && w:netrw_bannercnt <= line("$") +" call Decho("normal ftp site listing cleanup: bannercnt=".w:netrw_bannercnt." line($)=".line("$")) + exe 'silent keepjumps '.w:netrw_bannercnt.',$s/ -> .*$//e' + exe 'silent keepjumps '.w:netrw_bannercnt.',$s/^\(\%(\S\+\s\+\)\{7}\S\+\)\s\+\(\S.*\)$/\2\t\1/e' + exe 'silent keepjumps '.w:netrw_bannercnt + endif + endif + +" if exists("w:netrw_bannercnt") && w:netrw_bannercnt <= line("$") " Decho +" exe "keepjumps ".w:netrw_bannercnt.',$g/^./call Decho("listing: ".getline("."))' +" endif " Decho +" call Dret("s:RemoteListing") +endfun + +" --------------------------------------------------------------------- " NetGetWord: it gets the directory named under the cursor {{{2 fun! s:NetGetWord() -" call Dfunc("NetGetWord() line#".line(".")." longlist=".g:netrw_longlist." virtcol=".virtcol(".")) +" call Dfunc("NetGetWord() line#".line(".")." liststyle=".g:netrw_liststyle." virtcol=".virtcol(".")) call s:UseBufWinVars() - " insure that w:netrw_longlist is set up - if !exists("w:netrw_longlist") - if exists("g:netrw_longlist") - let w:netrw_longlist= g:netrw_longlist + " insure that w:netrw_liststyle is set up + if !exists("w:netrw_liststyle") + if exists("g:netrw_liststyle") + let w:netrw_liststyle= g:netrw_liststyle else - let w:netrw_longlist= 0 + let w:netrw_liststyle= s:THINLIST endif -" call Decho("w:netrw_longlist=".w:netrw_longlist) +" call Decho("w:netrw_liststyle=".w:netrw_liststyle) endif if exists("w:netrw_bannercnt") && line(".") < w:netrw_bannercnt @@ -1576,34 +2534,43 @@ fun! s:NetGetWord() norm! 0 let dirname= "./" let curline= getline(".") + if curline =~ '"\s*Sorted by\s' norm s let s:netrw_skipbrowse= 1 echo 'Pressing "s" also works' + elseif curline =~ '"\s*Sort sequence:' let s:netrw_skipbrowse= 1 echo 'Press "S" to edit sorting sequence' + elseif curline =~ '"\s*Quick Help:' norm ? let s:netrw_skipbrowse= 1 echo 'Pressing "?" also works' + elseif curline =~ '"\s*\%(Hiding\|Showing\):' norm a let s:netrw_skipbrowse= 1 echo 'Pressing "a" also works' + elseif line("$") > w:netrw_bannercnt exe 'silent keepjumps '.w:netrw_bannercnt endif - elseif w:netrw_longlist == 0 + elseif w:netrw_liststyle == s:THINLIST " call Decho("thin column handling") norm! 0 let dirname= getline(".") - elseif w:netrw_longlist == 1 + elseif w:netrw_liststyle == s:LONGLIST " call Decho("long column handling") norm! 0 - let dirname= substitute(getline("."),'^\(\%(\S\+\s\)*\S\+\).\{-}$','\1','e') + let dirname= substitute(getline("."),'^\(\%(\S\+ \)*\S\+\).\{-}$','\1','e') + + elseif w:netrw_liststyle == s:TREELIST +" call Decho("treelist handling") + let dirname= substitute(getline("."),'^\(| \)*','','e') else " call Decho("obtain word from wide listing") @@ -1615,6 +2582,7 @@ fun! s:NetGetWord() " call Decho("computed cpf") endif +" call Decho("buf#".bufnr("%")."<".bufname("%").">") let filestart = (virtcol(".")/b:netrw_cpf)*b:netrw_cpf " call Decho("filestart= ([virtcol=".virtcol(".")."]/[b:netrw_cpf=".b:netrw_cpf."])*b:netrw_cpf=".filestart." bannercnt=".w:netrw_bannercnt) " call Decho("1: dirname<".dirname.">") @@ -1649,6 +2617,7 @@ fun! s:NetBrowseRm(usrhost,path) range if rmfile !~ '^"' && (rmfile =~ '@$' || rmfile !~ '[\/]$') " attempt to remove file +" call Decho("attempt to remove file") if !all echohl Statement call inputsave() @@ -1669,9 +2638,9 @@ fun! s:NetBrowseRm(usrhost,path) range silent! keepjumps .,$d call s:NetBrowseFtpCmd(a:path,"delete ".rmfile) else - let netrw_rm_cmd= substitute(g:netrw_rm_cmd,'HOSTNAME',a:usrhost,'').' "'.escape(a:path.rmfile,s:netrw_cd_escape).'"' + let netrw_rm_cmd= s:MakeSshCmd(g:netrw_rm_cmd) " call Decho("attempt to remove file: system(".netrw_rm_cmd.")") - let ret= system(netrw_rm_cmd) + let ret= s:System("system",netrw_rm_cmd) " call Decho("returned=".ret." errcode=".v:shell_error) endif elseif ok =~ 'q\%[uit]' @@ -1680,6 +2649,7 @@ fun! s:NetBrowseRm(usrhost,path) range else " attempt to remove directory +" call Decho("attempt to remove directory") if !all call inputsave() let ok= input("Confirm deletion of directory<".rmfile."> ","[{y(es)},n(o),a(ll),q(uit)] ") @@ -1697,21 +2667,21 @@ fun! s:NetBrowseRm(usrhost,path) range if exists("w:netrw_method") && (w:netrw_method == 2 || w:netrw_method == 3) call s:NetBrowseFtpCmd(a:path,"rmdir ".rmfile) else - let rmfile = a:path.rmfile - let netrw_rmdir_cmd= substitute(g:netrw_rmdir_cmd,'HOSTNAME',a:usrhost,'').' '."'".'"'.rmfile.'"'."'" + let rmfile = substitute(a:path.rmfile,'/$','','') + let netrw_rmdir_cmd = s:MakeSshCmd(g:netrw_rmdir_cmd).' '.rmfile " call Decho("attempt to remove dir: system(".netrw_rmdir_cmd.")") - let ret= system(netrw_rmdir_cmd) + let ret= s:System("system",netrw_rmdir_cmd) " call Decho("returned=".ret." errcode=".v:shell_error) if v:shell_error != 0 - let netrw_rmf_cmd= substitute(g:netrw_rmf_cmd,'HOSTNAME',a:usrhost,'').' '.substitute(rmfile,'[\/]$','','e') +" call Decho("v:shell_error not 0") + let netrw_rmf_cmd= s:MakeSshCmd(g:netrw_rmf_cmd).' '.substitute(rmfile,'[\/]$','','e') " call Decho("2nd attempt to remove dir: system(".netrw_rmf_cmd.")") - let ret= system(netrw_rmf_cmd) + let ret= s:System("system",netrw_rmf_cmd) " call Decho("returned=".ret." errcode=".v:shell_error) if v:shell_error != 0 && !exists("g:netrw_quiet") - echohl Error | echo "***netrw*** unable to remove directory<".rmfile."> -- is it empty?" | echohl None - call inputsave()|call input("Press <cr> to continue")|call inputrestore() + call netrw#ErrorMsg(s:ERROR,"unable to remove directory<".rmfile."> -- is it empty?",22) endif endif endif @@ -1724,11 +2694,10 @@ fun! s:NetBrowseRm(usrhost,path) range let ctr= ctr + 1 endwhile - " refresh the directory - let curline= line(".")-1 -" call Decho("refresh the directory") - call s:NetBrowse(s:NetBrowseChgDir(expand("%"),'./')) - exe curline + " refresh the (remote) directory listing +" call Decho("refresh remote directory listing") + call netrw#NetSavePosn() + call s:NetRefresh(0,s:NetBrowseChgDir(0,'./')) " call Dret("NetBrowseRm") endfun @@ -1740,7 +2709,7 @@ fun! s:NetBrowseRename(usrhost,path) range " preparation for removing multiple files/directories let ctr = a:firstline - let rename_cmd = substitute(g:netrw_rename_cmd,'\<HOSTNAME\>',a:usrhost,'') + let rename_cmd = s:MakeSshCmd(g:netrw_rename_cmd) " attempt to rename files/directories while ctr <= a:lastline @@ -1760,7 +2729,7 @@ fun! s:NetBrowseRename(usrhost,path) range let oldname= a:path.oldname let newname= a:path.newname " call Decho("system(rename_cmd".' "'.escape(oldname," ").'" "'.escape(newname,s:netrw_cd_escape).'"') - let ret= system(rename_cmd.' "'.escape(oldname,s:netrw_cd_escape).'" "'.escape(newname,s:netrw_cd_escape).'"') + let ret= s:System("system",rename_cmd.' "'.escape(oldname,s:netrw_cd_escape).'" "'.escape(newname,s:netrw_cd_escape).'"') endif let ctr= ctr + 1 @@ -1768,22 +2737,25 @@ fun! s:NetBrowseRename(usrhost,path) range " refresh the directory let curline= line(".") - call s:NetBrowse(s:NetBrowseChgDir(expand("%"),'./')) + call s:NetBrowse(0,s:NetBrowseChgDir(0,'./')) exe "keepjumps ".curline " call Dret("NetBrowseRename") endfun " --------------------------------------------------------------------- " NetRefresh: {{{2 -fun! s:NetRefresh(dirname,islocal) -" call Dfunc("NetRefresh(dirname<".a:dirname.">,islocal=".a:islocal.")") - call netrw#NetSavePosn() - set ma +fun! s:NetRefresh(islocal,dirname) +" call Dfunc("NetRefresh(islocal<".a:islocal.">,dirname=".a:dirname.") hide=".g:netrw_hide." sortdir=".g:netrw_sort_direction) + " at the current time (Mar 19, 2007) all calls to NetRefresh() call NetBrowseChgDir() first. + " NetBrowseChgDir() may clear the display; hence a NetSavePosn() may not work if its placed here. + " Also, NetBrowseChgDir() now does a NetSavePosn() itself. + setlocal ma noro +" call Decho("clear buffer<".expand("%")."> with :%d") %d if a:islocal - call s:LocalBrowse(a:dirname) + call netrw#LocalBrowseCheck(a:dirname) else - call s:NetBrowse(a:dirname) + call s:NetBrowse(a:islocal,a:dirname) endif call netrw#NetRestorePosn() redraw! @@ -1793,33 +2765,70 @@ endfun " --------------------------------------------------------------------- " NetSplit: mode {{{2 " =0 : net and o -" =1 : net and v -" =2 : local and o -" =3 : local and v +" =1 : net and t +" =2 : net and v +" =3 : local and o +" =4 : local and t +" =5 : local and v fun! s:NetSplit(mode) " call Dfunc("NetSplit(mode=".a:mode.") alto=".g:netrw_alto." altv=".g:netrw_altv) call s:SaveWinVars() + if a:mode == 0 + " remote and o exe (g:netrw_alto? "bel " : "abo ").g:netrw_winsize."wincmd s" - call s:CopyWinVars() - exe "norm! 0" - call s:NetBrowse(s:NetBrowseChgDir(expand("%"),s:NetGetWord())) - elseif a:mode ==1 + let s:didsplit= 1 + call s:RestoreWinVars() + call s:NetBrowse(0,s:NetBrowseChgDir(0,s:NetGetWord())) + unlet s:didsplit + + elseif a:mode == 1 + " remote and t + let cursorword = s:NetGetWord() + tabnew + let s:didsplit= 1 + call s:RestoreWinVars() + call s:NetBrowse(0,s:NetBrowseChgDir(0,cursorword)) + unlet s:didsplit + + elseif a:mode == 2 + " remote and v exe (g:netrw_altv? "rightb " : "lefta ").g:netrw_winsize."wincmd v" - call s:CopyWinVars() - exe "norm! 0" - call s:NetBrowse(s:NetBrowseChgDir(expand("%"),s:NetGetWord())) - elseif a:mode ==2 + let s:didsplit= 1 + call s:RestoreWinVars() + call s:NetBrowse(0,s:NetBrowseChgDir(0,s:NetGetWord())) + unlet s:didsplit + + elseif a:mode == 3 + " local and o exe (g:netrw_alto? "bel " : "abo ").g:netrw_winsize."wincmd s" - call s:CopyWinVars() - exe "norm! 0" - call s:LocalBrowse(s:LocalBrowseChgDir(b:netrw_curdir,s:NetGetWord())) - else + let s:didsplit= 1 + call s:RestoreWinVars() + call netrw#LocalBrowseCheck(s:NetBrowseChgDir(1,s:NetGetWord())) + unlet s:didsplit + + elseif a:mode == 4 + " local and t + let netrw_curdir= b:netrw_curdir + let cursorword = s:NetGetWord() + tabnew + let b:netrw_curdir= netrw_curdir + let s:didsplit= 1 + call s:RestoreWinVars() + call netrw#LocalBrowseCheck(s:NetBrowseChgDir(1,cursorword)) + unlet s:didsplit + + elseif a:mode == 5 + " local and v exe (g:netrw_altv? "rightb " : "lefta ").g:netrw_winsize."wincmd v" - call s:CopyWinVars() - exe "norm! 0" - call s:LocalBrowse(s:LocalBrowseChgDir(b:netrw_curdir,s:NetGetWord())) + let s:didsplit= 1 + call s:RestoreWinVars() + call netrw#LocalBrowseCheck(s:NetBrowseChgDir(1,s:NetGetWord())) + unlet s:didsplit + + else + call netrw#ErrorMsg(s:ERROR,"(NetSplit) unsupported mode=".a:mode,45) endif " call Dret("NetSplit") @@ -1845,7 +2854,7 @@ fun! netrw#NetBrowseX(fname,remote) " usually have "kdeinit" running, though... (tnx Mikolaj Machowski) if !exists("s:haskdeinit") if has("unix") - silent! let s:haskdeinit= system('ps -e') =~ 'kdeinit' + let s:haskdeinit= s:System("system",'ps -e') =~ 'kdeinit' if v:shell_error let s:haskdeinit = 0 endif @@ -1857,10 +2866,11 @@ fun! netrw#NetBrowseX(fname,remote) if a:remote == 1 " create a local copy - let fname= tempname().".".exten -" call Decho("a:remote==1: create a local copy of <".a:fname."> as <".fname.">") + let fname= fnamemodify(tempname(),":t:r").".".exten +" call Decho("a:remote=".a:remote.": create a local copy of <".a:fname."> as <".fname.">") exe "silent keepjumps bot 1new ".a:fname - set bh=delete + setlocal bh=delete +" call Decho("exe w! ".fname) exe "w! ".fname q endif @@ -1874,20 +2884,21 @@ fun! netrw#NetBrowseX(fname,remote) endif " call Decho("redir{".redir."} srr{".&srr."}") - if exists("g:netrw_browsex_viewer") && executable(g:netrw_browsex_viewer) + " execute the file handler + if exists("g:netrw_browsex_viewer") && g:netrw_browsex_viewer == '-' +" call Decho("g:netrw_browsex_viewer<".g:netrw_browsex_viewer.">") + let ret= netrwFileHandlers#Invoke(exten,fname) + + elseif exists("g:netrw_browsex_viewer") && executable(g:netrw_browsex_viewer) " call Decho("g:netrw_browsex_viewer<".g:netrw_browsex_viewer.">") - if g:netrw_browsex_viewer == '-' - let ret= netrwFileHandlers#Invoke(exten,fname) - else -" call Decho("exe silent !".g:netrw_browsex_viewer." '".escape(fname,'%#')."' ".redir) - exe "silent !".g:netrw_browsex_viewer." '".escape(fname,'%#')."'".redir - let ret= v:shell_error - endif +" call Decho("exe silent !".g:netrw_browsex_viewer." '".escape(fname,'%#')."' ".redir) + exe "silent !".g:netrw_browsex_viewer." '".escape(fname,'%#')."'".redir + let ret= v:shell_error - " execute the file handler elseif has("win32") || has("win64") " call Decho('exe silent !start rundll32 url.dll,FileProtocolHandler "'.escape(fname, '%#').'"') exe 'silent !start rundll32 url.dll,FileProtocolHandler "'.escape(fname, '%#').'"' + call inputsave()|call input("Press <cr> to continue")|call inputrestore() let ret= v:shell_error elseif has("unix") && executable("gnome-open") && !s:haskdeinit @@ -1917,11 +2928,14 @@ fun! netrw#NetBrowseX(fname,remote) " return to prior buffer (directory listing) if a:remote == 1 && fname != a:fname " call Decho("deleting temporary file<".fname.">") - call delete(fname) + call s:System("delete",fname) endif if a:remote == 1 - set bh=delete bt=nofile noswf + setlocal bh=delete bt=nofile + if g:netrw_use_noswf + setlocal noswf + endif exe "norm! \<c-o>" redraw! endif @@ -1936,32 +2950,35 @@ endfun " enforced here. fun! s:NetBrowseFtpCmd(path,listcmd) " call Dfunc("NetBrowseFtpCmd(path<".a:path."> listcmd<".a:listcmd.">) netrw_method=".w:netrw_method) +" call Decho("line($)=".line("$")." bannercnt=".w:netrw_bannercnt) " because WinXX ftp uses unix style input - " curline is one more than the bannercnt in order to account - " for the unwanted first blank line (doing a :put to an empty - " buffer yields a blank first line) let ffkeep= &ff - setlocal ma ff=unix - let curline= w:netrw_bannercnt+1 - exe "silent! keepjumps ".curline.",$d" + setlocal ma ff=unix noro + + " clear off any older non-banner lines + " note that w:netrw_bannercnt indexes the line after the banner +" call Decho('exe silent! keepjumps '.w:netrw_bannercnt.",$d (clear off old non-banner lines)") + exe "silent! keepjumps ".w:netrw_bannercnt.",$d" "......................................... if w:netrw_method == 2 || w:netrw_method == 5 " ftp + <.netrc>: Method #2 if a:path != "" put ='cd \"'.a:path.'\"' -" call Decho('ftp: '.getline(".")) + endif + if exists("g:netrw_ftpextracmd") + exe "put ='".g:netrw_ftpextracmd."'" +" call Decho("filter input: ".getline(".")) endif exe "put ='".a:listcmd."'" -" call Decho("ftp: ".getline(".")) -" redraw!|call inputsave()|call input("Pausing...")|call inputrestore() +" exe w:netrw_bannercnt.',$g/^./call Decho("ftp#".line(".").": ".getline("."))' if exists("g:netrw_port") && g:netrw_port != "" -" call Decho("exe ".g:netrw_silentxfer.curline.",$!".g:netrw_ftp_cmd." -i ".g:netrw_machine." ".g:netrw_port) - exe g:netrw_silentxfer.curline.",$!".g:netrw_ftp_cmd." -i ".g:netrw_machine." ".g:netrw_port +" call Decho("exe ".g:netrw_silentxfer.w:netrw_bannercnt.",$!".g:netrw_ftp_cmd." -i ".g:netrw_machine." ".g:netrw_port) + exe g:netrw_silentxfer.w:netrw_bannercnt.",$!".g:netrw_ftp_cmd." -i ".g:netrw_machine." ".g:netrw_port else -" call Decho("exe ".g:netrw_silentxfer.curline.",$!".g:netrw_ftp_cmd." -i ".g:netrw_machine) - exe g:netrw_silentxfer.curline.",$!".g:netrw_ftp_cmd." -i ".g:netrw_machine +" call Decho("exe ".g:netrw_silentxfer.w:netrw_bannercnt.",$!".g:netrw_ftp_cmd." -i ".g:netrw_machine) + exe g:netrw_silentxfer.w:netrw_bannercnt.",$!".g:netrw_ftp_cmd." -i ".g:netrw_machine endif "......................................... @@ -1984,41 +3001,46 @@ fun! s:NetBrowseFtpCmd(path,listcmd) if a:path != "" put ='cd \"'.a:path.'\"' endif + if exists("g:netrw_ftpextracmd") + exe "put ='".g:netrw_ftpextracmd."'" +" call Decho("filter input: ".getline(".")) + endif exe "put ='".a:listcmd."'" " perform ftp: " -i : turns off interactive prompting from ftp " -n unix : DON'T use <.netrc>, even though it exists " -n win32: quit being obnoxious about password -" call Decho("exe ".g:netrw_silentxfer.curline.",$!".g:netrw_ftp_cmd." -i -n") - exe g:netrw_silentxfer.curline.",$!".g:netrw_ftp_cmd." -i -n" +" exe w:netrw_bannercnt.',$g/^./call Decho("ftp#".line(".").": ".getline("."))' +" call Decho("exe ".g:netrw_silentxfer.w:netrw_bannercnt.",$!".g:netrw_ftp_cmd." -i -n") + exe g:netrw_silentxfer.w:netrw_bannercnt.",$!".g:netrw_ftp_cmd." -i -n" "......................................... else - echo "***warning*** unable to comply with your request<" . choice . ">" + call netrw#ErrorMsg(s:WARNING,"unable to comply with your request<" . choice . ">",23) endif " cleanup for Windows if has("win32") || has("win95") || has("win64") || has("win16") - silent! keepjumps! %s/\r$//e + silent! keepjumps %s/\r$//e endif if a:listcmd == "dir" " infer directory/link based on the file permission string silent! keepjumps g/d\%([-r][-w][-x]\)\{3}/s@$@/@ silent! keepjumps g/l\%([-r][-w][-x]\)\{3}/s/$/@/ - if w:netrw_longlist == 0 || w:netrw_longlist == 2 - exe "silent! keepjumps ".curline.',$s/^\%(\S\+\s\+\)\{8}//e' + if w:netrw_liststyle == s:THINLIST || w:netrw_liststyle == s:WIDELIST || w:netrw_liststyle == s:TREELIST + exe "silent! keepjumps ".w:netrw_bannercnt.',$s/^\%(\S\+\s\+\)\{8}//e' endif endif - " ftp's ls doesn't seem to include ./ or ../ - if !search('^\.\/$','wn') - exe 'keepjumps '.curline - if a:path !~ '^$' - put ='../' - endif + " ftp's listing doesn't seem to include ./ or ../ + if !search('^\.\/$\|\s\.\/$','wn') + exe 'keepjumps '.w:netrw_bannercnt put ='./' - exe 'keepjumps '.curline + endif + if !search('^\.\.\/$\|\s\.\.\/$','wn') + exe 'keepjumps '.w:netrw_bannercnt + put ='../' endif " restore settings @@ -2027,15 +3049,17 @@ fun! s:NetBrowseFtpCmd(path,listcmd) endfun " --------------------------------------------------------------------- -" NetrwListHide: uses [range]g~...~d to delete files that match comma {{{2 +" NetListHide: uses [range]g~...~d to delete files that match comma {{{2 " separated patterns given in g:netrw_list_hide -fun! s:NetrwListHide() -" call Dfunc("NetrwListHide() hide=".g:netrw_hide." listhide<".g:netrw_list_hide.">") +fun! s:NetListHide() +" call Dfunc("NetListHide() hide=".g:netrw_hide." listhide<".g:netrw_list_hide.">") - " find a character not in the "hide" string to used as a separator - " for :g and :v commands + " find a character not in the "hide" string to use as a separator for :g and :v commands + " How-it-works: take the hiding command, convert it into a range. Duplicate + " characters don't matter. Remove all such characters from the '/~...90' + " string. Use the first character left as a separator character. let listhide= g:netrw_list_hide - let sep = strpart(substitute('~!@#$%^&*{};:,<.>/?|abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890','['.escape(listhide,'-]^\').']','','ge'),1,1) + let sep = strpart(substitute('/~@#$%^&*{};:,<.>?|1234567890','['.escape(listhide,'-]^\').']','','ge'),1,1) " call Decho("sep=".sep) while listhide != "" @@ -2061,7 +3085,7 @@ fun! s:NetrwListHide() exe 'silent keepjumps '.w:netrw_bannercnt.',$s@^\%( /-KEEP-/ \)\+@@e' endif -" call Dret("NetrwListHide") +" call Dret("NetListHide") endfun " --------------------------------------------------------------------- @@ -2069,6 +3093,9 @@ endfun fun! s:NetHideEdit(islocal) " call Dfunc("NetHideEdit(islocal=".a:islocal.")") + " save current cursor position + let s:nhe_curpos= getpos(".") + " get new hiding list from user call inputsave() let newhide= input("Edit Hiding List: ",g:netrw_list_hide) @@ -2077,19 +3104,19 @@ fun! s:NetHideEdit(islocal) " call Decho("new g:netrw_list_hide<".g:netrw_list_hide.">") " refresh the listing - if a:islocal == 0 - silent call s:NetBrowse(s:NetBrowseChgDir(expand("%"),'./')) - else - silent call s:NetRefresh(s:LocalBrowseChgDir(b:netrw_curdir,"./"),a:islocal) - endif + silent call s:NetRefresh(a:islocal,s:NetBrowseChgDir(a:islocal,"./")) + + " restore cursor position + call setpos('.',s:nhe_curpos) + unlet s:nhe_curpos " call Dret("NetHideEdit") endfun " --------------------------------------------------------------------- " NetSortSequence: allows user to edit the sorting sequence -fun! s:NetSortSequence(mode) -" call Dfunc("NetSortSequence(mode=".a:mode.")") +fun! s:NetSortSequence(islocal) +" call Dfunc("NetSortSequence(islocal=".a:islocal.")") call inputsave() let newsortseq= input("Edit Sorting Sequence: ",g:netrw_sort_sequence) @@ -2097,77 +3124,87 @@ fun! s:NetSortSequence(mode) " refresh the listing let g:netrw_sort_sequence= newsortseq - if a:mode == 0 - silent call s:NetBrowse(s:NetBrowseChgDir(expand("%"),'./')) - else - silent call s:LocalBrowse(s:LocalBrowseChgDir(b:netrw_curdir,"./")) - endif + call netrw#NetSavePosn() + call s:NetRefresh(a:islocal,s:NetBrowseChgDir(a:islocal,'./')) " call Dret("NetSortSequence") endfun " --------------------------------------------------------------------- -" NetLongList: {{{2 -fun! s:NetLongList(mode) -" call Dfunc("NetLongList(mode=".a:mode.") netrw_longlist=".w:netrw_longlist) - let fname = s:NetGetWord() - let w:netrw_longlist = (w:netrw_longlist + 1) % 3 +" NetListStyle: {{{2 +" islocal=0: remote browsing +" =1: local browsing +fun! s:NetListStyle(islocal) +" call Dfunc("NetListStyle(islocal=".a:islocal.") w:netrw_liststyle=".w:netrw_liststyle) + let fname = s:NetGetWord() + if !exists("w:netrw_liststyle")|let w:netrw_liststyle= g:netrw_liststyle|endif + let w:netrw_liststyle = (w:netrw_liststyle + 1) % s:MAXLIST " call Decho("fname<".fname.">") +" call Decho("chgd w:netrw_liststyle to ".w:netrw_liststyle) +" call Decho("b:netrw_curdir<".(exists("b:netrw_curdir")? b:netrw_curdir : "doesn't exist").">") - if w:netrw_longlist == 0 + if w:netrw_liststyle == s:THINLIST " use one column listing " call Decho("use one column list") let g:netrw_list_cmd = substitute(g:netrw_list_cmd,' -l','','ge') - elseif w:netrw_longlist == 1 + elseif w:netrw_liststyle == s:LONGLIST " use long list " call Decho("use long list") let g:netrw_list_cmd = g:netrw_list_cmd." -l" - else + elseif w:netrw_liststyle == s:WIDELIST " give wide list " call Decho("use wide list") let g:netrw_list_cmd = substitute(g:netrw_list_cmd,' -l','','ge') + + elseif w:netrw_liststyle == s:TREELIST +" call Decho("use tree list") + let g:netrw_list_cmd = substitute(g:netrw_list_cmd,' -l','','ge') + + else + call netrw#ErrorMsg(s:WARNING,"bad value for g:netrw_liststyle (=".w:netrw_liststyle.")",46) + let g:netrw_liststyle = s:THINLIST + let w:netrw_liststyle = g:netrw_liststyle + let g:netrw_list_cmd = substitute(g:netrw_list_cmd,' -l','','ge') endif - setlocal ma + setlocal ma noro - " clear buffer - this will cause NetBrowse/LocalBrowse to do a refresh + " clear buffer - this will cause NetBrowse/LocalBrowseCheck to do a refresh +" call Decho("clear buffer<".expand("%")."> with :%d") %d " refresh the listing - if a:mode == 0 - silent call s:NetBrowse(s:NetBrowseChgDir(expand("%"),"./")) - else - silent call s:LocalBrowse(s:LocalBrowseChgDir(b:netrw_curdir,"./")) - endif + call netrw#NetSavePosn() + call s:NetRefresh(a:islocal,s:NetBrowseChgDir(a:islocal,'./')) " keep cursor on the filename silent keepjumps $ - if fname =~ '/$' - silent call search('\%(^\|\s\{2,}\)\zs'.escape(fname,'.\[]*$^').'\%(\s\{2,}\|$\)','bW') - else - silent call search('\%(^\|\s\{2,}\)\zs'.escape(fname,'.\[]*$^').'\%(\s\{2,}\|$\)','bW') + let result= search('\%(^\%(|\+\s\)\=\|\s\{2,}\)\zs'.escape(fname,'.\[]*$^').'\%(\s\{2,}\|$\)','bc') +" call Decho("search result=".result." w:netrw_bannercnt=".(exists("w:netrw_bannercnt")? w:netrw_bannercnt : 'N/A')) + if result <= 0 && exists("w:netrw_bannercnt") + exe w:netrw_bannercnt endif -" call Dret("NetLongList : w:netrw_longlist=".w:netrw_longlist) +" call Dret("NetListStyle".(exists("w:netrw_liststyle")? ' : w:netrw_liststyle='.w:netrw_liststyle : "")) endfun " --------------------------------------------------------------------- -" NetrwWideListing: {{{2 -fun! s:NetrwWideListing() +" NetWideListing: {{{2 +fun! s:NetWideListing() - if w:netrw_longlist == 2 -" call Dfunc("NetrwWideListing() w:netrw_longlist=".w:netrw_longlist) + if w:netrw_liststyle == s:WIDELIST +" call Dfunc("NetWideListing() w:netrw_liststyle=".w:netrw_liststyle.' fo='.&fo.' l:fo='.&l:fo) " look for longest filename (cpf=characters per filename) " cpf: characters per file " fpl: files per line " fpc: files per column - set ma + setlocal ma noro let b:netrw_cpf= 0 if line("$") >= w:netrw_bannercnt exe 'silent keepjumps '.w:netrw_bannercnt.',$g/^./if virtcol("$") > b:netrw_cpf|let b:netrw_cpf= virtcol("$")|endif' else -" call Dret("NetrwWideListing") +" call Dret("NetWideListing") return endif " call Decho("max file strlen+1=".b:netrw_cpf) @@ -2181,11 +3218,12 @@ fun! s:NetrwWideListing() " call Decho("fpl= ".winwidth(0)."/[b:netrw_cpf=".b:netrw_cpf.']='.w:netrw_fpl) " make wide display - exe 'silent keepjumps '.w:netrw_bannercnt.',$s/^.*$/\=printf("%-'.b:netrw_cpf.'s",escape(submatch(0),"\\"))/' + exe 'silent keepjumps '.w:netrw_bannercnt.',$s/^.*$/\=escape(printf("%-'.b:netrw_cpf.'s",submatch(0)),"\\")/' let fpc = (line("$") - w:netrw_bannercnt + w:netrw_fpl)/w:netrw_fpl let newcolstart = w:netrw_bannercnt + fpc let newcolend = newcolstart + fpc - 1 " call Decho("bannercnt=".w:netrw_bannercnt." fpl=".w:netrw_fpl." fpc=".fpc." newcol[".newcolstart.",".newcolend."]") + silent! let keepregstar = @* while line("$") >= newcolstart if newcolend > line("$") | let newcolend= line("$") | endif let newcolqty= newcolend - newcolstart @@ -2198,14 +3236,187 @@ fun! s:NetrwWideListing() exe "silent keepjumps ".newcolstart.','.newcolend.'d' exe 'silent keepjumps '.w:netrw_bannercnt endwhile + silent! let @*= keepregstar exe "silent keepjumps ".w:netrw_bannercnt.',$s/\s\+$//e' - setlocal noma nomod -" call Dret("NetrwWideListing") + setlocal noma nomod ro +" call Dret("NetWideListing") endif endfun " --------------------------------------------------------------------- +" NetTreeDir: determine tree directory given current cursor position {{{2 +" (full path directory with trailing slash returned) +fun! s:NetTreeDir() +" call Dfunc("NetTreeDir() curline#".line(".")."<".getline(".")."> b:netrw_curdir<".b:netrw_curdir."> tab#".tabpagenr()." win#".winnr()." buf#".bufnr("%")) + + let treedir= b:netrw_curdir +" call Decho("set initial treedir<".treedir.">") + let s:treecurpos= getpos(".") + + if w:netrw_liststyle == s:TREELIST +" call Decho("w:netrrw_liststyle is TREELIST:") +" call Decho("line#".line(".")." getline(.)<".getline('.')."> treecurpos<".string(s:treecurpos).">") + if getline('.') =~ '/$' + let treedir= substitute(getline('.'),'^\%(| \)*\([^|].\{-}\)$','\1','e') + else + let treedir= "" + endif + +" call Decho("treedir<".treedir.">") + + " detect user attempting to close treeroot + if getline('.') !~ '|' && getline('.') != '..' +" call Decho("user attempted to close treeroot") + " now force a refresh +" call Decho("clear buffer<".expand("%")."> with :%d") + keepjumps %d +" call Dret("NetTreeDir <".treedir."> : (side effect) s:treecurpos<".string(s:treecurpos).">") + return b:netrw_curdir + endif + + " elide all non-depth information + let depth = substitute(getline('.'),'^\(\%(| \)*\)[^|].\{-}$','\1','e') +" call Decho("depth<".depth."> 1st subst") + + " elide first depth + let depth = substitute(depth,'^| ','','') +" call Decho("depth<".depth."> 2nd subst") + + " construct treedir by searching backwards at correct depth +" call Decho("constructing treedir<".treedir."> depth<".depth.">") + while depth != "" && search('^'.depth.'[^|].\{-}/$','bW') + let dirname= substitute(getline("."),'^\(| \)*','','e') + let treedir= dirname.treedir + let depth = substitute(depth,'^| ','','') +" call Decho("constructing treedir<".treedir.">: dirname<".dirname."> while depth<".depth.">") + endwhile + if w:netrw_treetop =~ '/$' + let treedir= w:netrw_treetop.treedir + else + let treedir= w:netrw_treetop.'/'.treedir + endif +" call Decho("bufnr(.)=".bufnr(".")." line($)=".line("$")." line(.)=".line(".")) + endif + let treedir= substitute(treedir,'//$','/','') + +" " now force a refresh +" call Decho("clear buffer<".expand("%")."> with :%d") +" setlocal ma noro +" keepjumps %d + +" call Dret("NetTreeDir <".treedir."> : (side effect) s:treecurpos<".string(s:treecurpos).">") + return treedir +endfun + +" --------------------------------------------------------------------- +" NetTreeDisplay: recursive tree display {{{2 +fun! s:NetTreeDisplay(dir,depth) +" call Dfunc("NetTreeDisplay(dir<".a:dir."> depth<".a:depth.">)") + + " insure that there are no folds + setlocal nofen + + " install ../ and shortdir + if a:depth == "" + call setline(line("$")+1,'../') +" call Decho("setline#".line("$")." ../ (depth is zero)") + endif + if a:dir =~ '^\a\+://' + if a:dir == w:netrw_treetop + let shortdir= a:dir + else + let shortdir= substitute(a:dir,'^.*/\([^/]\+\)/$','\1/','e') + endif + call setline(line("$")+1,a:depth.shortdir) + else + let shortdir= substitute(a:dir,'^.*/','','e') + call setline(line("$")+1,a:depth.shortdir.'/') + endif +" call Decho("setline#".line("$")." shortdir<".a:depth.shortdir.">") + + " append a / to dir if its missing one + let dir= a:dir + if dir !~ '/$' + let dir= dir.'/' + endif + + " display subtrees (if any) + let depth= "| ".a:depth +" call Decho("display subtrees with depth<".depth."> and current leaves") + for entry in w:netrw_treedict[a:dir] + let direntry= substitute(dir.entry,'/$','','e') +" call Decho("dir<".dir."> entry<".entry."> direntry<".direntry.">") + if entry =~ '/$' && has_key(w:netrw_treedict,direntry) +" call Decho("<".direntry."> is a key in treedict - display subtree for it") + call s:NetTreeDisplay(direntry,depth) + elseif entry =~ '/$' && has_key(w:netrw_treedict,direntry.'/') +" call Decho("<".direntry."/> is a key in treedict - display subtree for it") + call s:NetTreeDisplay(direntry.'/',depth) + else +" call Decho("<".entry."> is not a key in treedict (no subtree)") + call setline(line("$")+1,depth.entry) + endif + endfor +" call Dret("NetTreeDisplay") +endfun + +" --------------------------------------------------------------------- +" NetTreeListing: displays tree listing from treetop on down, using NetTreeDisplay() {{{2 +fun! s:NetTreeListing(dirname) + if w:netrw_liststyle == s:TREELIST +" call Dfunc("NetTreeListing() bufname<".expand("%").">") +" call Decho("curdir<".a:dirname.">") + + " update the treetop +" call Decho("update the treetop") + if !exists("w:netrw_treetop") + let w:netrw_treetop= a:dirname +" call Decho("w:netrw_treetop<".w:netrw_treetop."> (reusing)") + elseif (w:netrw_treetop =~ ('^'.a:dirname) && strlen(a:dirname) < strlen(w:netrw_treetop)) || a:dirname !~ ('^'.w:netrw_treetop) + let w:netrw_treetop= a:dirname +" call Decho("w:netrw_treetop<".w:netrw_treetop."> (went up)") + endif + + " insure that we have at least an empty treedict + if !exists("w:netrw_treedict") + let w:netrw_treedict= {} + endif + + " update the directory listing for the current directory +" call Decho("updating dictionary with ".a:dirname.":[..directory listing..]") +" call Decho("bannercnt=".w:netrw_bannercnt." line($)=".line("$")) + exe "silent! keepjumps ".w:netrw_bannercnt.',$g@^\.\.\=/$@d' + let w:netrw_treedict[a:dirname]= getline(w:netrw_bannercnt,line("$")) +" call Decho("treedict=".string(w:netrw_treedict)) + exe "silent! keepjumps ".w:netrw_bannercnt.",$d" + + " if past banner, record word + if exists("w:netrw_bannercnt") && line(".") > w:netrw_bannercnt + let fname= expand("<cword>") + else + let fname= "" + endif + + " display from treetop on down + call s:NetTreeDisplay(w:netrw_treetop,"") + + " place cursor + if !exists("s:nbcd_curpos") + if fname != "" +" call Decho("(NetTreeListing) place cursor <".fname.">") + call search('\<'.fname.'\>','cw') + elseif exists("w:netrw_bannercnt") + exe (w:netrw_bannercnt+1) +" call Decho("(NetTreeListing) place cursor line#".(w:netrw_bannercnt+1)) + endif + endif + +" call Dret("NetTreeListing : bufname<".expand("%").">") + endif +endfun + +" --------------------------------------------------------------------- " NetSaveWordPosn: used by the "s" command in both remote and local {{{2 " browsing. Along with NetRestoreWordPosn(), it keeps the cursor on " the same word even though the sorting has changed its order of appearance. @@ -2249,16 +3460,14 @@ fun! s:NetMakeDir(usrhost) " call Decho("fullnewdir<".fullnewdir.">") if isdirectory(fullnewdir) if !exists("g:netrw_quiet") - echohl WarningMsg | echo "***netrw*** <".newdirname."> is already a directory!" | echohl None - call inputsave()|call input("Press <cr> to continue")|call inputrestore() + call netrw#ErrorMsg(s:WARNING,"<".newdirname."> is already a directory!",24) endif " call Dret("NetMakeDir : directory<".newdirname."> exists previously") return endif - if filereadable(fullnewdir) + if s:FileReadable(fullnewdir) if !exists("g:netrw_quiet") - echohl WarningMsg | echo "***netrw*** <".newdirname."> is already a file!" | echohl None - call inputsave()|call input("Press <cr> to continue")|call inputrestore() + call netrw#ErrorMsg(s:WARNING,"<".newdirname."> is already a file!",25) endif " call Dret("NetMakeDir : file<".newdirname."> exists previously") return @@ -2272,8 +3481,8 @@ fun! s:NetMakeDir(usrhost) let netrw_origdir= s:NetGetcwd(1) exe 'keepjumps cd '.b:netrw_curdir " call Decho("netrw_origdir<".netrw_origdir.">: cd b:netrw_curdir<".b:netrw_curdir.">") -" call Decho("exe silent! !".g:netrw_local_mkdir.' "'.newdirname.'"') - exe "silent! !".g:netrw_local_mkdir.' "'.newdirname.'"' +" call Decho("exe silent! !".g:netrw_local_mkdir.' '.g:netrw_shq.newdirname.g:netrw_shq) + exe "silent! !".g:netrw_local_mkdir.' '.g:netrw_shq.newdirname.g:netrw_shq if !g:netrw_keepdir | exe 'keepjumps cd '.netrw_origdir | endif if !g:netrw_keepdir exe 'keepjumps cd '.netrw_origdir @@ -2284,36 +3493,25 @@ fun! s:NetMakeDir(usrhost) if v:shell_error == 0 " refresh listing " call Decho("refresh listing") - let linenum= line(".") - norm! H0 - let hline = line(".") - set ma|norm! 2D - call s:LocalBrowse(s:LocalBrowseChgDir(b:netrw_curdir,'./')) - exe "norm! ".hline."G0z\<CR>" - exe linenum + call netrw#NetSavePosn() + call s:NetRefresh(1,s:NetBrowseChgDir(1,'./')) elseif !exists("g:netrw_quiet") - echohl Error | echo "***netrw*** unable to make directory<".newdirname.">" | echohl None - call inputsave()|call input("Press <cr> to continue")|call inputrestore() + call netrw#ErrorMsg(s:ERROR,"unable to make directory<".newdirname.">",26) endif redraw! else " Remote mkdir: - let mkdircmd = substitute(g:netrw_mkdir_cmd,'\<HOSTNAME\>',a:usrhost,'') - let newdirname= "'".'"'.substitute(expand("%"),'^\%(.\{-}/\)\{3}\(.*\)$','\1','').newdirname.'"'."'" -" call Decho("exe silent! !".mkdircmd." ".newdirname) - exe "silent! !".mkdircmd." ".newdirname + let mkdircmd = s:MakeSshCmd(g:netrw_mkdir_cmd) + let newdirname= substitute(b:netrw_curdir,'^\%(.\{-}/\)\{3}\(.*\)$','\1','').newdirname +" call Decho("exe silent! !".mkdircmd." ".g:netrw_shq.newdirname.g:netrw_shq) + exe "silent! !".mkdircmd." ".g:netrw_shq.newdirname.g:netrw_shq if v:shell_error == 0 " refresh listing - let linenum= line(".") - norm! H0 - let hline = line(".") - call s:NetBrowse(s:NetBrowseChgDir(expand("%"),'./')) - exe "norm! ".hline."G0z\<CR>" - exe linenum + call netrw#NetSavePosn() + call s:NetRefresh(0,s:NetBrowseChgDir(0,'./')) elseif !exists("g:netrw_quiet") - echohl Error | echo "***netrw*** unable to make directory<".newdirname.">" | echohl None - call inputsave()|call input("Press <cr> to continue")|call inputrestore() + call netrw#ErrorMsg(s:ERROR,"unable to make directory<".newdirname.">",27) endif redraw! endif @@ -2326,36 +3524,33 @@ endfun " 0: (user: <b>) bookmark current directory " 1: (user: <B>) change to the bookmarked directory " 2: (user: <q>) list bookmarks -" 3: (LocalBrowse) record current directory history +" 3: (browsing) record current directory history " 4: (user: <u>) go up (previous) bookmark " 5: (user: <U>) go down (next) bookmark fun! s:NetBookmarkDir(chg,curdir) -" call Dfunc("NetBookmarkDir(chg=".a:chg." curdir<".a:curdir.">) cnt=".v:count) - if exists("w:netrw_bannercnt") && line(".") <= w:netrw_bannercnt - " looks like a "b" was pressed while in the banner region - if line("$") > w:netrw_bannercnt - exe 'silent keepjumps '.w:netrw_bannercnt - endif - if &ch > 1 - " "clear" the message - echo "" - endif -" call Dret("NetBookmarkDir - ignoring") - return - endif +" call Dfunc("NetBookmarkDir(chg=".a:chg." curdir<".a:curdir.">) cnt=".v:count." bookmarkcnt=".g:NETRW_BOOKMARKMAX." histcnt=".g:NETRW_DIRHIST_CNT." bookmax=".g:NETRW_BOOKMARKMAX." histmax=".g:netrw_dirhistmax) if a:chg == 0 " bookmark the current directory - let g:NETRW_BOOKMARKDIR_{v:count}= a:curdir - if !exists("g:NETRW_BOOKMARKMAX") - let g:NETRW_BOOKMARKMAX= v:count - elseif v:count > g:NETRW_BOOKMARKMAX - let g:NETRW_BOOKMARKMAX= v:count +" call Decho("(user: <b>) bookmark the current directory") + if v:count > 0 + " handle bookmark# specified via the count + let g:NETRW_BOOKMARKDIR_{v:count}= a:curdir + if !exists("g:NETRW_BOOKMARKMAX") + let g:NETRW_BOOKMARKMAX= v:count + elseif v:count > g:NETRW_BOOKMARKMAX + let g:NETRW_BOOKMARKMAX= v:count + endif + else + " handle no count specified + let g:NETRW_BOOKMARKMAX = g:NETRW_BOOKMARKMAX + 1 + let g:NETRW_BOOKMARKDIR_{g:NETRW_BOOKMARKMAX} = a:curdir endif echo "bookmarked the current directory" elseif a:chg == 1 " change to the bookmarked directory +" call Decho("(user: <B>) change to the bookmarked directory") if exists("g:NETRW_BOOKMARKDIR_{v:count}") exe "e ".g:NETRW_BOOKMARKDIR_{v:count} else @@ -2363,7 +3558,10 @@ fun! s:NetBookmarkDir(chg,curdir) endif elseif a:chg == 2 + redraw! + let didwork= 0 " list user's bookmarks +" call Decho("(user: <q>) list user's bookmarks") if exists("g:NETRW_BOOKMARKMAX") " call Decho("list bookmarks [0,".g:NETRW_BOOKMARKMAX."]") let cnt= 0 @@ -2371,6 +3569,7 @@ fun! s:NetBookmarkDir(chg,curdir) if exists("g:NETRW_BOOKMARKDIR_{cnt}") " call Decho("Netrw Bookmark#".cnt.": ".g:NETRW_BOOKMARKDIR_{cnt}) echo "Netrw Bookmark#".cnt.": ".g:NETRW_BOOKMARKDIR_{cnt} + let didwork= 1 endif let cnt= cnt + 1 endwhile @@ -2386,6 +3585,7 @@ fun! s:NetBookmarkDir(chg,curdir) if exists("g:NETRW_DIRHIST_{cnt}") " call Decho("Netrw History#".histcnt.": ".g:NETRW_DIRHIST_{cnt}) echo "Netrw History#".histcnt.": ".g:NETRW_DIRHIST_{cnt} + let didwork= 1 endif let first = 0 let cnt = ( cnt - 1 ) % g:netrw_dirhistmax @@ -2393,24 +3593,36 @@ fun! s:NetBookmarkDir(chg,curdir) let cnt= cnt + g:netrw_dirhistmax endif endwhile + if didwork + call inputsave()|call input("Press <cr> to continue")|call inputrestore() + endif elseif a:chg == 3 " saves most recently visited directories (when they differ) +" call Decho("(browsing) record curdir history") if !exists("g:NETRW_DIRHIST_0") || g:NETRW_DIRHIST_{g:NETRW_DIRHIST_CNT} != a:curdir let g:NETRW_DIRHIST_CNT= ( g:NETRW_DIRHIST_CNT + 1 ) % g:netrw_dirhistmax - let g:NETRW_DIRHIST_{g:NETRW_DIRHIST_CNT}= substitute(a:curdir,'[/\\]$','','e') +" let g:NETRW_DIRHIST_{g:NETRW_DIRHIST_CNT}= substitute(a:curdir,'[/\\]$','','e') + let g:NETRW_DIRHIST_{g:NETRW_DIRHIST_CNT}= a:curdir " call Decho("save dirhist#".g:NETRW_DIRHIST_CNT."<".g:NETRW_DIRHIST_{g:NETRW_DIRHIST_CNT}.">") endif elseif a:chg == 4 " u: change to the previous directory stored on the history list +" call Decho("(user: <u>) chg to prev dir from history") let g:NETRW_DIRHIST_CNT= ( g:NETRW_DIRHIST_CNT - 1 ) % g:netrw_dirhistmax if g:NETRW_DIRHIST_CNT < 0 let g:NETRW_DIRHIST_CNT= g:NETRW_DIRHIST_CNT + g:netrw_dirhistmax endif if exists("g:NETRW_DIRHIST_{g:NETRW_DIRHIST_CNT}") " call Decho("changedir u#".g:NETRW_DIRHIST_CNT."<".g:NETRW_DIRHIST_{g:NETRW_DIRHIST_CNT}.">") - exe "e ".g:NETRW_DIRHIST_{g:NETRW_DIRHIST_CNT} + if exists("w:netrw_liststyle") && w:netrw_liststyle == s:TREELIST && exists("b:netrw_curdir") + setlocal ma noro + %d + setlocal nomod + endif +" call Decho("exe e! ".g:NETRW_DIRHIST_{g:NETRW_DIRHIST_CNT}) + exe "e! ".g:NETRW_DIRHIST_{g:NETRW_DIRHIST_CNT} else let g:NETRW_DIRHIST_CNT= ( g:NETRW_DIRHIST_CNT + 1 ) % g:netrw_dirhistmax echo "Sorry, no predecessor directory exists yet" @@ -2418,10 +3630,17 @@ fun! s:NetBookmarkDir(chg,curdir) elseif a:chg == 5 " U: change to the subsequent directory stored on the history list +" call Decho("(user: <U>) chg to next dir from history") let g:NETRW_DIRHIST_CNT= ( g:NETRW_DIRHIST_CNT + 1 ) % g:netrw_dirhistmax if exists("g:NETRW_DIRHIST_{g:NETRW_DIRHIST_CNT}") " call Decho("changedir U#".g:NETRW_DIRHIST_CNT."<".g:NETRW_DIRHIST_{g:NETRW_DIRHIST_CNT}.">") - exe "e ".g:NETRW_DIRHIST_{g:NETRW_DIRHIST_CNT} + if exists("w:netrw_liststyle") && w:netrw_liststyle == s:TREELIST && exists("b:netrw_curdir") + setlocal ma noro + %d + setlocal nomod + endif +" call Decho("exe e! ".g:NETRW_DIRHIST_{g:NETRW_DIRHIST_CNT}) + exe "e! ".g:NETRW_DIRHIST_{g:NETRW_DIRHIST_CNT} else let g:NETRW_DIRHIST_CNT= ( g:NETRW_DIRHIST_CNT - 1 ) % g:netrw_dirhistmax if g:NETRW_DIRHIST_CNT < 0 @@ -2430,39 +3649,93 @@ fun! s:NetBookmarkDir(chg,curdir) echo "Sorry, no successor directory exists yet" endif endif + call s:NetBookmarkMenu() " call Dret("NetBookmarkDir") endfun " --------------------------------------------------------------------- +" NetBookmarkMenu: {{{2 +fun! s:NetBookmarkMenu() + if !exists("s:netrw_menucnt") + return + endif +" call Dfunc("NetBookmarkMenu() bookmarkcnt=".g:NETRW_BOOKMARKMAX." histcnt=".g:NETRW_DIRHIST_CNT." menucnt=".s:netrw_menucnt) + if has("menu") && has("gui_running") && &go =~ 'm' + if exists("g:NetrwTopLvlMenu") + exe 'silent! unmenu '.g:NetrwTopLvlMenu.'Bookmark' + endif + + " show bookmarked places + let cnt = 0 + while cnt <= g:NETRW_BOOKMARKMAX + if exists("g:NETRW_BOOKMARKDIR_{cnt}") + let bmdir= escape(g:NETRW_BOOKMARKDIR_{cnt},'.') +" call Decho('silent! menu '.g:NetrwMenuPriority.".2.".cnt." ".g:NetrwTopLvlMenu.'Bookmark.'.bmdir.' :e '.g:NETRW_BOOKMARKDIR_{cnt}) + exe 'silent! menu '.g:NetrwMenuPriority.".2.".cnt." ".g:NetrwTopLvlMenu.'Bookmarks.'.bmdir.' :e '.g:NETRW_BOOKMARKDIR_{cnt}."\<cr>" + endif + let cnt= cnt + 1 + endwhile + + " show directory browsing history + let cnt = g:NETRW_DIRHIST_CNT + let first = 1 + let histcnt = 0 + while ( first || cnt != g:NETRW_DIRHIST_CNT ) + let histcnt = histcnt + 1 + let priority = g:NETRW_DIRHIST_CNT + histcnt + if exists("g:NETRW_DIRHIST_{cnt}") + let bmdir= escape(g:NETRW_DIRHIST_{cnt},'.') +" call Decho('silent! menu '.g:NetrwMenuPriority.".3.".priority." ".g:NetrwTopLvlMenu.'History.'.bmdir.' :e '.g:NETRW_DIRHIST_{cnt}) + exe 'silent! menu '.g:NetrwMenuPriority.".3.".priority." ".g:NetrwTopLvlMenu.'History.'.bmdir.' :e '.g:NETRW_DIRHIST_{cnt}."\<cr>" + endif + let first = 0 + let cnt = ( cnt - 1 ) % g:netrw_dirhistmax + if cnt < 0 + let cnt= cnt + g:netrw_dirhistmax + endif + endwhile + endif +" call Dret("NetBookmarkMenu") +endfun + +" --------------------------------------------------------------------- " NetObtain: obtain file under cursor (for remote browsing support) {{{2 -fun! netrw#NetObtain(...) -" call Dfunc("NetObtain() a:0=".a:0) +fun! netrw#NetObtain(vismode,...) range +" call Dfunc("NetObtain(vismode=".a:vismode.") a:0=".a:0) - if a:0==0 - " no arguments -- use word under cursor + if a:vismode == 0 + " normal mode let fname= expand("<cWORD>") " call Decho("no arguments, use <".fname.">") - elseif a:0 > 1 - " more than one argument, recurse with each argument separately -" call Decho("more than 1 argument, use recursion") - let i=1 - while i <= a:0 - call netrw#NetObtain(a:{i}) - let i=i+1 - endwhile + elseif a:vismode == 1 + " visual mode + let keeprega = @a + norm! gv"ay + if g:netrw_liststyle == s:THINLIST + " thin listing + let filelist= split(@a,'\n') + elseif g:netrw_liststyle == s:LONGLIST + " long listing + let filelist= split(substitute(@a,'\t.\{-}\n','\n','g'),'\n') + else + " wide listing + let filelist = split(substitute(@a,'\s\{2,}','\n','g'),'\n') + let filelist = map(filelist,'substitute(v:val,"^\\s\\+","","")') + let filelist = map(filelist,'substitute(v:val,"\\s\\+$","","")') + endif +" call Decho("filelist<".string(filelist).">") + let @a= keeprega + for f in filelist + if f != "" + call netrw#NetObtain(2,f) + endif + endfor +" call Dret("NetObtain : visual mode handler") return - else - " one argument provided - let fname = a:1 - let keep_netrw_choice = exists("b:netrw_choice")? b:netrw_choice : "" - let keep_netrw_fname = exists("b:netrw_fname")? b:netrw_fname : "" - let keep_netrw_wmethod = exists("w:netrw_method")? w:netrw_method : "" - call s:NetMethod(fname) - let w:netrw_method= b:netrw_method - let fname = b:netrw_fname -" call Decho("g:netrw_scp_cmd<".g:netrw_scp_cmd.">") -" call Decho("g:netrw_machine<".g:netrw_machine.">") -" call Decho("fname<".fname.">") + elseif a:vismode == 2 + " multiple file mode + let fname= a:1 +" call Decho("visual mode handling: <".fname.">") endif " NetrwStatusLine support - for obtaining support @@ -2472,11 +3745,11 @@ fun! netrw#NetObtain(...) " call Decho("method=".w:netrw_method) if executable("ftp") " call Decho("ftp is executable, method=".w:netrw_method) - let curdir = expand("%") + let curdir = b:netrw_curdir let path = substitute(curdir,'ftp://[^/]\+/','','e') let curline= line(".") let endline= line("$")+1 - set ma + setlocal ma noro keepjumps $ " call Decho("getcwd<".getcwd().">") " call Decho("curdir<".curdir.">") @@ -2526,12 +3799,14 @@ fun! netrw#NetObtain(...) " call Decho('user '.g:netrw_uid.' '.g:netrw_passwd) endif - if a:path != "" - put ='cd '.a:path + if path != "" + put ='cd '.path " call Decho('cd '.a:path) endif - exe "put ='".a:cmd."'" -" call Decho("ftp: ".a:cmd) + put ='get '.fname +" call Decho("ftp: get ".fname) + put ='quit' +" call Decho("ftp: quit") " perform ftp: " -i : turns off interactive prompting from ftp @@ -2542,17 +3817,16 @@ fun! netrw#NetObtain(...) "......................................... else - echo "***warning*** unable to comply with your request<" . choice . ">" + call netrw#ErrorMsg(s:WARNING,"unable to comply with your request<" . choice . ">",28) endif " restore exe "silent! ".endline.",$d" exe "keepjumps ".curline - setlocal noma nomod + setlocal noma nomod ro else " call Decho("ftp not executable") if !exists("g:netrw_quiet") - echohl Error | echo "***netrw*** this system doesn't support ftp" | echohl None - call inputsave()|call input("Press <cr> to continue")|call inputrestore() + call netrw#ErrorMsg(s:ERROR,"this system doesn't support ftp",29) endif " restore status line let &stl = s:netrw_users_stl @@ -2570,7 +3844,7 @@ fun! netrw#NetObtain(...) else " scp: Method#4 " call Decho("using scp") - let curdir = expand("%") + let curdir = b:netrw_curdir let path = substitute(curdir,'scp://[^/]\+/','','e') " call Decho("path<".path.">") if exists("g:netrw_port") && g:netrw_port != "" @@ -2578,13 +3852,8 @@ fun! netrw#NetObtain(...) else let useport= "" endif - if g:netrw_cygwin == 1 - let cygtmpfile=substitute(tmpfile,'^\(\a\):','/cygdrive/\1/','e') -" call Decho("executing: !".g:netrw_scp_cmd.useport." ".g:netrw_machine.":".path.escape(fname,' ?&')." .") - exe g:netrw_silentxfer."!".g:netrw_scp_cmd.useport." ".g:netrw_machine.":".path.escape(fname,' ?&')." ." - else -" call Decho("executing: !".g:netrw_scp_cmd.useport." ".g:netrw_machine.":".path.escape(fname,' ?&')." .") - exe g:netrw_silentxfer."!".g:netrw_scp_cmd.useport." ".g:netrw_machine.":".path.escape(fname,' ?&')." ." +" call Decho("executing: !".g:netrw_scp_cmd.useport." ".g:netrw_machine.":".path.escape(fname,' ?&')." .") + exe g:netrw_silentxfer."!".g:netrw_scp_cmd.useport." ".g:netrw_machine.":".path.escape(fname,' ?&')." ." endif endif @@ -2611,7 +3880,6 @@ fun! s:NetPrevWinOpen(islocal) " get last window number and the word currently under the cursor let lastwinnr = winnr("$") let curword = s:NetGetWord() - let curdir = b:netrw_curdir " call Decho("lastwinnr=".lastwinnr." curword<".curword.">") let didsplit = 0 @@ -2640,8 +3908,7 @@ fun! s:NetPrevWinOpen(islocal) let v:errmsg= "" silent w if v:errmsg != "" - echohl Error | echo "***netrw*** "unable to write <".bufname.">!" | echohl None - call inputsave()|call input("Press <cr> to continue")|call inputrestore() + call netrw#ErrorMsg(s:ERROR,"unable to write <".bufname.">!",30) if didsplit q else @@ -2653,8 +3920,8 @@ fun! s:NetPrevWinOpen(islocal) elseif choice == 2 " No -- don't worry about changed file, just browse anyway - set nomod - echohl WarningMsg | echo "***netrw*** ".bufname." changes abandoned" | echohl None + setlocal nomod + call netrw#ErrorMsg(s:WARNING,bufname." changes abandoned",31) else " Cancel -- don't do this @@ -2671,9 +3938,9 @@ fun! s:NetPrevWinOpen(islocal) endif if a:islocal - call s:LocalBrowse(s:LocalBrowseChgDir(curdir,curword)) + call netrw#LocalBrowseCheck(s:NetBrowseChgDir(a:islocal,curword)) else - call s:NetBrowse(s:NetBrowseChgDir(expand("%"),curword)) + call s:NetBrowse(a:islocal,s:NetBrowseChgDir(a:islocal,curword)) endif " call Dret("NetPrevWinOpen") endfun @@ -2686,40 +3953,41 @@ fun! s:NetMenu(domenu) let g:NetrwMenuPriority= 80 endif - if has("menu") && has("gui_running") && &go =~ 'm' + if has("menu") && has("gui_running") && &go =~ 'm' && g:netrw_menu " call Dfunc("NetMenu(domenu=".a:domenu.")") + if !exists("s:netrw_menu_enabled") && a:domenu " call Decho("initialize menu") let s:netrw_menu_enabled= 1 - if !exists("g:NetrwTopLvlMenu") - let g:NetrwTopLvlMenu= "Netrw." - endif - exe 'silent! '.g:NetrwMenuPriority.'menu '.g:NetrwTopLvlMenu.'Help<tab><F1> <F1>' - exe 'silent! '.g:NetrwMenuPriority.'menu '.g:NetrwTopLvlMenu.'Apply\ Special\ Viewer<tab>x x' - exe 'silent! '.g:NetrwMenuPriority.'menu '.g:NetrwTopLvlMenu.'Bookmark\ Current\ Directory<tab>b Nb' - exe 'silent! '.g:NetrwMenuPriority.'menu '.g:NetrwTopLvlMenu.'Go\ Up\ Directory<tab>- -' - exe 'silent! '.g:NetrwMenuPriority.'menu '.g:NetrwTopLvlMenu.'Goto\ Bookmarked\ Directory<tab>B NB' - exe 'silent! '.g:NetrwMenuPriority.'menu '.g:NetrwTopLvlMenu.'Change\ To\ Recently\ Used\ Directory<tab>u u' - exe 'silent! '.g:NetrwMenuPriority.'menu '.g:NetrwTopLvlMenu.'Change\ To\ Subsequently\ Used\ Directory<tab>U U' - exe 'silent! '.g:NetrwMenuPriority.'menu '.g:NetrwTopLvlMenu.'Delete\ File/Directory<tab>D D' - exe 'silent! '.g:NetrwMenuPriority.'menu '.g:NetrwTopLvlMenu.'Edit\ File\ Hiding\ List<tab>'."<ctrl-h> \<c-h>" - exe 'silent! '.g:NetrwMenuPriority.'menu '.g:NetrwTopLvlMenu.'Edit\ File/Directory<tab><cr> '."\<cr>" - exe 'silent! '.g:NetrwMenuPriority.'menu '.g:NetrwTopLvlMenu.'Edit\ File/Directory,\ New\ Window<tab>o o' - exe 'silent! '.g:NetrwMenuPriority.'menu '.g:NetrwTopLvlMenu.'Edit\ File/Directory,\ New\ Vertical\ Window<tab>v v' - exe 'silent! '.g:NetrwMenuPriority.'menu '.g:NetrwTopLvlMenu.'List\ Bookmarks\ and\ History<tab>q q' - exe 'silent! '.g:NetrwMenuPriority.'menu '.g:NetrwTopLvlMenu.'Listing\ Style\ (thin-long-wide)<tab>i i' - exe 'silent! '.g:NetrwMenuPriority.'menu '.g:NetrwTopLvlMenu.'Make\ Subdirectory<tab>d d' - exe 'silent! '.g:NetrwMenuPriority.'menu '.g:NetrwTopLvlMenu.'Normal-Hide-Show<tab>a a' - exe 'silent! '.g:NetrwMenuPriority.'menu '.g:NetrwTopLvlMenu.'Obtain\ File<tab>O O' - exe 'silent! '.g:NetrwMenuPriority.'menu '.g:NetrwTopLvlMenu.'Preview\ File/Directory<tab>p p' - exe 'silent! '.g:NetrwMenuPriority.'menu '.g:NetrwTopLvlMenu.'Previous\ Window\ Browser<tab>P P' - exe 'silent! '.g:NetrwMenuPriority.'menu '.g:NetrwTopLvlMenu.'Refresh\ Listing<tab>'."<ctrl-l> \<c-l>" - exe 'silent! '.g:NetrwMenuPriority.'menu '.g:NetrwTopLvlMenu.'Rename\ File/Directory<tab>R R' - exe 'silent! '.g:NetrwMenuPriority.'menu '.g:NetrwTopLvlMenu.'Reverse\ Sorting\ Order<tab>'."r r" - exe 'silent! '.g:NetrwMenuPriority.'menu '.g:NetrwTopLvlMenu.'Select\ Sorting\ Style<tab>s s' - exe 'silent! '.g:NetrwMenuPriority.'menu '.g:NetrwTopLvlMenu.'Sorting\ Sequence\ Edit<tab>S S' - exe 'silent! '.g:NetrwMenuPriority.'menu '.g:NetrwTopLvlMenu.'Set\ Current\ Directory<tab>c c' - exe 'silent! '.g:NetrwMenuPriority.'menu '.g:NetrwTopLvlMenu.'Settings/Options<tab>:NetrwSettings '.":NetrwSettings\<cr>" + exe 'silent! menu '.g:NetrwMenuPriority.'.1 '.g:NetrwTopLvlMenu.'Help<tab><F1> <F1>' + call s:NetBookmarkMenu() " provide some history! + exe 'silent! menu '.g:NetrwMenuPriority.'.4 '.g:NetrwTopLvlMenu.'Go\ Up\ Directory<tab>- -' + exe 'silent! menu '.g:NetrwMenuPriority.'.5 '.g:NetrwTopLvlMenu.'Apply\ Special\ Viewer<tab>x x' + exe 'silent! menu '.g:NetrwMenuPriority.'.6 '.g:NetrwTopLvlMenu.'Bookmark\ Current\ Directory<tab>mb mb' + exe 'silent! menu '.g:NetrwMenuPriority.'.7 '.g:NetrwTopLvlMenu.'Goto\ Bookmarked\ Directory<tab>gb gb' + exe 'silent! menu '.g:NetrwMenuPriority.'.8 '.g:NetrwTopLvlMenu.'Change\ To\ Recently\ Used\ Directory<tab>u u' + exe 'silent! menu '.g:NetrwMenuPriority.'.9 '.g:NetrwTopLvlMenu.'Change\ To\ Subsequently\ Used\ Directory<tab>U U' + exe 'silent! menu '.g:NetrwMenuPriority.'.10 '.g:NetrwTopLvlMenu.'Delete\ File/Directory<tab>D D' + exe 'silent! menu '.g:NetrwMenuPriority.'.11 '.g:NetrwTopLvlMenu.'Edit\ File\ Hiding\ List<tab>'."<ctrl-h> \<c-h>" + exe 'silent! menu '.g:NetrwMenuPriority.'.12 '.g:NetrwTopLvlMenu.'Edit\ File/Directory<tab><cr> '."\<cr>" + exe 'silent! menu '.g:NetrwMenuPriority.'.13 '.g:NetrwTopLvlMenu.'Edit\ File/Directory,\ New\ Window<tab>o o' + exe 'silent! menu '.g:NetrwMenuPriority.'.14 '.g:NetrwTopLvlMenu.'Edit\ File/Directory,\ New\ Vertical\ Window<tab>v v' + exe 'silent! menu '.g:NetrwMenuPriority.'.15 '.g:NetrwTopLvlMenu.'List\ Bookmarks\ and\ History<tab>q q' + exe 'silent! menu '.g:NetrwMenuPriority.'.16 '.g:NetrwTopLvlMenu.'Listing\ Style\ (thin-long-wide)<tab>i i' + exe 'silent! menu '.g:NetrwMenuPriority.'.17 '.g:NetrwTopLvlMenu.'Make\ Subdirectory<tab>d d' + exe 'silent! menu '.g:NetrwMenuPriority.'.18 '.g:NetrwTopLvlMenu.'Normal-Hide-Show<tab>a a' + exe 'silent! menu '.g:NetrwMenuPriority.'.19 '.g:NetrwTopLvlMenu.'Obtain\ File<tab>O O' + exe 'silent! menu '.g:NetrwMenuPriority.'.20 '.g:NetrwTopLvlMenu.'Preview\ File/Directory<tab>p p' + exe 'silent! menu '.g:NetrwMenuPriority.'.21 '.g:NetrwTopLvlMenu.'Previous\ Window\ Browser<tab>P P' + exe 'silent! menu '.g:NetrwMenuPriority.'.22 '.g:NetrwTopLvlMenu.'Refresh\ Listing<tab>'."<ctrl-l> \<c-l>" + exe 'silent! menu '.g:NetrwMenuPriority.'.23 '.g:NetrwTopLvlMenu.'Rename\ File/Directory<tab>R R' + exe 'silent! menu '.g:NetrwMenuPriority.'.24 '.g:NetrwTopLvlMenu.'Reverse\ Sorting\ Order<tab>'."r r" + exe 'silent! menu '.g:NetrwMenuPriority.'.25 '.g:NetrwTopLvlMenu.'Select\ Sorting\ Style<tab>s s' + exe 'silent! menu '.g:NetrwMenuPriority.'.26 '.g:NetrwTopLvlMenu.'Sorting\ Sequence\ Edit<tab>S S' + exe 'silent! menu '.g:NetrwMenuPriority.'.27 '.g:NetrwTopLvlMenu.'Set\ Current\ Directory<tab>c c' + exe 'silent! menu '.g:NetrwMenuPriority.'.28 '.g:NetrwTopLvlMenu.'Settings/Options<tab>:NetrwSettings '.":NetrwSettings\<cr>" + let s:netrw_menucnt= 28 + elseif !a:domenu let s:netrwcnt = 0 let curwin = winnr() @@ -2757,7 +4025,8 @@ fun! s:NetMenu(domenu) exe 'silent! unmenu '.g:NetrwTopLvlMenu.'Sorting\ Sequence\ Edit' exe 'silent! unmenu '.g:NetrwTopLvlMenu.'Set\ Current\ Directory' exe 'silent! unmenu '.g:NetrwTopLvlMenu.'Settings/Options' - unlet s:netrw_menu_enabled + exe 'silent! unmenu '.g:NetrwTopLvlMenu.'Bookmarks' + silent! unlet s:netrw_menu_enabled endif endif " call Dret("NetMenu") @@ -2770,329 +4039,36 @@ endfun " ========================================== " --------------------------------------------------------------------- -" LocalBrowse: {{{2 -fun! s:LocalBrowse(dirname) - " unfortunate interaction -- debugging calls can't be used here; - " the BufEnter event causes triggering when attempts to write to - " the DBG buffer are made. +" LocalBrowseCheck: {{{2 +fun! netrw#LocalBrowseCheck(dirname) + " unfortunate interaction -- split window debugging can't be +" " used here, must use DechoRemOn or DechoTabOn -- the BufEnter + " event triggers another call to LocalBrowseCheck() when attempts + " to write to the DBG buffer are made. +" call Dfunc("LocalBrowseCheck(dirname<".a:dirname.">") if isdirectory(a:dirname) - silent! call netrw#DirBrowse(a:dirname) + silent! call s:NetBrowse(1,a:dirname) endif +" call Dret("LocalBrowseCheck") " not a directory, ignore it endfun " --------------------------------------------------------------------- -" DirBrowse: supports local file/directory browsing {{{2 -fun! netrw#DirBrowse(dirname) - if !exists("w:netrw_longlist")|let w:netrw_longlist= g:netrw_longlist|endif -" call Dfunc("DirBrowse(dirname<".a:dirname.">) buf#".bufnr("%")." winnr=".winnr()." sortby=".g:netrw_sort_by." hide=".g:netrw_hide) -" call Dredir("ls!") - - if exists("s:netrw_skipbrowse") - unlet s:netrw_skipbrowse -" call Dret("DirBrowse") - return - endif - if &fo =~ '[ta]' - set fo-=t - set fo-=a - echohl Warning - echo '***warning*** directory browsing and formatoptions "ta" are incompatible' - echohl None - endif - - call s:NetOptionSave() - if exists("w:acdkeep") && w:acdkeep - exe 'cd '.escape(a:dirname,s:netrw_cd_escape) -" call Decho("cd ".escape(a:dirname,s:netrw_cd_escape)) -" call Decho("getcwd<".getcwd().">") - endif - - if v:version < 603 - if !exists("g:netrw_quiet") - echohl Error | echo "***netrw*** vim version<".v:version."> too old for browsing with netrw" | echohl None - call inputsave()|call input("Press <cr> to continue")|call inputrestore() - endif - call s:NetOptionRestore() -" call Dret("DirBrowse : vim version<".v:version."> too old") - return - endif - - " use buffer-oriented WinVars if buffer ones exist but window ones don't - call s:UseBufWinVars() - - " set up menus - let b:netrw_browser_active= 1 - call s:NetMenu(1) - - " find buffer number of buffer named precisely the same as a:dirname - let bufnum= bufnr(escape(a:dirname,'\')) -" call Decho("findbuf: bufnum=".bufnum) - if bufnum > 0 && bufname(bufnum) != a:dirname - let ibuf= 1 - let buflast= bufnr("$") - while bufname(ibuf) !~ '^'.a:dirname.'\=$' && ibuf <= buflast -" call Decho("findbuf: ibuf=".ibuf. " bufname<".bufname(ibuf)."> dirname<".a:dirname.">") - let ibuf= ibuf + 1 - endwhile - if ibuf > buflast - let bufnum= -1 - else - let bufnum= ibuf - endif -" call Decho("findbuf: bufnum=".bufnum." (final)") - endif - - " get cleared buffer - mark ' - if bufnum < 0 || !bufexists(bufnum) - keepjumps keepalt enew! -" call Decho("enew buffer") - else - exe "keepalt b ".bufnum - if exists("s:last_sort_by") && g:netrw_sort_by == s:last_sort_by - if getline(2) =~ '^" Netrw Directory Listing ' - if !g:netrw_keepdir - exe 'cd '.escape(b:netrw_curdir,s:netrw_cd_escape) -" call Decho("netrw_keepdir=".g:netrw_keepdir.": cd ".escape(b:netrw_curdir,s:netrw_cd_escape)) - endif - call s:NetOptionRestore() -" call Dret("DirBrowse : reusing buffer#".bufnum."<".a:dirname.">") - return - endif - endif - endif - let s:last_sort_by= g:netrw_sort_by - - " set up ShellCmdPost handling. Append current buffer to browselist - call s:LocalFastBrowser() - - " get the new directory name - if has("win32") || has("win95") || has("win64") || has("win16") - let b:netrw_curdir= substitute(a:dirname,'\\','/','ge') - else - let b:netrw_curdir= a:dirname - endif - if b:netrw_curdir =~ '[/\\]$' - let b:netrw_curdir= substitute(b:netrw_curdir,'[/\\]$','','e') - endif - if b:netrw_curdir == '' - " under unix, when the root directory is encountered, the result - " from the preceding substitute is an empty string. - let b:netrw_curdir= '/' - endif -" call Decho("b:netrw_curdir<".b:netrw_curdir.">") - - " make netrw's idea of the current directory vim's if the user wishes - if !g:netrw_keepdir -" call Decho("netrw_keepdir=".g:netrw_keepdir.": cd ".escape(b:netrw_curdir,s:netrw_cd_escape)) - try - exe 'cd '.escape(b:netrw_curdir,s:netrw_cd_escape) - catch /^Vim\%((\a\+)\)\=:E472/ - echohl Error | echo "***netrw*** unable to change directory to <".b:netrw_curdir."> (permissions?)" | echohl None - call inputsave()|call input("Press <cr> to continue")|call inputrestore() - if exists("w:netrw_prvdir") - let b:netrw_curdir= w:netrw_prvdir - else - call s:NetOptionRestore() -" call Dret("DirBrowse : reusing buffer#".bufnum."<".a:dirname.">") - return - endif - endtry - endif - - " change the name of the buffer to reflect the b:netrw_curdir - " Hmm. When another vim is open to the same directory, I get - " a "Press ENTER" ... ok, setting "noswf" avoids it. -" call Decho('exe silent! file '.escape(b:netrw_curdir,s:netrw_cd_escape)) - exe 'silent! file '.escape(b:netrw_curdir,s:netrw_cd_escape) - - " make this buffer not-a-file, modifiable, not line-numbered, etc - setlocal bt=nofile nobl ma nonu noswf nowrap - if g:netrw_fastbrowse >= 2 - setlocal bh=hide - else - setlocal bh=delete - endif - keepalt silent! %d - - " --------------------------- - " Perform Directory Listing: - if exists("g:netrw_silent") && g:netrw_silent == 0 && &ch >= 1 - echo "(netrw) Processing your browsing request..." - endif - - " save current directory on directory history list - call s:NetBookmarkDir(3,b:netrw_curdir) - - " set up all the maps -" call Decho("Setting up local browser maps") - nnoremap <buffer> <silent> <cr> :call <SID>LocalBrowse(<SID>LocalBrowseChgDir(b:netrw_curdir,<SID>NetGetWord()))<cr> - nnoremap <buffer> <silent> <c-l> :call <SID>NetRefresh(<SID>LocalBrowseChgDir(b:netrw_curdir,'./'),1)<cr> - nnoremap <buffer> <silent> - :exe "norm! 0"<bar>call <SID>LocalBrowse(<SID>LocalBrowseChgDir(b:netrw_curdir,'../'))<cr> - nnoremap <buffer> <silent> a :let g:netrw_hide=(g:netrw_hide+1)%3<bar>exe "norm! 0"<bar>call <SID>NetRefresh(<SID>LocalBrowseChgDir(b:netrw_curdir,'./'),1)<cr> - if w:netrw_longlist != 2 - nnoremap <buffer> <silent> b :<c-u>call <SID>NetBookmarkDir(0,b:netrw_curdir)<cr> - nnoremap <buffer> <silent> B :<c-u>call <SID>NetBookmarkDir(1,b:netrw_curdir)<cr> - endif - nnoremap <buffer> <silent> Nb :<c-u>call <SID>NetBookmarkDir(0,b:netrw_curdir)<cr> - nnoremap <buffer> <silent> NB :<c-u>call <SID>NetBookmarkDir(1,b:netrw_curdir)<cr> - nnoremap <buffer> <silent> c :exe "cd ".b:netrw_curdir<cr> - nnoremap <buffer> <silent> d :call <SID>NetMakeDir("")<cr> - nnoremap <buffer> <silent> <c-h> :call <SID>NetHideEdit(1)<cr> - nnoremap <buffer> <silent> i :call <SID>NetLongList(1)<cr> - nnoremap <buffer> <silent> o :call <SID>NetSplit(2)<cr> - nnoremap <buffer> <silent> O :call <SID>LocalObtain()<cr> - nnoremap <buffer> <silent> p :call <SID>LocalPreview(<SID>LocalBrowseChgDir(b:netrw_curdir,<SID>NetGetWord(),1))<cr> - nnoremap <buffer> <silent> P :call <SID>NetPrevWinOpen(1)<cr> - nnoremap <buffer> <silent> q :<c-u>call <SID>NetBookmarkDir(2,b:netrw_curdir)<cr> - nnoremap <buffer> <silent> r :let g:netrw_sort_direction= (g:netrw_sort_direction =~ 'n')? 'r' : 'n'<bar>exe "norm! 0"<bar>call <SID>NetRefresh(<SID>LocalBrowseChgDir(b:netrw_curdir,'./'),1)<cr> - nnoremap <buffer> <silent> s :call <SID>NetSaveWordPosn()<bar>let g:netrw_sort_by= (g:netrw_sort_by =~ 'n')? 'time' : (g:netrw_sort_by =~ 't')? 'size' : 'name'<bar>exe "norm! 0"<bar>call <SID>LocalBrowse(<SID>LocalBrowseChgDir(b:netrw_curdir,'./'))<bar>call <SID>NetRestoreWordPosn()<cr> - nnoremap <buffer> <silent> S :call <SID>NetSortSequence(1)<cr> - nnoremap <buffer> <silent> u :<c-u>call <SID>NetBookmarkDir(4,expand("%"))<cr> - nnoremap <buffer> <silent> U :<c-u>call <SID>NetBookmarkDir(5,expand("%"))<cr> - nnoremap <buffer> <silent> v :call <SID>NetSplit(3)<cr> - nnoremap <buffer> <silent> x :call netrw#NetBrowseX(<SID>LocalBrowseChgDir(b:netrw_curdir,<SID>NetGetWord(),0),0)"<cr> - nnoremap <buffer> <silent> <2-leftmouse> :call <SID>LocalBrowse(<SID>LocalBrowseChgDir(b:netrw_curdir,<SID>NetGetWord()))<cr> - if s:didstarstar || !mapcheck("<s-down>","n") - nnoremap <buffer> <silent> <s-down> :Nexplore<cr> - endif - if s:didstarstar || !mapcheck("<s-up>","n") - nnoremap <buffer> <silent> <s-up> :Pexplore<cr> - endif - exe 'nnoremap <buffer> <silent> <del> :call <SID>LocalBrowseRm("'.b:netrw_curdir.'")<cr>' - exe 'vnoremap <buffer> <silent> <del> :call <SID>LocalBrowseRm("'.b:netrw_curdir.'")<cr>' - exe 'nnoremap <buffer> <silent> D :call <SID>LocalBrowseRm("'.b:netrw_curdir.'")<cr>' - exe 'vnoremap <buffer> <silent> D :call <SID>LocalBrowseRm("'.b:netrw_curdir.'")<cr>' - exe 'nnoremap <buffer> <silent> R :call <SID>LocalBrowseRename("'.b:netrw_curdir.'")<cr>' - exe 'vnoremap <buffer> <silent> R :call <SID>LocalBrowseRename("'.b:netrw_curdir.'")<cr>' - exe 'nnoremap <buffer> <silent> <Leader>m :call <SID>NetMakeDir("")<cr>' - nnoremap <buffer> <F1> :he netrw-dir<cr> - - " Set up the banner -" call Decho("set up banner") - keepjumps put ='\" ============================================================================' - keepjumps 1d - keepjumps put ='\" Netrw Directory Listing (netrw '.g:loaded_netrw.')' - keepjumps put ='\" '.b:netrw_curdir - let w:netrw_bannercnt= 3 - - let sortby= g:netrw_sort_by - if g:netrw_sort_direction =~ "^r" - let sortby= sortby." reversed" - endif - - " Sorted by... - if g:netrw_sort_by =~ "^n" -" call Decho("directories will be sorted by name") - " sorted by name - keepjumps put ='\" Sorted by '.sortby - keepjumps put ='\" Sort sequence: '.g:netrw_sort_sequence - let w:netrw_bannercnt= w:netrw_bannercnt + 2 - else -" call Decho("directories will be sorted by size or date") - " sorted by size or date - keepjumps put ='\" Sorted by '.sortby - let w:netrw_bannercnt= w:netrw_bannercnt + 1 - endif - - " Hiding... -or- Showing... - if g:netrw_list_hide != "" && g:netrw_hide - if g:netrw_hide == 1 - keepjumps put ='\" Hiding: '.g:netrw_list_hide - else - keepjumps put ='\" Showing: '.g:netrw_list_hide - endif - let w:netrw_bannercnt= w:netrw_bannercnt + 1 - endif - keepjumps put ='\" Quick Help: <F1>:help -:go up dir D:delete R:rename s:sort-by x:exec' - keepjumps put ='\" ============================================================================' - let w:netrw_bannercnt= w:netrw_bannercnt + 2 - - " bannercnt should index the line just after the banner - let w:netrw_bannercnt= w:netrw_bannercnt + 1 -" call Decho("bannercnt=".w:netrw_bannercnt) - - " generate the requested directory listing - call s:LocalBrowseList() - - " set up syntax highlighting - if has("syntax") - setlocal ft=netrw - if !exists("g:syntax_on") || !g:syntax_on - setlocal ft= - endif - endif - - " manipulate the directory listing (hide, sort) - if line("$") >= w:netrw_bannercnt - if g:netrw_hide && g:netrw_list_hide != "" - call s:NetrwListHide() - endif - if line("$") >= w:netrw_bannercnt - - if g:netrw_sort_by =~ "^n" - call s:SetSort() - - if w:netrw_bannercnt < line("$") - if g:netrw_sort_direction =~ 'n' - exe 'silent keepjumps '.w:netrw_bannercnt.',$sort' - else - exe 'silent keepjumps '.w:netrw_bannercnt.',$sort!' - endif - endif - " remove priority pattern prefix - exe 'silent keepjumps '.w:netrw_bannercnt.',$s/^\d\{3}\///e' - - else - if w:netrw_bannercnt < line("$") - if g:netrw_sort_direction =~ 'n' - exe 'silent keepjumps '.w:netrw_bannercnt.',$sort' - else - exe 'silent keepjumps '.w:netrw_bannercnt.',$sort!' - endif - endif - exe 'silent keepjumps '.w:netrw_bannercnt.',$s/^\d\{-}\///e' - endif - - endif - endif - - call s:NetrwWideListing() - if exists("w:netrw_bannercnt") && line("$") > w:netrw_bannercnt - " place cursor on the top-left corner of the file listing - exe 'silent '.w:netrw_bannercnt - norm! 0 - endif - - " record previous current directory - let w:netrw_prvdir= b:netrw_curdir - - " save certain window-oriented variables into buffer-oriented variables - call s:SetBufWinVars() - call s:NetOptionRestore() - setlocal noma nomod nonu nobl nowrap - if g:netrw_fastbrowse >= 2 - setlocal bh=hide - endif - -" call Dret("DirBrowse : file<".expand("%:p")."> bufname<".bufname("%").">") -endfun - -" --------------------------------------------------------------------- -" LocalBrowseList: does the job of "ls" for local directories {{{2 -fun! s:LocalBrowseList() -" call Dfunc("LocalBrowseList() b:netrw_curdir<".b:netrw_curdir."> sortby<".g:netrw_sort_by.">") +" LocalListing: does the job of "ls" for local directories {{{2 +fun! s:LocalListing() +" call Dfunc("LocalListing() &ma=".&ma." &mod=".&mod." &ro=".&ro) +" if exists("b:netrw_curdir") |call Decho('b:netrw_curdir<'.b:netrw_curdir.">") |else|call Decho("b:netrw_curdir doesn't exist") |endif +" if exists("g:netrw_sort_by")|call Decho('g:netrw_sort_by<'.g:netrw_sort_by.">")|else|call Decho("g:netrw_sort_by doesn't exist")|endif " get the list of files contained in the current directory let dirname = escape(b:netrw_curdir,s:netrw_glob_escape) let dirnamelen = strlen(b:netrw_curdir) - let filelist = glob(dirname."/*") -" call Decho("glob(dirname<".dirname."/.*>)=".filelist) + let filelist = glob(s:ComposePath(dirname,"*")) +" call Decho("glob(dirname<".dirname."/*>)=".filelist) if filelist != "" let filelist= filelist."\n" endif - let filelist= filelist.glob(dirname."/.*") + let filelist= filelist.glob(s:ComposePath(dirname,".*")) " call Decho("glob(dirname<".dirname."/.*>)=".glob(dirname.".*")) " if the directory name includes a "$", and possibly other characters, @@ -3100,16 +4076,21 @@ fun! s:LocalBrowseList() if filelist !~ '[\\/]\.[\\/]\=\(\n\|$\)' " call Decho("forcibly tacking on .") if filelist == "" - let filelist= dirname."." + let filelist= s:ComposePath(dirname,"./") else - let filelist= filelist."\n".b:netrw_curdir."." + let filelist= filelist."\n".s:ComposePath(b:netrw_curdir,"./") endif " call Decho("filelist<".filelist.">") endif if filelist !~ '[\\/]\.\.[\\/]\=\(\n\|$\)' " call Decho("forcibly tacking on ..") - let filelist= filelist."\n".b:netrw_curdir.".." -" call Decho("filelist<".filelist.">") + let filelist= filelist."\n".s:ComposePath(b:netrw_curdir,"../") +" call Decho("filelist<".filelist.">") + endif + if b:netrw_curdir == '/' + " remove .. from filelist when current directory is root directory + let filelist= substitute(filelist,'/\.\.\n','','') +" call Decho("remove .. from filelist") endif let filelist= substitute(filelist,'\n\{2,}','\n','ge') if (has("win32") || has("win95") || has("win64") || has("win16")) @@ -3138,12 +4119,12 @@ fun! s:LocalBrowseList() let pfile= substitute(pfile,'//$','/','e') endif let pfile= strpart(pfile,dirnamelen) - let pfile= substitute(pfile,'^/','','e') + let pfile= substitute(pfile,'^[/\\]','','e') " call Decho(" ") " call Decho("filename<".filename.">") " call Decho("pfile <".pfile.">") - if w:netrw_longlist == 1 + if w:netrw_liststyle == s:LONGLIST let sz = getfsize(filename) let fsz = strpart(" ",1,15-strlen(sz)).sz let pfile= pfile."\t".fsz." ".strftime(g:netrw_timefmt,getftime(filename)) @@ -3178,65 +4159,9 @@ fun! s:LocalBrowseList() " cleanup any windows mess at end-of-line silent! keepjumps %s/\r$//e setlocal ts=32 +" call Decho("setlocal ts=32") -" call Dret("LocalBrowseList") -endfun - -" --------------------------------------------------------------------- -" LocalBrowseChgDir: constructs a new directory based on the current {{{2 -" directory and a new directory name -fun! s:LocalBrowseChgDir(dirname,newdir,...) -" call Dfunc("LocalBrowseChgDir(dirname<".a:dirname."> newdir<".a:newdir.">) a:0=".a:0) - - let dirname= substitute(a:dirname,'\\','','ge') - let newdir = a:newdir - - if dirname !~ '[\/]$' - " apparently vim is "recognizing" that it is in the home directory and - " is removing the "/". Bad idea, so I have to put it back. - let dirname= dirname.'/' -" call Decho("adjusting dirname<".dirname.">") - endif - - if newdir !~ '[\/]$' - " handling a file - let dirname= dirname.newdir -" call Decho("handling a file: dirname<".dirname.">") - " this lets NetBrowseX avoid the edit - if a:0 < 1 -" call Decho("dirname<".dirname."> netrw_cd_escape<".s:netrw_cd_escape.">") -" call Decho("about to edit<".escape(dirname,s:netrw_cd_escape).">") - if g:netrw_browse_split == 1 - new - wincmd _ - elseif g:netrw_browse_split == 2 - rightb vert new - wincmd | - else - " handling a file, didn't split, so possibly remove menu - call s:NetMenu(0) - endif - exe "e! ".escape(dirname,s:netrw_cd_escape) - set ma nomod - endif - - elseif newdir == './' - " refresh the directory list -" call Decho("refresh directory listing") - - elseif newdir == '../' - " go up one directory - let dirname= substitute(dirname,'^\(.*/\)\([^/]\+[\/]$\)','\1','e') -" call Decho("go up one dir: dirname<".dirname.">") - - else - " go down one directory - let dirname= dirname.newdir -" call Decho("go down one dir: dirname<".dirname."> newdir<".newdir.">") - endif - -" call Dret("LocalBrowseChgDir <".dirname.">") - return dirname +" call Dret("LocalListing") endfun " --------------------------------------------------------------------- @@ -3246,22 +4171,32 @@ endfun " on the chance that s/he removed/created a file/directory with it. fun! s:LocalBrowseShellCmdRefresh() " call Dfunc("LocalBrowseShellCmdRefresh() browselist=".string(s:netrw_browselist)) + " determine which buffers currently reside in a tab + let itab = 1 + let buftablist = [] + while itab <= tabpagenr("$") + let buftablist= buftablist + tabpagebuflist() + let itab= itab + 1 + tabn + endwhile +" call Decho("buftablist".string(buftablist)) " GO through all buffers on netrw_browselist (ie. just local-netrw buffers): " | refresh any netrw window " | wipe out any non-displaying netrw buffer let curwin = winnr() let ibl = 0 for ibuf in s:netrw_browselist - if bufwinnr(ibuf) == -1 -" call Decho("wiping buf#".ibuf) +" call Decho("bufwinnr(".ibuf.") index(buftablist,".ibuf.")=".index(buftablist,ibuf)) + if bufwinnr(ibuf) == -1 && index(buftablist,ibuf) == -1 +" call Decho("wiping buf#".ibuf,"<".bufname(ibuf).">") exe "silent! bw ".ibuf call remove(s:netrw_browselist,ibl) " call Decho("browselist=".string(s:netrw_browselist)) continue - else + elseif index(tabpagebuflist(),ibuf) != -1 " call Decho("refresh buf#".ibuf.'-> win#'.bufwinnr(ibuf)) exe bufwinnr(ibuf)."wincmd w" - call s:NetRefresh(s:LocalBrowseChgDir(b:netrw_curdir,'./'),1) + call s:NetRefresh(1,s:NetBrowseChgDir(1,'./')) endif let ibl= ibl + 1 endfor @@ -3297,7 +4232,7 @@ fun! s:LocalBrowseRm(path) range endif norm! 0 - let rmfile= a:path."/".curword + let rmfile= s:ComposePath(a:path,curword) " call Decho("rmfile<".rmfile.">") if rmfile !~ '^"' && (rmfile =~ '@$' || rmfile !~ '[\/]$') @@ -3320,7 +4255,7 @@ fun! s:LocalBrowseRm(path) range endif if all || ok =~ 'y\%[es]' || ok == "" - let ret= delete(rmfile) + let ret= s:System("delete",rmfile) " call Decho("errcode=".v:shell_error." ret=".ret) elseif ok =~ 'q\%[uit]' break @@ -3345,25 +4280,23 @@ fun! s:LocalBrowseRm(path) range if all || ok =~ 'y\%[es]' || ok == "" " call Decho("1st attempt: system(".g:netrw_local_rmdir.' "'.rmfile.'")') - call system(g:netrw_local_rmdir.' "'.rmfile.'"') + call s:System("system",g:netrw_local_rmdir.' "'.rmfile.'"') " call Decho("v:shell_error=".v:shell_error) if v:shell_error != 0 " call Decho("2nd attempt to remove directory<".rmfile.">") - let errcode= delete(rmfile) + let errcode= s:System("delete",rmfile) " call Decho("errcode=".errcode) if errcode != 0 if has("unix") " call Decho("3rd attempt to remove directory<".rmfile.">") -call system("rm ".rmfile) + call s:System("system","rm ".rmfile) if v:shell_error != 0 && !exists("g:netrw_quiet") - echohl Error | echo "***netrw*** unable to remove directory<".rmfile."> -- is it empty?" | echohl None - call inputsave()|call input("Press <cr> to continue")|call inputrestore() + call netrw#ErrorMsg(s:ERROR,"unable to remove directory<".rmfile."> -- is it empty?",34) endif elseif !exists("g:netrw_quiet") - echohl Error | echo "***netrw*** unable to remove directory<".rmfile."> -- is it empty?" | echohl None - call inputsave()|call input("Press <cr> to continue")|call inputrestore() + call netrw#ErrorMsg(s:ERROR,"unable to remove directory<".rmfile."> -- is it empty?",35) endif endif endif @@ -3379,7 +4312,7 @@ endif " refresh the directory let curline= line(".") " call Decho("refresh the directory") - call s:NetRefresh(s:LocalBrowseChgDir(b:netrw_curdir,'./'),1) + call s:NetRefresh(1,s:NetBrowseChgDir(1,'./')) exe curline " call Dret("LocalBrowseRm") @@ -3409,7 +4342,7 @@ fun! s:LocalBrowseRename(path) range endif norm! 0 - let oldname= a:path."/".curword + let oldname= s:ComposePath(a:path,curword) " call Decho("oldname<".oldname.">") call inputsave() @@ -3423,26 +4356,31 @@ fun! s:LocalBrowseRename(path) range endwhile " refresh the directory - let curline= line(".") " call Decho("refresh the directory listing") - call s:NetRefresh(s:LocalBrowseChgDir(b:netrw_curdir,'./'),1) - exe "keepjumps ".curline + call netrw#NetSavePosn() + call s:NetRefresh(1,s:NetBrowseChgDir(1,'./')) " call Dret("LocalBrowseRename") endfun " --------------------------------------------------------------------- " LocalFastBrowser: handles setting up/taking down fast browsing for the {{{2 " local browser +" fastbrowse Local Remote Hiding a buffer implies it may be re-used (fast) +" slow 0 D D Deleting a buffer implies it will not be re-used (slow) +" med 1 D H +" fast 2 H H fun! s:LocalFastBrowser() -" call Dfunc("LocalFastBrowser()") +" call Dfunc("LocalFastBrowser() g:netrw_fastbrowse=".g:netrw_fastbrowse) " initialize browselist, a list of buffer numbers that the local browser has used if !exists("s:netrw_browselist") +" call Decho("initialize s:netrw_browselist") let s:netrw_browselist= [] endif " append current buffer to fastbrowse list if g:netrw_fastbrowse <= 1 && (empty(s:netrw_browselist) || bufnr("%") > s:netrw_browselist[-1]) +" call Decho("appendng current buffer to browselist") call add(s:netrw_browselist,bufnr("%")) " call Decho("browselist=".string(s:netrw_browselist)) endif @@ -3466,6 +4404,7 @@ fun! s:LocalFastBrowser() " user must have changed fastbrowse to its fast setting, so remove " the associated autocmd events if g:netrw_fastbrowse > 1 && exists("s:netrw_browser_shellcmd") +" call Decho("remove AuNetrwShellCmd autcmd group") unlet s:netrw_browser_shellcmd augroup AuNetrwShellCmd au! @@ -3485,180 +4424,227 @@ fun! s:LocalObtain() let fcopy= readfile(b:netrw_curdir."/".fname,"b") call writefile(fcopy,getcwd()."/".fname,"b") elseif !exists("b:netrw_curdir") - echohl Error | echo "***netrw*** local browsing directory doesn't exist!" - call inputsave()|call input("Press <cr> to continue")|call inputrestore() + call netrw#ErrorMsg(s:ERROR,"local browsing directory doesn't exist!",36) else - echohl Error | echo "***netrw*** local browsing directory and current directory are identical" - call inputsave()|call input("Press <cr> to continue")|call inputrestore() + call netrw#ErrorMsg(s:ERROR,"local browsing directory and current directory are identical",37) endif " call Dret("LocalObtain") endfun " --------------------------------------------------------------------- -" LocalPreview: {{{2 -fun! s:LocalPreview(path) range -" call Dfunc("LocalPreview(path<".a:path.">)") - if has("quickfix") - if !isdirectory(a:path) - exe "pedit ".escape(a:path,g:netrw_fname_escape) - elseif !exists("g:netrw_quiet") - echohl WarningMsg | echo "***netrw*** sorry, cannot preview a directory such as <".a:path.">" | echohl None - call inputsave()|call input("Press <cr> to continue")|call inputrestore() - endif - elseif !exists("g:netrw_quiet") - echohl WarningMsg | echo "***netrw*** sorry, to preview your vim needs the quickfix feature compiled in" | echohl None - call inputsave()|call input("Press <cr> to continue")|call inputrestore() - endif -" call Dret("LocalPreview") -endfun - -" --------------------------------------------------------------------- -" Explore: launch the local browser in the directory of the current file {{{2 +" netrw#Explore: launch the local browser in the directory of the current file {{{2 " dosplit==0: the window will be split iff the current file has " been modified " dosplit==1: the window will be split before running the local " browser fun! netrw#Explore(indx,dosplit,style,...) -" call Dfunc("Explore(indx=".a:indx." dosplit=".a:dosplit." style=".a:style.")") +" call Dfunc("netrw#Explore(indx=".a:indx." dosplit=".a:dosplit." style=".a:style.",a:1<".a:1.">) &modified=".&modified) + if !exists("b:netrw_curdir") + let b:netrw_curdir= getcwd() + endif + let curfile = b:netrw_curdir +" call Decho("curfile<".curfile.">") + + " save registers + silent! let keepregstar = @* + silent! let keepregplus = @+ + silent! let keepregslash= @/ " if dosplit or file has been modified - if a:dosplit || &modified + if a:dosplit || &modified || a:style == 6 +" call Decho("case: dosplit=".a:dosplit." modified=".&modified." a:style=".a:style) call s:SaveWinVars() if a:style == 0 " Explore, Sexplore - exe g:netrw_winsize."wincmd s" " call Decho("style=0: Explore or Sexplore") + exe g:netrw_winsize."wincmd s" elseif a:style == 1 "Explore!, Sexplore! - exe g:netrw_winsize."wincmd v" " call Decho("style=1: Explore! or Sexplore!") + exe g:netrw_winsize."wincmd v" elseif a:style == 2 " Hexplore - exe "bel ".g:netrw_winsize."wincmd s" " call Decho("style=2: Hexplore") + exe "bel ".g:netrw_winsize."wincmd s" elseif a:style == 3 " Hexplore! - exe "abo ".g:netrw_winsize."wincmd s" " call Decho("style=3: Hexplore!") + exe "abo ".g:netrw_winsize."wincmd s" elseif a:style == 4 " Vexplore - exe "lefta ".g:netrw_winsize."wincmd v" " call Decho("style=4: Vexplore") + exe "lefta ".g:netrw_winsize."wincmd v" elseif a:style == 5 " Vexplore! - exe "rightb ".g:netrw_winsize."wincmd v" " call Decho("style=5: Vexplore!") + exe "rightb ".g:netrw_winsize."wincmd v" + + elseif a:style == 6 " Texplore + call s:SaveBufVars() +" call Decho("style = 6: Texplore") + tabnew + call s:RestoreBufVars() endif - call s:CopyWinVars() + call s:RestoreWinVars() endif norm! 0 - if a:1 =~ '^\*/' +" call Decho("a:1<".a:1.">") + if a:1 =~ '^\~' && (has("unix") || (exists("g:netrw_cygwin") && g:netrw_cygwin)) + let dirname= substitute(a:1,'\~',expand("$HOME"),'') +" call Decho("using dirname<".dirname."> (case: ~ && unix||cygwin)") + elseif a:1 == '.' + let dirname= exists("b:netrw_curdir")? b:netrw_curdir : getcwd() + if dirname !~ '/$' + let dirname= dirname."/" + endif +" call Decho("using dirname<".dirname."> (case: ".(exists("b:netrw_curdir")? "b:netrw_curdir" : "getcwd()").")") + else + let dirname= a:1 +" call Decho("using dirname<".dirname.">") + endif + + if dirname =~ '^\*/' " Explore */pattern - let pattern= substitute(a:1,'^\*/\(.*\)$','\1','') -" call Decho("Explore */pat: a:1<".a:1."> -> pattern<".pattern.">") - elseif a:1 =~ '^\*\*//' +" call Decho("case Explore */pattern") + let pattern= substitute(dirname,'^\*/\(.*\)$','\1','') +" call Decho("Explore */pat: dirname<".dirname."> -> pattern<".pattern.">") + if &hls | let keepregslash= s:ExplorePatHls(pattern) | endif + elseif dirname =~ '^\*\*//' " Explore **//pattern - let pattern = substitute(a:1,'^\*\*//','','') +" call Decho("case Explore **//pattern") + let pattern = substitute(dirname,'^\*\*//','','') let starstarpat = 1 -" call Decho("Explore **//pat: a:1<".a:1."> -> pattern<".pattern.">") +" call Decho("Explore **//pat: dirname<".dirname."> -> pattern<".pattern.">") endif - if a:1 == "" && a:indx >= 0 + if dirname == "" && a:indx >= 0 " Explore Hexplore Vexplore Sexplore -" call Decho("Explore Hexplore Vexplore Sexplore") +" call Decho("case Explore Hexplore Vexplore Sexplore") let newdir= substitute(expand("%:p"),'^\(.*[/\\]\)[^/\\]*$','\1','e') if newdir =~ '^scp:' || newdir =~ '^ftp:' -" call Decho("calling NetBrowse(newdir<".newdir.">)") - call s:NetBrowse(newdir) +" call Decho("calling NetBrowse(0,newdir<".newdir.">)") + call s:NetBrowse(0,newdir) else if newdir == ""|let newdir= getcwd()|endif -" call Decho("calling LocalBrowse(newdir<".newdir.">)") - call s:LocalBrowse(newdir) +" call Decho("calling LocalBrowseCheck(newdir<".newdir.">)") + call netrw#LocalBrowseCheck(newdir) endif + call search('\<'.substitute(curfile,'^.*/','','e').'\>','cW') - elseif a:1 =~ '^\*\*/' || a:indx < 0 || a:1 =~ '^\*/' + elseif dirname =~ '^\*\*/' || a:indx < 0 || dirname =~ '^\*/' " Nexplore, Pexplore, Explore **/... , or Explore */pattern -" call Decho("Nexplore, Pexplore, <s-down>, <s-up>, Explore ".a:1) - let s:didstarstar= 1 - if exists("b:netrw_curdir") +" call Decho("case Nexplore, Pexplore, <s-down>, <s-up>, Explore dirname<".dirname.">") + if !mapcheck("<s-up>","n") && !mapcheck("<s-down>","n") && exists("b:netrw_curdir") +" call Decho("set up <s-up> and <s-down> maps") + let s:didstarstar= 1 nnoremap <buffer> <silent> <s-up> :Pexplore<cr> nnoremap <buffer> <silent> <s-down> :Nexplore<cr> endif if has("path_extra") +" call Decho("has path_extra") if !exists("w:netrw_explore_indx") let w:netrw_explore_indx= 0 endif let indx = a:indx -" call Decho("set indx=".indx) +" call Decho("set indx= [a:indx=".indx."]") " if indx == -1 "Nexplore +" call Decho("case Nexplore: (indx=".indx.")") if !exists("w:netrw_explore_list") " sanity check - echohl WarningMsg | echo "***netrw*** using Nexplore or <s-down> improperly; see help for netrw-starstar" | echohl None - call inputsave()|call input("Press <cr> to continue")|call inputrestore() -" call Dret("Explore") + call netrw#ErrorMsg(s:WARNING,"using Nexplore or <s-down> improperly; see help for netrw-starstar",40) + silent! let @* = keepregstar + silent! let @+ = keepregstar + silent! let @/ = keepregslash +" call Dret("netrw#Explore") return endif - let indx = w:netrw_explore_indx + let indx= w:netrw_explore_indx + if indx < 0 | let indx= 0 | endif + if indx >= w:netrw_explore_listlen | let indx= w:netrw_explore_listlen - 1 | endif let curfile= w:netrw_explore_list[indx] +" call Decho("indx=".indx." curfile<".curfile.">") while indx < w:netrw_explore_listlen && curfile == w:netrw_explore_list[indx] let indx= indx + 1 -" call Decho("indx=".indx) +" call Decho("indx=".indx." (Nexplore while loop)") endwhile + if indx >= w:netrw_explore_listlen | let indx= w:netrw_explore_listlen - 1 | endif " call Decho("Nexplore: indx= [w:netrw_explore_indx=".w:netrw_explore_indx."]=".indx) elseif indx == -2 "Pexplore +" call Decho("case Pexplore: (indx=".indx.")") if !exists("w:netrw_explore_list") " sanity check - echohl WarningMsg | echo "***netrw*** using Pexplore or <s-up> improperly; see help for netrw-starstar" | echohl None - call inputsave()|call input("Press <cr> to continue")|call inputrestore() -" call Dret("Explore") + call netrw#ErrorMsg(s:WARNING,"using Pexplore or <s-up> improperly; see help for netrw-starstar",41) + silent! let @* = keepregstar + silent! let @+ = keepregstar + silent! let @/ = keepregslash +" call Dret("netrw#Explore") return endif - let indx = w:netrw_explore_indx + let indx= w:netrw_explore_indx + if indx < 0 | let indx= 0 | endif + if indx >= w:netrw_explore_listlen | let indx= w:netrw_explore_listlen - 1 | endif let curfile= w:netrw_explore_list[indx] - while indx > 0 && curfile == w:netrw_explore_list[indx] +" call Decho("indx=".indx." curfile<".curfile.">") + while indx >= 0 && curfile == w:netrw_explore_list[indx] let indx= indx - 1 +" call Decho("indx=".indx." (Pexplore while loop)") endwhile + if indx < 0 | let indx= 0 | endif " call Decho("Pexplore: indx= [w:netrw_explore_indx=".w:netrw_explore_indx."]=".indx) else " Explore -- initialize " build list of files to Explore with Nexplore/Pexplore -" call Decho("Explore -- initialize") +" call Decho("case Explore: initialize (indx=".indx.")") let w:netrw_explore_indx= 0 if !exists("b:netrw_curdir") let b:netrw_curdir= getcwd() endif " call Decho("b:netrw_curdir<".b:netrw_curdir.">") + if exists("pattern") -" call Decho("building list based on pattern<".pattern."> cwd<".getcwd().">") +" call Decho("pattern exists: building list pattern<".pattern."> cwd<".getcwd().">") if exists("starstarpat") - exe "vimgrep /".pattern."/gj "."**/*" - let s:netrw_curdir= b:netrw_curdir - let w:netrw_explore_list = map(getqflist(),'s:netrw_curdir."/".bufname(v:val.bufnr)') +" call Decho("starstarpat<".starstarpat.">") + try + exe "silent vimgrep /".pattern."/gj "."**/*" + catch /^Vim\%((\a\+)\)\=:E480/ + call netrw#ErrorMsg(s:WARNING,'no files matched pattern<'.pattern.'>',45) + if &hls | let keepregslash= s:ExplorePatHls(pattern) | endif + silent! let @* = keepregstar + silent! let @+ = keepregstar + silent! let @/ = keepregslash +" call Dret("netrw#Explore : no files matched pattern") + return + endtry + let s:netrw_curdir = b:netrw_curdir + let w:netrw_explore_list = getqflist() + let w:netrw_explore_list = map(w:netrw_explore_list,'s:netrw_curdir."/".bufname(v:val.bufnr)') else +" call Decho("no starstarpat") exe "vimgrep /".pattern."/gj ".b:netrw_curdir."/*" - if (has("win32") || has("win95") || has("win64") || has("win16")) - let w:netrw_explore_list = map(getqflist(),'bufname(v:val.bufnr)') - else - let w:netrw_explore_list = map(getqflist(),'b:netrw_curdir.bufname(v:val.bufnr)') - endif + let w:netrw_explore_list = map(getqflist(),'bufname(v:val.bufnr)') + if &hls | let keepregslash= s:ExplorePatHls(pattern) | endif endif else -" call Decho("building list based on ".b:netrw_curdir."/".a:1) - let w:netrw_explore_list= split(expand(b:netrw_curdir."/".a:1),'\n') +" call Decho("no pattern: building list based on ".b:netrw_curdir."/".dirname) + let w:netrw_explore_list= split(expand(b:netrw_curdir."/".dirname),'\n') + if &hls | let keepregslash= s:ExplorePatHls(dirname) | endif endif let w:netrw_explore_listlen = len(w:netrw_explore_list) " call Decho("w:netrw_explore_list<".string(w:netrw_explore_list)."> listlen=".w:netrw_explore_listlen) - if w:netrw_explore_listlen == 1 && w:netrw_explore_list[0] =~ '\*\*\/' - echohl WarningMsg | echo "***netrw*** no files matched" | echohl None - call inputsave()|call input("Press <cr> to continue")|call inputrestore() -" call Dret("Explore") + if w:netrw_explore_listlen == 0 || (w:netrw_explore_listlen == 1 && w:netrw_explore_list[0] =~ '\*\*\/') + call netrw#ErrorMsg(s:WARNING,"no files matched",42) + silent! let @* = keepregstar + silent! let @+ = keepregstar + silent! let @/ = keepregslash +" call Dret("netrw#Explore : no files matched") return endif endif @@ -3667,13 +4653,13 @@ fun! netrw#Explore(indx,dosplit,style,...) let w:netrw_explore_indx= indx " call Decho("explorelist<".join(w:netrw_explore_list,',')."> len=".w:netrw_explore_listlen) - " sanity check + " wrap the indx around, but issue a note if indx >= w:netrw_explore_listlen || indx < 0 - let indx= (indx < 0)? 0 : ( w:netrw_explore_listlen - 1 ) - echohl WarningMsg | echo "***netrw*** no more files match Explore pattern" | echohl None - call inputsave()|call input("Press <cr> to continue")|call inputrestore() -" call Dret("Explore") - return +" call Decho("wrap indx (indx=".indx." listlen=".w:netrw_explore_listlen.")") + let indx = (indx < 0)? ( w:netrw_explore_listlen - 1 ) : 0 + let w:netrw_explore_indx= indx + call netrw#ErrorMsg(s:NOTE,"no more files match Explore pattern",43) + sleep 1 endif exe "let dirfile= w:netrw_explore_list[".indx."]" @@ -3681,9 +4667,12 @@ fun! netrw#Explore(indx,dosplit,style,...) let newdir= substitute(dirfile,'/[^/]*$','','e') " call Decho("newdir<".newdir.">") -" call Decho("calling LocalBrowse(newdir<".newdir.">)") - call s:LocalBrowse(newdir) - if w:netrw_longlist == 0 || w:netrw_longlist == 1 +" call Decho("calling LocalBrowseCheck(newdir<".newdir.">)") + call netrw#LocalBrowseCheck(newdir) + if !exists("w:netrw_liststyle") + let w:netrw_liststyle= g:netrw_liststyle + endif + if w:netrw_liststyle == s:THINLIST || w:netrw_liststyle == s:LONGLIST call search('^'.substitute(dirfile,"^.*/","","").'\>',"W") else call search('\<'.substitute(dirfile,"^.*/","","").'\>',"w") @@ -3695,19 +4684,48 @@ fun! netrw#Explore(indx,dosplit,style,...) " call Decho("explore: mtchcnt=".w:netrw_explore_mtchcnt." bufnr=".w:netrw_explore_bufnr." line#".w:netrw_explore_line) else +" call Decho("vim does not have path_extra") if !exists("g:netrw_quiet") - echohl WarningMsg | echo "***netrw*** your vim needs the +path_extra feature for Exploring with **!" | echohl None | echohl None + call netrw#ErrorMsg(s:WARNING,"your vim needs the +path_extra feature for Exploring with **!",44) endif - call inputsave()|call input("Press <cr> to continue")|call inputrestore() + silent! let @* = keepregstar + silent! let @+ = keepregstar + silent! let @/ = keepregslash +" call Dret("netrw#Explore : missing +path_extra") + return endif else -" call Decho("Explore newdir<".a:1.">") - let newdir= a:1 - call s:LocalBrowse(newdir) +" call Decho("case Explore newdir<".dirname.">") + if exists("w:netrw_liststyle") && w:netrw_liststyle == s:TREELIST && dirname =~ '/' + silent! unlet w:netrw_treedict + silent! unlet w:netrw_treetop + endif + let newdir= dirname + if !exists("b:netrw_curdir") + call netrw#LocalBrowseCheck(getcwd()) + else + call netrw#LocalBrowseCheck(s:NetBrowseChgDir(1,newdir)) + endif endif -" call Dret("Explore") + silent! let @* = keepregstar + silent! let @+ = keepregstar + silent! let @/ = keepregslash +" call Dret("netrw#Explore : @/<".@/.">") +endfun + +" --------------------------------------------------------------------- +" s:ExplorePatHls: converts an Explore pattern into a regular expression search pattern {{{2 +fun! s:ExplorePatHls(pattern) +" call Dfunc("s:ExplorePatHls(pattern<".a:pattern.">)") + let repat= substitute(a:pattern,'^**/\{1,2}','','') +" call Decho("repat<".repat.">") + let repat= escape(repat,'][.\') +" call Decho("repat<".repat.">") + let repat= '\<'.substitute(repat,'\*','\\(\\S\\+ \\)*\\S\\+','g').'\>' +" call Dret("s:ExplorePatHls repat<".repat.">") + return repat endfun " --------------------------------------------------------------------- @@ -3746,7 +4764,7 @@ fun! s:SetupNetrwStatusLine(statline) " insure that windows have a statusline " make sure statusline is displayed let &stl=a:statline - set laststatus=2 + setlocal laststatus=2 " call Decho("stl=".&stl) redraw! @@ -3757,7 +4775,7 @@ endfun " NetrwStatusLine: {{{2 fun! NetrwStatusLine() - " vvv NetrwStatusLine() debugging vvv +" vvv NetrwStatusLine() debugging vvv " let g:stlmsg="" " if !exists("w:netrw_explore_bufnr") " let g:stlmsg="!X<explore_bufnr>" @@ -3772,7 +4790,7 @@ fun! NetrwStatusLine() " if !exists("w:netrw_explore_list") " let g:stlmsg=" !X<explore_list>" " endif - " ^^^ NetrwStatusLine() debugging ^^^ +" ^^^ NetrwStatusLine() debugging ^^^ if !exists("w:netrw_explore_bufnr") || w:netrw_explore_bufnr != bufnr("%") || !exists("w:netrw_explore_line") || w:netrw_explore_line != line(".") || !exists("w:netrw_explore_list") " restore user's status line @@ -3804,395 +4822,6 @@ fun! s:NetGetcwd(doesc) endfun " --------------------------------------------------------------------- -" NetMethod: determine method of transfer {{{2 -" method == 1: rcp -" 2: ftp + <.netrc> -" 3: ftp + machine, id, password, and [path]filename -" 4: scp -" 5: http (wget) -" 6: cadaver -" 7: rsync -" 8: fetch -" 9: sftp -fun! s:NetMethod(choice) " globals: method machine id passwd fname -" call Dfunc("NetMethod(a:choice<".a:choice.">)") - - " initialization - let b:netrw_method = 0 - let g:netrw_machine = "" - let b:netrw_fname = "" - let g:netrw_port = "" - let g:netrw_choice = a:choice - - " Patterns: - " mipf : a:machine a:id password filename Use ftp - " mf : a:machine filename Use ftp + <.netrc> or g:netrw_uid g:netrw_passwd - " ftpurm : ftp://[user@]host[[#:]port]/filename Use ftp + <.netrc> or g:netrw_uid g:netrw_passwd - " rcpurm : rcp://[user@]host/filename Use rcp - " rcphf : [user@]host:filename Use rcp - " scpurm : scp://[user@]host[[#:]port]/filename Use scp - " httpurm : http://[user@]host/filename Use wget - " davurm : [s]dav://host[:port]/path Use cadaver - " rsyncurm : rsync://host[:port]/path Use rsync - " fetchurm : fetch://[user@]host[:http]/filename Use fetch (defaults to ftp, override for http) - " sftpurm : sftp://[user@]host/filename Use scp - let mipf = '^\(\S\+\)\s\+\(\S\+\)\s\+\(\S\+\)\s\+\(\S\+\)$' - let mf = '^\(\S\+\)\s\+\(\S\+\)$' - let ftpurm = '^ftp://\(\([^/@]\{-}\)@\)\=\([^/#:]\{-}\)\([#:]\d\+\)\=/\(.*\)$' - let rcpurm = '^rcp://\%(\([^/@]\{-}\)@\)\=\([^/]\{-}\)/\(.*\)$' - let rcphf = '^\(\(\h\w*\)@\)\=\(\h\w*\):\([^@]\+\)$' - let scpurm = '^scp://\([^/#:]\+\)\%([#:]\(\d\+\)\)\=/\(.*\)$' - let httpurm = '^http://\([^/]\{-}\)\(/.*\)\=$' - let davurm = '^s\=dav://\([^/]\+\)/\(.*/\)\([-_.~[:alnum:]]\+\)$' - let rsyncurm = '^rsync://\([^/]\{-}\)/\(.*\)\=$' - let fetchurm = '^fetch://\(\([^/@]\{-}\)@\)\=\([^/#:]\{-}\)\(:http\)\=/\(.*\)$' - let sftpurm = '^sftp://\([^/]\{-}\)/\(.*\)\=$' - -" call Decho("determine method:") - " Determine Method - " rcp://user@hostname/...path-to-file - if match(a:choice,rcpurm) == 0 -" call Decho("rcp://...") - let b:netrw_method = 1 - let userid = substitute(a:choice,rcpurm,'\1',"") - let g:netrw_machine = substitute(a:choice,rcpurm,'\2',"") - let b:netrw_fname = substitute(a:choice,rcpurm,'\3',"") - if userid != "" - let g:netrw_uid= userid - endif - - " scp://user@hostname/...path-to-file - elseif match(a:choice,scpurm) == 0 -" call Decho("scp://...") - let b:netrw_method = 4 - let g:netrw_machine = substitute(a:choice,scpurm,'\1',"") - let g:netrw_port = substitute(a:choice,scpurm,'\2',"") - let b:netrw_fname = substitute(a:choice,scpurm,'\3',"") - - " http://user@hostname/...path-to-file - elseif match(a:choice,httpurm) == 0 -" call Decho("http://...") - let b:netrw_method = 5 - let g:netrw_machine= substitute(a:choice,httpurm,'\1',"") - let b:netrw_fname = substitute(a:choice,httpurm,'\2',"") - - " dav://hostname[:port]/..path-to-file.. - elseif match(a:choice,davurm) == 0 -" call Decho("dav://...") - let b:netrw_method= 6 - if a:choice =~ '^s' - let g:netrw_machine= 'https://'.substitute(a:choice,davurm,'\1/\2',"") - else - let g:netrw_machine= 'http://'.substitute(a:choice,davurm,'\1/\2',"") - endif - let b:netrw_fname = substitute(a:choice,davurm,'\3',"") - - " rsync://user@hostname/...path-to-file - elseif match(a:choice,rsyncurm) == 0 -" call Decho("rsync://...") - let b:netrw_method = 7 - let g:netrw_machine= substitute(a:choice,rsyncurm,'\1',"") - let b:netrw_fname = substitute(a:choice,rsyncurm,'\2',"") - - " ftp://[user@]hostname[[:#]port]/...path-to-file - elseif match(a:choice,ftpurm) == 0 -" call Decho("ftp://...") - let userid = substitute(a:choice,ftpurm,'\2',"") - let g:netrw_machine= substitute(a:choice,ftpurm,'\3',"") - let g:netrw_port = substitute(a:choice,ftpurm,'\4',"") - let b:netrw_fname = substitute(a:choice,ftpurm,'\5',"") - if userid != "" - let g:netrw_uid= userid - endif - if exists("g:netrw_uid") && exists("g:netrw_passwd") - let b:netrw_method = 3 - else - if filereadable(expand("$HOME/.netrc")) && !exists("g:netrw_ignorenetrc") - let b:netrw_method= 2 - else - if !exists("g:netrw_uid") || g:netrw_uid == "" - call NetUserPass() - elseif !exists("g:netrw_passwd") || g:netrw_passwd == "" - call NetUserPass(g:netrw_uid) - " else just use current g:netrw_uid and g:netrw_passwd - endif - let b:netrw_method= 3 - endif - endif - - elseif match(a:choice,fetchurm) == 0 -" call Decho("fetch://...") - let b:netrw_method = 8 - let g:netrw_userid = substitute(a:choice,fetchurm,'\2',"") - let g:netrw_machine= substitute(a:choice,fetchurm,'\3',"") - let b:netrw_option = substitute(a:choice,fetchurm,'\4',"") - let b:netrw_fname = substitute(a:choice,fetchurm,'\5',"") - - " Issue an ftp : "machine id password [path/]filename" - elseif match(a:choice,mipf) == 0 -" call Decho("(ftp) host id pass file") - let b:netrw_method = 3 - let g:netrw_machine = substitute(a:choice,mipf,'\1',"") - let g:netrw_uid = substitute(a:choice,mipf,'\2',"") - let g:netrw_passwd = substitute(a:choice,mipf,'\3',"") - let b:netrw_fname = substitute(a:choice,mipf,'\4',"") - - " Issue an ftp: "hostname [path/]filename" - elseif match(a:choice,mf) == 0 -" call Decho("(ftp) host file") - if exists("g:netrw_uid") && exists("g:netrw_passwd") - let b:netrw_method = 3 - let g:netrw_machine = substitute(a:choice,mf,'\1',"") - let b:netrw_fname = substitute(a:choice,mf,'\2',"") - - elseif filereadable(expand("$HOME/.netrc")) - let b:netrw_method = 2 - let g:netrw_machine = substitute(a:choice,mf,'\1',"") - let b:netrw_fname = substitute(a:choice,mf,'\2',"") - endif - - " sftp://user@hostname/...path-to-file - elseif match(a:choice,sftpurm) == 0 -" call Decho("sftp://...") - let b:netrw_method = 9 - let g:netrw_machine= substitute(a:choice,sftpurm,'\1',"") - let b:netrw_fname = substitute(a:choice,sftpurm,'\2',"") - - " Issue an rcp: hostname:filename" (this one should be last) - elseif match(a:choice,rcphf) == 0 -" call Decho("(rcp) [user@]host:file) rcphf<".rcphf.">") - let b:netrw_method = 1 - let userid = substitute(a:choice,rcphf,'\2',"") - let g:netrw_machine= substitute(a:choice,rcphf,'\3',"") - let b:netrw_fname = substitute(a:choice,rcphf,'\4',"") -" call Decho('\1<'.substitute(a:choice,rcphf,'\1',"").">") -" call Decho('\2<'.substitute(a:choice,rcphf,'\2',"").">") -" call Decho('\3<'.substitute(a:choice,rcphf,'\3',"").">") -" call Decho('\4<'.substitute(a:choice,rcphf,'\4',"").">") - if userid != "" - let g:netrw_uid= userid - endif - if has("win32") || has("win95") || has("win64") || has("win16") - " don't let PCs try <.netrc> - let b:netrw_method = 3 - endif - - else - if !exists("g:netrw_quiet") - echohl Error | echo "***netrw*** cannot determine method" | echohl None - call inputsave()|call input("Press <cr> to continue")|call inputrestore() - endif - let b:netrw_method = -1 - endif - - " remove any leading [:#] from port number - if g:netrw_port != "" - let g:netrw_port = substitute(g:netrw_port,'[#:]\+','','') - endif - -" call Decho("a:choice <".a:choice.">") -" call Decho("b:netrw_method <".b:netrw_method.">") -" call Decho("g:netrw_machine<".g:netrw_machine.">") -" call Decho("g:netrw_port <".g:netrw_port.">") -" if exists("g:netrw_uid") "Decho -" call Decho("g:netrw_uid <".g:netrw_uid.">") -" endif "Decho -" if exists("g:netrw_passwd") "Decho -" call Decho("g:netrw_passwd <".g:netrw_passwd.">") -" endif "Decho -" call Decho("b:netrw_fname <".b:netrw_fname.">") -" call Dret("NetMethod : b:netrw_method=".b:netrw_method) -endfun - -" ------------------------------------------------------------------------ -" NetUserPass: set username and password for subsequent ftp transfer {{{2 -" Usage: :call NetUserPass() -- will prompt for userid and password -" :call NetUserPass("uid") -- will prompt for password -" :call NetUserPass("uid","password") -- sets global userid and password -fun! NetUserPass(...) - - " get/set userid - if a:0 == 0 -" call Dfunc("NetUserPass(a:0<".a:0.">)") - if !exists("g:netrw_uid") || g:netrw_uid == "" - " via prompt - let g:netrw_uid= input('Enter username: ') - endif - else " from command line -" call Dfunc("NetUserPass(a:1<".a:1.">) {") - let g:netrw_uid= a:1 - endif - - " get password - if a:0 <= 1 " via prompt -" call Decho("a:0=".a:0." case <=1:") - let g:netrw_passwd= inputsecret("Enter Password: ") - else " from command line -" call Decho("a:0=".a:0." case >1: a:2<".a:2.">") - let g:netrw_passwd=a:2 - endif - -" call Dret("NetUserPass") -endfun - -" ------------------------------------------------------------------------ -" NetOptionSave: save options and set to "standard" form {{{2 -fun! s:NetOptionSave() -" call Dfunc("NetOptionSave()") - if !exists("w:netoptionsave") - let w:netoptionsave= 1 - else -" call Dret("NetOptionSave : netoptionsave=".w:netoptionsave) - return - endif - - " Get Temporary Filename - if exists("&acd") - let w:acdkeep = &acd - endif - let w:aikeep = &ai - let w:fokeep = &fo - let w:cikeep = &ci - let w:cinkeep = &cin - let w:cinokeep = &cino - let w:comkeep = &com - let w:cpokeep = &cpo - let w:hidkeep = &hidden - let w:magickeep = &magic - if !g:netrw_keepdir - let w:dirkeep = getcwd() - endif - let w:gdkeep = &gd - let w:repkeep = &report - let w:spellkeep = &spell - let w:twkeep = &tw - setlocal cino = - setlocal com = - setlocal cpo -=aA - if exists("&acd") - setlocal noacd nocin noai noci magic nospell fo=nroql2 nohid - else - setlocal nocin noai noci magic nospell fo=nroql2 nohid - endif - setlocal tw =0 - setlocal report=10000 - if has("win32") && !has("win95") - let w:swfkeep= &swf - setlocal noswf -" call Decho("setting w:swfkeep to <".&swf.">") - endif - -" call Dret("NetOptionSave") -endfun - -" ------------------------------------------------------------------------ -" NetOptionRestore: restore options {{{2 -fun! s:NetOptionRestore() -" call Dfunc("NetOptionRestore()") - if !exists("w:netoptionsave") -" call Dret("NetOptionRestore : w:netoptionsave doesn't exist") - return - endif - unlet w:netoptionsave - - if exists("&acd") - if exists("w:acdkeep") |let &acd = w:acdkeep |unlet w:acdkeep |endif - endif - if exists("w:aikeep") |let &ai = w:aikeep |unlet w:aikeep |endif - if exists("w:cikeep") |let &ci = w:cikeep |unlet w:cikeep |endif - if exists("w:cinkeep") |let &cin = w:cinkeep |unlet w:cinkeep |endif - if exists("w:cinokeep") |let &cino = w:cinokeep |unlet w:cinokeep |endif - if exists("w:comkeep") |let &com = w:comkeep |unlet w:comkeep |endif - if exists("w:cpokeep") |let &cpo = w:cpokeep |unlet w:cpokeep |endif - if exists("w:dirkeep") |exe "lcd ".w:dirkeep |unlet w:dirkeep |endif - if exists("w:fokeep") |let &fo = w:fokeep |unlet w:fokeep |endif - if exists("w:gdkeep") |let &gd = w:gdkeep |unlet w:gdkeep |endif - if exists("w:hidkeep") |let &hidden = w:hidkeep |unlet w:hidkeep |endif - if exists("w:magic") |let &magic = w:magic |unlet w:magic |endif - if exists("w:repkeep") |let &report = w:repkeep |unlet w:repkeep |endif - if exists("w:spellkeep")|let &spell = w:spellkeep |unlet w:spellkeep|endif - if exists("w:twkeep") |let &tw = w:twkeep |unlet w:twkeep |endif - if exists("w:swfkeep") - if &directory == "" && exists("w:swfkeep") - " user hasn't specified a swapfile directory; - " netrw will temporarily make the swapfile - " directory the current local one. - let &directory = getcwd() - silent! let &swf = w:swfkeep - set directory= - else - let &swf= w:swfkeep - endif - unlet w:swfkeep - endif - -" call Dret("NetOptionRestore") -endfun - -" ------------------------------------------------------------------------ -" NetReadFixup: this sort of function is typically written by the user {{{2 -" to handle extra junk that their system's ftp dumps -" into the transfer. This function is provided as an -" example and as a fix for a Windows 95 problem: in my -" experience, win95's ftp always dumped four blank lines -" at the end of the transfer. -if has("win95") && exists("g:netrw_win95ftp") && g:netrw_win95ftp - fun! NetReadFixup(method, line1, line2) -" call Dfunc("NetReadFixup(method<".a:method."> line1=".a:line1." line2=".a:line2.")") - if method == 3 " ftp (no <.netrc>) - let fourblanklines= line2 - 3 - silent fourblanklines.",".line2."g/^\s*/d" - endif -" call Dret("NetReadFixup") - endfun -endif - -" --------------------------------------------------------------------- -" NetSort: Piet Delport's BISort2() function, modified to take a range {{{2 -if v:version < 700 - fun! s:NetSort() range -" " call Dfunc("NetSort()") - - let i = a:firstline + 1 - while i <= a:lastline - " find insertion point via binary search - let i_val = getline(i) - let lo = a:firstline - let hi = i - while lo < hi - let mid = (lo + hi) / 2 - let mid_val = getline(mid) - if g:netrw_sort_direction =~ '^n' - " normal sorting order - if i_val < mid_val - let hi = mid - else - let lo = mid + 1 - if i_val == mid_val | break | endif - endif - else - " reverse sorting order - if i_val > mid_val - let hi = mid - else - let lo = mid + 1 - if i_val == mid_val | break | endif - endif - endif - endwhile - " do insert - if lo < i - exe 'keepjumps '.i.'d_' - keepjumps call append(lo - 1, i_val) - endif - let i = i + 1 - endwhile - -" " call Dret("NetSort") - endfun -endif - -" --------------------------------------------------------------------- " SetSort: sets up the sort based on the g:netrw_sort_sequence {{{2 " What this function does is to compute a priority for the patterns " in the g:netrw_sort_sequence. It applies a substitute to any @@ -4200,7 +4829,7 @@ endif " front. An "*" pattern handles the default priority. fun! s:SetSort() " call Dfunc("SetSort() bannercnt=".w:netrw_bannercnt) - if w:netrw_longlist == 1 + if w:netrw_liststyle == s:LONGLIST let seqlist = substitute(g:netrw_sort_sequence,'\$','\\%(\t\\|\$\\)','ge') else let seqlist = g:netrw_sort_sequence @@ -4255,66 +4884,403 @@ fun! s:SetSort() " call Dret("SetSort") endfun +" ===================================================================== +" Support Functions: {{{1 + " --------------------------------------------------------------------- -" SaveWinVars: (used by Explore()) {{{2 -fun! s:SaveWinVars() -" call Dfunc("SaveWinVars()") - if exists("w:netrw_bannercnt") |let s:bannercnt = w:netrw_bannercnt |endif - if exists("w:netrw_method") |let s:method = w:netrw_method |endif - if exists("w:netrw_prvdir") |let s:prvdir = w:netrw_prvdir |endif - if exists("w:netrw_explore_indx") |let s:explore_indx = w:netrw_explore_indx |endif - if exists("w:netrw_explore_listlen")|let s:explore_listlen = w:netrw_explore_listlen|endif - if exists("w:netrw_explore_mtchcnt")|let s:explore_mtchcnt = w:netrw_explore_mtchcnt|endif - if exists("w:netrw_explore_bufnr") |let s:explore_bufnr = w:netrw_explore_bufnr |endif - if exists("w:netrw_explore_line") |let s:explore_line = w:netrw_explore_line |endif - if exists("w:netrw_explore_list") |let s:explore_list = w:netrw_explore_list |endif -" call Dret("SaveWinVars") +" ComposePath: Appends a new part to a path taking different systems into consideration {{{2 +fun! s:ComposePath(base,subdir) +" call Dfunc("s:ComposePath(base<".a:base."> subdir<".a:subdir.">)") + if(has("amiga")) + let ec = a:base[strlen(a:base)-1] + if ec != '/' && ec != ':' + let ret = a:base . "/" . a:subdir + else + let ret = a:base . a:subdir + endif + elseif a:base =~ '^\a\+://' + let urlbase = substitute(a:base,'^\(\a\+://.\{-}/\)\(.*\)$','\1','') + let curpath = substitute(a:base,'^\(\a\+://.\{-}/\)\(.*\)$','\2','') + let ret = urlbase.curpath.a:subdir +" call Decho("urlbase<".urlbase.">") +" call Decho("curpath<".curpath.">") +" call Decho("ret<".ret.">") + else + let ret = substitute(a:base."/".a:subdir,"//","/","g") + endif +" call Dret("s:ComposePath ".ret) + return ret +endfun + +" --------------------------------------------------------------------- +" netrw#ErrorMsg: {{{2 +" 0=note = s:NOTE +" 1=warning = s:WARNING +" 2=error = s:ERROR +" Mar 19, 2007 : max errnum currently is 49 +fun! netrw#ErrorMsg(level,msg,errnum) +" call Dfunc("netrw#ErrorMsg(level=".a:level." msg<".a:msg."> errnum=".a:errnum.")") + + " record current window number for NetRestorePosn()'s benefit + let s:winBeforeErr= winnr() + + " getting messages out reliably is just plain difficult! + " This attempt splits the current window, creating a one line window. + let errbufnum= bufnr("NetrwMessage") + + bo 1split + enew + setlocal bt=nofile + file NetrwMessage + + put ='***netrw*** '.a:msg + if &fo !~ '[ta]' + syn clear + syn match netrwMesg "^\*\*\*netrw\*\*\*" + if a:level == s:WARNING + hi link netrwMesg WarningMsg + elseif a:level == s:ERROR + hi link netrwMesg Error + endif + endif + 1d + setlocal noma ro bh=wipe + +" call Dret("netrw#ErrorMsg") +endfun + +" --------------------------------------------------------------------- +" netrw#RFC2396: converts %xx into characters {{{2 +fun! netrw#RFC2396(fname) +" call Dfunc("netrw#RFC2396(fname<".a:fname.">)") + let fname = escape(substitute(a:fname,'%\(\x\x\)','\=nr2char("0x".submatch(1))','ge')," \t") +" call Dret("netrw#RFC2396 ".fname) + return fname +endfun + +" --------------------------------------------------------------------- +" s:FileReadable: o/s independent filereadable {{{2 +fun! s:FileReadable(fname) +" call Dfunc("s:FileReadable(fname<".a:fname.">)") + + if g:netrw_cygwin + let ret= filereadable(substitute(a:fname,'/cygdrive/\(.\)','\1:/','')) + else + let ret= filereadable(a:fname) + endif + +" call Dret("s:FileReadable ".ret) + return ret endfun " --------------------------------------------------------------------- -" CopyWinVars: (used by Explore()) {{{2 -fun! s:CopyWinVars() -" call Dfunc("CopyWinVars()") +" s:GetTempfile: gets a tempname that'll work for various o/s's {{{2 +" Places correct suffix on end of temporary filename, +" using the suffix provided with fname +fun! s:GetTempfile(fname) +" call Dfunc("s:GetTempfile(fname<".a:fname.">)") + + if !exists("b:netrw_tmpfile") + " get a brand new temporary filename + let tmpfile= tempname() +" call Decho("tmpfile<".tmpfile."> : from tempname()") + + let tmpfile= escape(substitute(tmpfile,'\','/','ge'),g:netrw_tmpfile_escape) +" call Decho("tmpfile<".tmpfile."> : chgd any \\ -> /") + + " sanity check -- does the temporary file's directory exist? + if !isdirectory(substitute(tmpfile,'[^/]\+$','','e')) + call netrw#ErrorMsg(s:ERROR,"your <".substitute(tmpfile,'[^/]\+$','','e')."> directory is missing!",2) +" call Dret("s:GetTempfile getcwd<".getcwd().">") + return "" + endif + + " let netrw#NetSource() know about the tmpfile + let s:netrw_tmpfile= tmpfile " used by netrw#NetSource() +" call Decho("tmpfile<".tmpfile."> s:netrw_tmpfile<".s:netrw_tmpfile.">") + + " o/s dependencies + if g:netrw_cygwin == 1 + let tmpfile = substitute(tmpfile,'^\(\a\):','/cygdrive/\1','e') + elseif has("win32") || has("win95") || has("win64") || has("win16") + let tmpfile = substitute(tmpfile,'/','\\','g') + else + let tmpfile = tmpfile + endif + let b:netrw_tmpfile= tmpfile +" call Decho("o/s dependent fixed tempname<".tmpfile.">") + else + " re-use temporary filename + let tmpfile= b:netrw_tmpfile +" call Decho("tmpfile<".tmpfile."> re-using") + endif + + " use fname's suffix for the temporary file + if a:fname != "" + if a:fname =~ '\.[^./]\+$' +" call Decho("using fname<".a:fname.">'s suffix") + if a:fname =~ '.tar.gz' || a:fname =~ '.tar.bz2' + let suffix = ".tar".substitute(a:fname,'^.*\(\.[^./]\+\)$','\1','e') + else + let suffix = substitute(a:fname,'^.*\(\.[^./]\+\)$','\1','e') + endif + let suffix = escape(suffix,g:netrw_tmpfile_escape) +" call Decho("suffix<".suffix.">") + let tmpfile= substitute(tmpfile,'\.tmp$','','e') +" call Decho("chgd tmpfile<".tmpfile."> (removed any .tmp suffix)") + let tmpfile .= suffix +" call Decho("chgd tmpfile<".tmpfile."> (added ".suffix." suffix) netrw_fname<".b:netrw_fname.">") + let s:netrw_tmpfile= tmpfile " supports netrw#NetSource() + endif + endif + +" call Dret("s:GetTempfile <".tmpfile.">") + return tmpfile +endfun + +" --------------------------------------------------------------------- +" s:MakeSshCmd: transforms input command using USEPORT HOSTNAME into {{{2 +" a correct command +fun! s:MakeSshCmd(sshcmd) +" call Dfunc("s:MakeSshCmd(sshcmd<".a:sshcmd.">)") + let sshcmd = substitute(a:sshcmd,'\<HOSTNAME\>',s:user.s:machine,'') + if exists("g:netrw_port") && g:netrw_port != "" + let sshcmd= substitute(sshcmd,"USEPORT",'-P '.g:netrw_port,'') + elseif exists("s:port") && s:port != "" + let sshcmd= substitute(sshcmd,"USEPORT",'-P '.s:port,'') + else + let sshcmd= substitute(sshcmd,"USEPORT ",'','') + endif +" call Dret("s:MakeSshCmd <".sshcmd.">") + return sshcmd +endfun + +" --------------------------------------------------------------------- +" s:NetrwEnew: opens a new buffer, passes netrw buffer variables through {{{2 +fun! s:NetrwEnew(curdir) +" call Dfunc("s:NetrwEnew(curdir<".a:curdir.">) expand(%)<".expand("%").">") + + " grab a function-local copy of buffer variables + if exists("b:netrw_bannercnt") |let netrw_bannercnt = b:netrw_bannercnt |endif + if exists("b:netrw_browser_active") |let netrw_browser_active = b:netrw_browser_active |endif + if exists("b:netrw_cpf") |let netrw_cpf = b:netrw_cpf |endif + if exists("b:netrw_curdir") |let netrw_curdir = b:netrw_curdir |endif + if exists("b:netrw_explore_bufnr") |let netrw_explore_bufnr = b:netrw_explore_bufnr |endif + if exists("b:netrw_explore_indx") |let netrw_explore_indx = b:netrw_explore_indx |endif + if exists("b:netrw_explore_line") |let netrw_explore_line = b:netrw_explore_line |endif + if exists("b:netrw_explore_list") |let netrw_explore_list = b:netrw_explore_list |endif + if exists("b:netrw_explore_listlen")|let netrw_explore_listlen = b:netrw_explore_listlen|endif + if exists("b:netrw_explore_mtchcnt")|let netrw_explore_mtchcnt = b:netrw_explore_mtchcnt|endif + if exists("b:netrw_fname") |let netrw_fname = b:netrw_fname |endif + if exists("b:netrw_lastfile") |let netrw_lastfile = b:netrw_lastfile |endif + if exists("b:netrw_liststyle") |let netrw_liststyle = b:netrw_liststyle |endif + if exists("b:netrw_method") |let netrw_method = b:netrw_method |endif + if exists("b:netrw_option") |let netrw_option = b:netrw_option |endif + if exists("b:netrw_prvdir") |let netrw_prvdir = b:netrw_prvdir |endif + + if getline(2) =~ '^" Netrw Directory Listing' +" call Decho("generate a buffer with keepjumps keepalt enew! (1)") + keepjumps keepalt enew! + else +" call Decho("generate a buffer with keepjumps enew! (2)") + keepjumps enew! + endif + + " copy function-local variables to buffer variable equivalents + if exists("netrw_bannercnt") |let b:netrw_bannercnt = netrw_bannercnt |endif + if exists("netrw_browser_active") |let b:netrw_browser_active = netrw_browser_active |endif + if exists("netrw_cpf") |let b:netrw_cpf = netrw_cpf |endif + if exists("netrw_curdir") |let b:netrw_curdir = netrw_curdir |endif + if exists("netrw_explore_bufnr") |let b:netrw_explore_bufnr = netrw_explore_bufnr |endif + if exists("netrw_explore_indx") |let b:netrw_explore_indx = netrw_explore_indx |endif + if exists("netrw_explore_line") |let b:netrw_explore_line = netrw_explore_line |endif + if exists("netrw_explore_list") |let b:netrw_explore_list = netrw_explore_list |endif + if exists("netrw_explore_listlen")|let b:netrw_explore_listlen = netrw_explore_listlen|endif + if exists("netrw_explore_mtchcnt")|let b:netrw_explore_mtchcnt = netrw_explore_mtchcnt|endif + if exists("netrw_fname") |let b:netrw_fname = netrw_fname |endif + if exists("netrw_lastfile") |let b:netrw_lastfile = netrw_lastfile |endif + if exists("netrw_liststyle") |let b:netrw_liststyle = netrw_liststyle |endif + if exists("netrw_method") |let b:netrw_method = netrw_method |endif + if exists("netrw_option") |let b:netrw_option = netrw_option |endif + if exists("netrw_prvdir") |let b:netrw_prvdir = netrw_prvdir |endif + + let b:netrw_curdir= a:curdir + if b:netrw_curdir =~ '/$' + if exists("w:netrw_liststyle") && w:netrw_liststyle == s:TREELIST + file NetrwTreeListing + else + exe "silent! file ".b:netrw_curdir + endif + endif + +" call Dret("s:NetrwEnew : buf#".bufnr("%")) +endfun + +" ------------------------------------------------------------------------ +" s:RemotePathAnalysis: {{{2 +fun! s:RemotePathAnalysis(dirname) +" call Dfunc("s:RemotePathAnalysis()") + + let dirpat = '^\(\w\{-}\)://\(\w\+@\)\=\([^/:#]\+\)\%([:#]\(\d\+\)\)\=/\(.*\)$' + let s:method = substitute(a:dirname,dirpat,'\1','') + let s:user = substitute(a:dirname,dirpat,'\2','') + let s:machine = substitute(a:dirname,dirpat,'\3','') + let s:port = substitute(a:dirname,dirpat,'\4','') + let s:path = substitute(a:dirname,dirpat,'\5','') + let s:fname = substitute(a:dirname,'^.*/\ze.','','') + +" call Decho("set up s:method <".s:method .">") +" call Decho("set up s:user <".s:user .">") +" call Decho("set up s:machine<".s:machine.">") +" call Decho("set up s:port <".s:port.">") +" call Decho("set up s:path <".s:path .">") +" call Decho("set up s:fname <".s:fname .">") + +" call Dret("s:RemotePathAnalysis") +endfun + +" --------------------------------------------------------------------- +" s:RestoreBufVars: {{{2 +fun! s:RestoreBufVars() +" call Dfunc("s:RestoreBufVars()") + + if exists("s:netrw_curdir") |let b:netrw_curdir = s:netrw_curdir |endif + if exists("s:netrw_lastfile") |let b:netrw_lastfile = s:netrw_lastfile |endif + if exists("s:netrw_method") |let b:netrw_method = s:netrw_method |endif + if exists("s:netrw_fname") |let b:netrw_fname = s:netrw_fname |endif + if exists("s:netrw_machine") |let b:netrw_machine = s:netrw_machine |endif + if exists("s:netrw_browser_active")|let b:netrw_browser_active = s:netrw_browser_active|endif + +" call Dret("s:RestoreBufVars") +endfun + +" --------------------------------------------------------------------- +" s:RestoreWinVars: (used by Explore() and NetSplit()) {{{2 +fun! s:RestoreWinVars() +" call Dfunc("s:RestoreWinVars()") if exists("s:bannercnt") |let w:netrw_bannercnt = s:bannercnt |unlet s:bannercnt |endif - if exists("s:method") |let w:netrw_method = s:method |unlet s:method |endif - if exists("s:prvdir") |let w:netrw_prvdir = s:prvdir |unlet s:prvdir |endif - if exists("s:explore_indx") |let w:netrw_explore_indx = s:explore_indx |unlet s:explore_indx |endif - if exists("s:explore_listlen")|let w:netrw_explore_listlen = s:explore_listlen|unlet s:explore_listlen|endif - if exists("s:explore_mtchcnt")|let w:netrw_explore_mtchcnt = s:explore_mtchcnt|unlet s:explore_mtchcnt|endif + if exists("s:col") |let w:netrw_col = s:col |unlet s:col |endif + if exists("s:curdir") |let w:netrw_curdir = s:curdir |unlet s:curdir |endif if exists("s:explore_bufnr") |let w:netrw_explore_bufnr = s:explore_bufnr |unlet s:explore_bufnr |endif + if exists("s:explore_indx") |let w:netrw_explore_indx = s:explore_indx |unlet s:explore_indx |endif if exists("s:explore_line") |let w:netrw_explore_line = s:explore_line |unlet s:explore_line |endif + if exists("s:explore_listlen")|let w:netrw_explore_listlen = s:explore_listlen|unlet s:explore_listlen|endif if exists("s:explore_list") |let w:netrw_explore_list = s:explore_list |unlet s:explore_list |endif -" call Dret("CopyWinVars") + if exists("s:explore_mtchcnt")|let w:netrw_explore_mtchcnt = s:explore_mtchcnt|unlet s:explore_mtchcnt|endif + if exists("s:fpl") |let w:netrw_fpl = s:fpl |unlet s:fpl |endif + if exists("s:hline") |let w:netrw_hline = s:hline |unlet s:hline |endif + if exists("s:line") |let w:netrw_line = s:line |unlet s:line |endif + if exists("s:liststyle") |let w:netrw_liststyle = s:liststyle |unlet s:liststyle |endif + if exists("s:method") |let w:netrw_method = s:method |unlet s:method |endif + if exists("s:prvdir") |let w:netrw_prvdir = s:prvdir |unlet s:prvdir |endif + if exists("s:treedict") |let w:netrw_treedict = s:treedict |unlet s:treedict |endif + if exists("s:treetop") |let w:netrw_treetop = s:treetop |unlet s:treetop |endif + if exists("s:winnr") |let w:netrw_winnr = s:winnr |unlet s:winnr |endif +" call Dret("s:RestoreWinVars") +endfun + +" --------------------------------------------------------------------- +" s:SaveBufVars: {{{2 +fun! s:SaveBufVars() +" call Dfunc("s:SaveBufVars()") + + if exists("b:netrw_curdir") |let s:netrw_curdir = b:netrw_curdir |endif + if exists("b:netrw_lastfile") |let s:netrw_lastfile = b:netrw_lastfile |endif + if exists("b:netrw_method") |let s:netrw_method = b:netrw_method |endif + if exists("b:netrw_fname") |let s:netrw_fname = b:netrw_fname |endif + if exists("b:netrw_machine") |let s:netrw_machine = b:netrw_machine |endif + if exists("b:netrw_browser_active")|let s:netrw_browser_active = b:netrw_browser_active|endif + +" call Dret("s:SaveBufVars") endfun " --------------------------------------------------------------------- -" SetBufWinVars: (used by NetBrowse() and LocalBrowse()) {{{2 +" s:SaveWinVars: (used by Explore() and NetSplit()) {{{2 +fun! s:SaveWinVars() +" call Dfunc("s:SaveWinVars()") + if exists("w:netrw_bannercnt") |let s:bannercnt = w:netrw_bannercnt |endif + if exists("w:netrw_col") |let s:col = w:netrw_col |endif + if exists("w:netrw_curdir") |let s:curdir = w:netrw_curdir |endif + if exists("w:netrw_explore_bufnr") |let s:explore_bufnr = w:netrw_explore_bufnr |endif + if exists("w:netrw_explore_indx") |let s:explore_indx = w:netrw_explore_indx |endif + if exists("w:netrw_explore_line") |let s:explore_line = w:netrw_explore_line |endif + if exists("w:netrw_explore_listlen")|let s:explore_listlen = w:netrw_explore_listlen|endif + if exists("w:netrw_explore_list") |let s:explore_list = w:netrw_explore_list |endif + if exists("w:netrw_explore_mtchcnt")|let s:explore_mtchcnt = w:netrw_explore_mtchcnt|endif + if exists("w:netrw_fpl") |let s:fpl = w:netrw_fpl |endif + if exists("w:netrw_hline") |let s:hline = w:netrw_hline |endif + if exists("w:netrw_line") |let s:line = w:netrw_line |endif + if exists("w:netrw_liststyle") |let s:liststyle = w:netrw_liststyle |endif + if exists("w:netrw_method") |let s:method = w:netrw_method |endif + if exists("w:netrw_prvdir") |let s:prvdir = w:netrw_prvdir |endif + if exists("w:netrw_treedict") |let s:treedict = w:netrw_treedict |endif + if exists("w:netrw_treetop") |let s:treetop = w:netrw_treetop |endif + if exists("w:netrw_winnr") |let s:winnr = w:netrw_winnr |endif +" call Dret("s:SaveWinVars") +endfun + +" --------------------------------------------------------------------- +" s:SetBufWinVars: (used by NetBrowse() and LocalBrowseCheck()) {{{2 " To allow separate windows to have their own activities, such as " Explore **/pattern, several variables have been made window-oriented. " However, when the user splits a browser window (ex: ctrl-w s), these " variables are not inherited by the new window. SetBufWinVars() and " UseBufWinVars() get around that. fun! s:SetBufWinVars() -" call Dfunc("SetBufWinVars()") - if exists("w:netrw_longlist") |let b:netrw_longlist = w:netrw_longlist |endif - if exists("w:netrw_bannercnt") |let b:netrw_bannercnt = w:netrw_bannercnt |endif - if exists("w:netrw_method") |let b:netrw_method = w:netrw_method |endif - if exists("w:netrw_prvdir") |let b:netrw_prvdir = w:netrw_prvdir |endif - if exists("w:netrw_explore_indx") |let b:netrw_explore_indx = w:netrw_explore_indx |endif - if exists("w:netrw_explore_listlen")|let b:netrw_explore_listlen = w:netrw_explore_listlen|endif - if exists("w:netrw_explore_mtchcnt")|let b:netrw_explore_mtchcnt = w:netrw_explore_mtchcnt|endif - if exists("w:netrw_explore_bufnr") |let b:netrw_explore_bufnr = w:netrw_explore_bufnr |endif - if exists("w:netrw_explore_line") |let b:netrw_explore_line = w:netrw_explore_line |endif - if exists("w:netrw_explore_list") |let b:netrw_explore_list = w:netrw_explore_list |endif -" call Dret("SetBufWinVars") +" call Dfunc("s:SetBufWinVars()") + if exists("w:netrw_liststyle") |let b:netrw_liststyle = w:netrw_liststyle |endif + if exists("w:netrw_bannercnt") |let b:netrw_bannercnt = w:netrw_bannercnt |endif + if exists("w:netrw_method") |let b:netrw_method = w:netrw_method |endif + if exists("w:netrw_prvdir") |let b:netrw_prvdir = w:netrw_prvdir |endif + if exists("w:netrw_explore_indx") |let b:netrw_explore_indx = w:netrw_explore_indx |endif + if exists("w:netrw_explore_listlen")|let b:netrw_explore_listlen= w:netrw_explore_listlen|endif + if exists("w:netrw_explore_mtchcnt")|let b:netrw_explore_mtchcnt= w:netrw_explore_mtchcnt|endif + if exists("w:netrw_explore_bufnr") |let b:netrw_explore_bufnr = w:netrw_explore_bufnr |endif + if exists("w:netrw_explore_line") |let b:netrw_explore_line = w:netrw_explore_line |endif + if exists("w:netrw_explore_list") |let b:netrw_explore_list = w:netrw_explore_list |endif +" call Dret("s:SetBufWinVars") +endfun + +" --------------------------------------------------------------------- +" s:System: using Steve Hall's idea to insure that Windows paths stay {{{2 +" acceptable. No effect on Unix paths. +" Examples of use: let result= s:System("system",path) +" let result= s:System("delete",path) +fun! s:System(cmd,path) +" call Dfunc("s:System(cmd<".a:cmd."> path<".a:path.">)") + + let path = a:path + if (has("win32") || has("win95") || has("win64") || has("win16")) + " system call prep + " remove trailing slash (Win95) + let path = substitute(path, '\(\\\|/\)$', '', 'g') + " remove escaped spaces + let path = substitute(path, '\ ', ' ', 'g') + " convert slashes to backslashes + let path = substitute(path, '/', '\', 'g') + if exists("+shellslash") + let sskeep= &shellslash + setlocal noshellslash + exe "let result= ".a:cmd."('".path."')" + let &shellslash = sskeep + else + exe "let result= ".a:cmd."(".g:netrw_shq.path.g:netrw_shq.")" + endif + else + exe "let result= ".a:cmd."('".path."')" + endif + +" call Decho("result<".result.">") +" call Dret("s:System") + return result endfun " --------------------------------------------------------------------- -" UseBufWinVars: (used by NetBrowse() and LocalBrowse() {{{2 +" s:UseBufWinVars: (used by NetBrowse() and LocalBrowseCheck() {{{2 " Matching function to BufferWinVars() fun! s:UseBufWinVars() -" call Dfunc("UseBufWinVars()") - if exists("b:netrw_longlist") && !exists("w:netrw_longlist") |let w:netrw_longlist = b:netrw_longlist |endif +" call Dfunc("s:UseBufWinVars()") + if exists("b:netrw_liststyle") && !exists("w:netrw_liststyle") |let w:netrw_liststyle = b:netrw_liststyle |endif if exists("b:netrw_bannercnt") && !exists("w:netrw_bannercnt") |let w:netrw_bannercnt = b:netrw_bannercnt |endif if exists("b:netrw_method") && !exists("w:netrw_method") |let w:netrw_method = b:netrw_method |endif if exists("b:netrw_prvdir") && !exists("w:netrw_prvdir") |let w:netrw_prvdir = b:netrw_prvdir |endif @@ -4324,19 +5290,10 @@ fun! s:UseBufWinVars() if exists("b:netrw_explore_bufnr") && !exists("w:netrw_explore_bufnr") |let w:netrw_explore_bufnr = b:netrw_explore_bufnr |endif if exists("b:netrw_explore_line") && !exists("w:netrw_explore_line") |let w:netrw_explore_line = b:netrw_explore_line |endif if exists("b:netrw_explore_list") && !exists("w:netrw_explore_list") |let w:netrw_explore_list = b:netrw_explore_list |endif -" call Dret("UseBufWinVars") +" call Dret("s:UseBufWinVars") endfun " --------------------------------------------------------------------- -" RFC2396: converts %xx into characters {{{2 -fun! netrw#RFC2396(fname) -" call Dfunc("RFC2396(fname<".a:fname.">)") - let fname = escape(substitute(a:fname,'%\(\x\x\)','\=nr2char("0x".submatch(1))','ge')," \t") -" call Dret("RFC2396 ".fname) - return fname -endfun - -" ------------------------------------------------------------------------ " Settings Restoration: {{{2 let &cpo= s:keepcpo unlet s:keepcpo diff --git a/runtime/autoload/pythoncomplete.vim b/runtime/autoload/pythoncomplete.vim index ee217ed2c..2f52f97e2 100644 --- a/runtime/autoload/pythoncomplete.vim +++ b/runtime/autoload/pythoncomplete.vim @@ -1,16 +1,34 @@ "pythoncomplete.vim - Omni Completion for python " Maintainer: Aaron Griffin <aaronmgriffin@gmail.com> -" Version: 0.5 -" Last Updated: 19 April 2006 -" -" Yeah, I skipped a version number - 0.4 was never public. -" It was a bugfix version on top of 0.3. This is a complete -" rewrite. +" Version: 0.7 +" Last Updated: 19 Oct 2006 " +" Changes " TODO: " User defined docstrings aren't handled right... " 'info' item output can use some formatting work " Add an "unsafe eval" mode, to allow for return type evaluation +" Complete basic syntax along with import statements +" i.e. "import url<c-x,c-o>" +" Continue parsing on invalid line?? +" +" v 0.7 +" * Fixed function list sorting (_ and __ at the bottom) +" * Removed newline removal from docs. It appears vim handles these better in +" recent patches +" +" v 0.6: +" * Fixed argument completion +" * Removed the 'kind' completions, as they are better indicated +" with real syntax +" * Added tuple assignment parsing (whoops, that was forgotten) +" * Fixed import handling when flattening scope +" +" v 0.5: +" Yeah, I skipped a version number - 0.4 was never public. +" It was a bugfix version on top of 0.3. This is a complete +" rewrite. +" if !has('python') echo "Error: Required vim compiled with +python" @@ -28,7 +46,7 @@ function! pythoncomplete#Complete(findstart, base) if c =~ '\w' continue elseif ! c =~ '\.' - idx = -1 + let idx = -1 break else break @@ -45,7 +63,7 @@ function! pythoncomplete#Complete(findstart, base) while idx > 0 let idx -= 1 let c = line[idx] - if c =~ '\w' || c =~ '\.' + if c =~ '\w' || c =~ '\.' || c == '(' let cword = c . cword continue elseif strlen(cword) > 0 || idx == 0 @@ -73,7 +91,24 @@ def vimcomplete(context,match): try: import vim def complsort(x,y): - return x['abbr'] > y['abbr'] + try: + xa = x['abbr'] + ya = y['abbr'] + if xa[0] == '_': + if xa[1] == '_' and ya[0:2] == '__': + return xa > ya + elif ya[0:2] == '__': + return -1 + elif y[0] == '_': + return xa > ya + else: + return 1 + elif ya[0] == '_': + return -1 + else: + return xa > ya + except: + return 0 cmpl = Completer() cmpl.evalsource('\n'.join(vim.current.buffer),vim.eval("line('.')")) all = cmpl.get_completions(context,match) @@ -86,7 +121,7 @@ def vimcomplete(context,match): dictstr += '"icase":0},' if dictstr[-1] == ',': dictstr = dictstr[:-1] dictstr += ']' - dbg("dict: %s" % dictstr) + #dbg("dict: %s" % dictstr) vim.command("silent let g:pythoncomplete_completions = %s" % dictstr) #dbg("Completion dict:\n%s" % all) except vim.error: @@ -108,11 +143,7 @@ class Completer(object): except: dbg("locals: %s, %s [%s]" % (sys.exc_info()[0],sys.exc_info()[1],l)) def _cleanstr(self,doc): - return doc.replace('"',' ')\ - .replace("'",' ')\ - .replace('\n',' ')\ - .replace('\r',' ')\ - .replace('
',' ') + return doc.replace('"',' ').replace("'",' ') def get_arguments(self,func_obj): def _ctor(obj): @@ -128,23 +159,23 @@ class Completer(object): elif type(func_obj) == types.MethodType: func_obj = func_obj.im_func else: arg_offset = 0 - arg_text = ')' + arg_text='' if type(func_obj) in [types.FunctionType, types.LambdaType]: try: cd = func_obj.func_code real_args = cd.co_varnames[arg_offset:cd.co_argcount] - defaults = func_obj.func_defaults or [] - defaults = [map(lambda name: "=%s" % name, defaults)] + defaults = func_obj.func_defaults or '' + defaults = map(lambda name: "=%s" % name, defaults) defaults = [""] * (len(real_args)-len(defaults)) + defaults items = map(lambda a,d: a+d, real_args, defaults) if func_obj.func_code.co_flags & 0x4: items.append("...") if func_obj.func_code.co_flags & 0x8: items.append("***") - arg_text = ", ".join(items) + ')' + arg_text = (','.join(items)) + ')' except: - dbg("completion: %s: %s" % (sys.exc_info()[0],sys.exc_info()[1])) + dbg("arg completion: %s: %s" % (sys.exc_info()[0],sys.exc_info()[1])) pass if len(arg_text) == 0: # The doc string sometimes contains the function signature @@ -160,6 +191,7 @@ class Completer(object): ridx = sigline.find(')') if lidx > 0 and ridx > 0: arg_text = sigline[lidx+1:ridx] + ')' + if len(arg_text) == 0: arg_text = ')' return arg_text def get_completions(self,context,match): @@ -172,12 +204,11 @@ class Completer(object): all = {} ridx = stmt.rfind('.') if len(stmt) > 0 and stmt[-1] == '(': - #TODO result = eval(_sanitize(stmt[:-1]), self.compldict) doc = result.__doc__ if doc == None: doc = '' - args = self.get_arguments(res) - return [{'word':self._cleanstr(args),'info':self._cleanstr(doc),'kind':'p'}] + args = self.get_arguments(result) + return [{'word':self._cleanstr(args),'info':self._cleanstr(doc)}] elif ridx == -1: match = stmt all = self.compldict @@ -206,22 +237,18 @@ class Completer(object): if doc == None or doc == '': doc = maindoc wrd = m[len(match):] - c = {'word':wrd, 'abbr':m, 'info':self._cleanstr(doc),'kind':'m'} + c = {'word':wrd, 'abbr':m, 'info':self._cleanstr(doc)} if "function" in typestr: c['word'] += '(' c['abbr'] += '(' + self._cleanstr(self.get_arguments(inst)) - c['kind'] = 'f' elif "method" in typestr: c['word'] += '(' c['abbr'] += '(' + self._cleanstr(self.get_arguments(inst)) - c['kind'] = 'f' elif "module" in typestr: c['word'] += '.' - c['kind'] = 'm' elif "class" in typestr: c['word'] += '(' c['abbr'] += '(' - c['kind']='c' completions.append(c) except: i = sys.exc_info() @@ -277,10 +304,13 @@ class Scope(object): # we need to start with this, to fix up broken completions # hopefully this name is unique enough... str = '"""'+self.docstr+'"""\n' + for l in self.locals: + if l.startswith('import'): str += l+'\n' str += 'class _PyCmplNoType:\n def __getattr__(self,name):\n return None\n' for sub in self.subscopes: str += sub.get_code() - #str += '\n'.join(self.locals)+'\n' + for l in self.locals: + if not l.startswith('import'): str += l+'\n' return str @@ -420,6 +450,8 @@ class PyParser: tokentype, token, indent = self.next() if tokentype == tokenize.STRING or token == 'str': return '""' + elif token == '(' or token == 'tuple': + return '()' elif token == '[' or token == 'list': return '[]' elif token == '{' or token == 'dict': @@ -494,9 +526,9 @@ class PyParser: freshscope=True while True: tokentype, token, indent = self.next() - #print 'main: token=[%s] indent=[%s]' % (token,indent) + #dbg( 'main: token=[%s] indent=[%s]' % (token,indent)) - if tokentype == DEDENT: + if tokentype == DEDENT or token == "pass": self.scope = self.scope.pop(indent) elif token == 'def': func = self._parsefunction(indent) diff --git a/runtime/autoload/rubycomplete.vim b/runtime/autoload/rubycomplete.vim index 9cde21494..5b728607c 100644 --- a/runtime/autoload/rubycomplete.vim +++ b/runtime/autoload/rubycomplete.vim @@ -5,6 +5,7 @@ " URL: http://vim-ruby.rubyforge.org " Anon CVS: See above site " Release Coordinator: Doug Kearns <dougkearns@gmail.com> +" Maintainer Version: 0.8 " ---------------------------------------------------------------------------- " " Ruby IRB/Complete author: Keiju ISHITSUKA(keiju@ishitsuka.com) @@ -12,20 +13,20 @@ " {{{ requirement checks if !has('ruby') - echohl ErrorMsg - echo "Error: Required vim compiled with +ruby" - echohl None + s:ErrMsg( "Error: Rubycomplete requires vim compiled with +ruby" ) + s:ErrMsg( "Error: falling back to syntax completion" ) + " lets fall back to syntax completion + setlocal omnifunc=syntaxcomplete#Complete finish endif if version < 700 - echohl ErrorMsg - echo "Error: Required vim >= 7.0" - echohl None + s:ErrMsg( "Error: Required vim >= 7.0" ) finish endif " }}} requirement checks +" {{{ configuration failsafe initialization if !exists("g:rubycomplete_rails") let g:rubycomplete_rails = 0 endif @@ -34,76 +35,131 @@ if !exists("g:rubycomplete_classes_in_global") let g:rubycomplete_classes_in_global = 0 endif +if !exists("g:rubycomplete_buffer_loading") + let g:rubycomplete_classes_in_global = 0 +endif + +if !exists("g:rubycomplete_include_object") + let g:rubycomplete_include_object = 0 +endif + +if !exists("g:rubycomplete_include_objectspace") + let g:rubycomplete_include_objectspace = 0 +endif +" }}} configuration failsafe initialization + " {{{ vim-side support functions -function! GetBufferRubyModule(name) - let [snum,enum] = GetBufferRubyEntity(a:name, "module") +let s:rubycomplete_debug = 0 + +function! s:ErrMsg(msg) + echohl ErrorMsg + echo a:msg + echohl None +endfunction + +function! s:dprint(msg) + if s:rubycomplete_debug == 1 + echom a:msg + endif +endfunction + +function! s:GetBufferRubyModule(name, ...) + if a:0 == 1 + let [snum,enum] = s:GetBufferRubyEntity(a:name, "module", a:1) + else + let [snum,enum] = s:GetBufferRubyEntity(a:name, "module") + endif return snum . '..' . enum endfunction -function! GetBufferRubyClass(name) - let [snum,enum] = GetBufferRubyEntity(a:name, "class") +function! s:GetBufferRubyClass(name, ...) + if a:0 >= 1 + let [snum,enum] = s:GetBufferRubyEntity(a:name, "class", a:1) + else + let [snum,enum] = s:GetBufferRubyEntity(a:name, "class") + endif return snum . '..' . enum endfunction -function! GetBufferRubySingletonMethods(name) +function! s:GetBufferRubySingletonMethods(name) endfunction -function! GetBufferRubyEntity( name, type ) +function! s:GetBufferRubyEntity( name, type, ... ) + let lastpos = getpos(".") + let lastline = lastpos + if (a:0 >= 1) + let lastline = [ 0, a:1, 0, 0 ] + call cursor( a:1, 0 ) + endif + let stopline = 1 - let crex = '^\s*' . a:type . '\s*' . a:name . '\s*\(<\s*.*\s*\)\?\n*\(\(\s\|#\).*\n*\)*\n*\s*end$' - let [lnum,lcol] = searchpos( crex, 'nbw') + + let crex = '^\s*\<' . a:type . '\>\s*\<' . a:name . '\>\s*\(<\s*.*\s*\)\?' + let [lnum,lcol] = searchpos( crex, 'w' ) + "let [lnum,lcol] = searchpairpos( crex . '\zs', '', '\(end\|}\)', 'w' ) + if lnum == 0 && lcol == 0 + call cursor(lastpos[1], lastpos[2]) return [0,0] endif - let [enum,ecol] = searchpos( crex, 'nebw') + let curpos = getpos(".") + let [enum,ecol] = searchpairpos( crex, '', '\(end\|}\)', 'wr' ) + call cursor(lastpos[1], lastpos[2]) + if lnum > enum - let realdef = getline( lnum ) - let crexb = '^' . realdef . '\n*\(\(\s\|#\).*\n*\)*\n*\s*end$' - let [enum,ecol] = searchpos( crexb, 'necw' ) + return [0,0] endif " we found a the class def return [lnum,enum] endfunction -function! IsInClassDef() - let [snum,enum] = GetBufferRubyEntity( '.*', "class" ) +function! s:IsInClassDef() + return s:IsPosInClassDef( line('.') ) +endfunction + +function! s:IsPosInClassDef(pos) + let [snum,enum] = s:GetBufferRubyEntity( '.*', "class" ) let ret = 'nil' - let pos = line('.') - if snum < pos && pos < enum + if snum < a:pos && a:pos < enum let ret = snum . '..' . enum endif return ret endfunction -function! GetRubyVarType(v) +function! s:GetRubyVarType(v) let stopline = 1 let vtp = '' let pos = getpos('.') - let [lnum,lcol] = searchpos('^\s*#\s*@var\s*'.a:v.'\>\s\+[^ \t]\+\s*$','nb',stopline) + let sstr = '^\s*#\s*@var\s*'.a:v.'\>\s\+[^ \t]\+\s*$' + let [lnum,lcol] = searchpos(sstr,'nb',stopline) if lnum != 0 && lcol != 0 call setpos('.',pos) let str = getline(lnum) - let vtp = substitute(str,'^\s*#\s*@var\s*'.a:v.'\>\s\+\([^ \t]\+\)\s*$','\1','') + let vtp = substitute(str,sstr,'\1','') return vtp endif call setpos('.',pos) - if g:rubycomplete_rails == 1 && g:rubycomplete_rails_loaded == 1 - let ctors = '\(now\|new\|open\|get_instance\|find\|create\)' + let ctors = '\(now\|new\|open\|get_instance' + if exists('g:rubycomplete_rails') && g:rubycomplete_rails == 1 && s:rubycomplete_rails_loaded == 1 + let ctors = ctors.'\|find\|create' else - let ctors = '\(now\|new\|open\|get_instance\)' endif + let ctors = ctors.'\)' - let [lnum,lcol] = searchpos(''.a:v.'\>\s*[+\-*/]*=\s*\([^ \t]\+.' . ctors .'\>\|[\[{"''/]\|%r{\|[A-Za-z0-9@:\-()]\+...\?\)','nb',stopline) + let fstr = '=\s*\([^ \t]\+.' . ctors .'\>\|[\[{"''/]\|%[xwQqr][(\[{@]\|[A-Za-z0-9@:\-()\.]\+...\?\|lambda\|&\)' + let sstr = ''.a:v.'\>\s*[+\-*/]*'.fstr + let [lnum,lcol] = searchpos(sstr,'nb',stopline) if lnum != 0 && lcol != 0 - let str = matchstr(getline(lnum),'=\s*\([^ \t]\+.' . ctors . '\>\|[\[{"''/]\|%r{\|[A-Za-z0-9@:\-()]\+...\?\)',lcol) + let str = matchstr(getline(lnum),fstr,lcol) let str = substitute(str,'^=\s*','','') + call setpos('.',pos) - if str == '"' || str == '''' + if str == '"' || str == '''' || stridx(tolower(str), '%q[') != -1 return 'String' - elseif str == '[' + elseif str == '[' || stridx(str, '%w[') != -1 return 'Array' elseif str == '{' return 'Hash' @@ -111,6 +167,8 @@ function! GetRubyVarType(v) return 'Regexp' elseif strlen(str) >= 4 && stridx(str,'..') != -1 return 'Range' + elseif stridx(str, 'lambda') != -1 || str == '&' + return 'Proc' elseif strlen(str) > 4 let l = stridx(str,'.') return str[0:l-1] @@ -123,6 +181,11 @@ endfunction "}}} vim-side support functions +"{{{ vim-side completion function +function! rubycomplete#Init() + execute "ruby VimRubyCompletion.preload_rails" +endfunction + function! rubycomplete#Complete(findstart, base) "findstart = 1 when we need to get the text length if a:findstart @@ -145,346 +208,595 @@ function! rubycomplete#Complete(findstart, base) "findstart = 0 when we need to return the list of completions else let g:rubycomplete_completions = [] - execute "ruby get_completions('" . a:base . "')" + execute "ruby VimRubyCompletion.get_completions('" . a:base . "')" return g:rubycomplete_completions endif endfunction +"}}} vim-side completion function - +"{{{ ruby-side code function! s:DefRuby() ruby << RUBYEOF # {{{ ruby completion -RailsWords = [ - "has_many", "has_one", - "belongs_to", - ] - -ReservedWords = [ - "BEGIN", "END", - "alias", "and", - "begin", "break", - "case", "class", - "def", "defined", "do", - "else", "elsif", "end", "ensure", - "false", "for", - "if", "in", - "module", - "next", "nil", "not", - "or", - "redo", "rescue", "retry", "return", - "self", "super", - "then", "true", - "undef", "unless", "until", - "when", "while", - "yield", - ] - -Operators = [ "%", "&", "*", "**", "+", "-", "/", - "<", "<<", "<=", "<=>", "==", "===", "=~", ">", ">=", ">>", - "[]", "[]=", "^", ] - - -def load_requires - buf = VIM::Buffer.current - enum = buf.line_number - nums = Range.new( 1, enum ) - nums.each do |x| - ln = buf[x] + +begin + require 'rubygems' # let's assume this is safe...? +rescue Exception + #ignore? +end +class VimRubyCompletion +# {{{ constants + @@debug = false + @@ReservedWords = [ + "BEGIN", "END", + "alias", "and", + "begin", "break", + "case", "class", + "def", "defined", "do", + "else", "elsif", "end", "ensure", + "false", "for", + "if", "in", + "module", + "next", "nil", "not", + "or", + "redo", "rescue", "retry", "return", + "self", "super", + "then", "true", + "undef", "unless", "until", + "when", "while", + "yield", + ] + + @@Operators = [ "%", "&", "*", "**", "+", "-", "/", + "<", "<<", "<=", "<=>", "==", "===", "=~", ">", ">=", ">>", + "[]", "[]=", "^", ] +# }}} constants + +# {{{ buffer analysis magic + def load_requires + buf = VIM::Buffer.current + enum = buf.line_number + nums = Range.new( 1, enum ) + nums.each do |x| + ln = buf[x] + begin + eval( "require %s" % $1 ) if /.*require\s*(.*)$/.match( ln ) + rescue Exception + #ignore? + end + end + end + + def load_buffer_class(name) + dprint "load_buffer_class(%s) START" % name + classdef = get_buffer_entity(name, 's:GetBufferRubyClass("%s")') + return if classdef == nil + + pare = /^\s*class\s*(.*)\s*<\s*(.*)\s*\n/.match( classdef ) + load_buffer_class( $2 ) if pare != nil && $2 != name # load parent class if needed + + mixre = /.*\n\s*include\s*(.*)\s*\n/.match( classdef ) + load_buffer_module( $2 ) if mixre != nil && $2 != name # load mixins if needed + begin - eval( "require %s" % $1 ) if /.*require\s*(.*)$/.match( ln ) + eval classdef rescue Exception - #ignore? + VIM::evaluate( "s:ErrMsg( 'Problem loading class \"%s\", was it already completed?' )" % name ) end + dprint "load_buffer_class(%s) END" % name end -end -def load_buffer_class(name) - classdef = get_buffer_entity(name, 'GetBufferRubyClass("%s")') - return if classdef == nil + def load_buffer_module(name) + dprint "load_buffer_module(%s) START" % name + classdef = get_buffer_entity(name, 's:GetBufferRubyModule("%s")') + return if classdef == nil - pare = /^\s*class\s*(.*)\s*<\s*(.*)\s*\n/.match( classdef ) - load_buffer_class( $2 ) if pare != nil + begin + eval classdef + rescue Exception + VIM::evaluate( "s:ErrMsg( 'Problem loading module \"%s\", was it already completed?' )" % name ) + end + dprint "load_buffer_module(%s) END" % name + end + + def get_buffer_entity(name, vimfun) + loading_allowed = VIM::evaluate("exists('g:rubycomplete_buffer_loading') && g:rubycomplete_buffer_loading") + return nil if loading_allowed != '1' + return nil if /(\"|\')+/.match( name ) + buf = VIM::Buffer.current + nums = eval( VIM::evaluate( vimfun % name ) ) + return nil if nums == nil + return nil if nums.min == nums.max && nums.min == 0 + + dprint "get_buffer_entity START" + visited = [] + clscnt = 0 + bufname = VIM::Buffer.current.name + classdef = "" + cur_line = VIM::Buffer.current.line_number + while (nums != nil && !(nums.min == 0 && nums.max == 0) ) + dprint "visited: %s" % visited.to_s + break if visited.index( nums ) + visited << nums + + nums.each do |x| + if x != cur_line + next if x == 0 + ln = buf[x] + if /^\s*(module|class|def|include)\s+/.match(ln) + clscnt += 1 if $1 == "class" + #dprint "\$1: %s" % $1 + classdef += "%s\n" % ln + classdef += "end\n" if /def\s+/.match(ln) + dprint ln + end + end + end - mixre = /.*\n\s*include\s*(.*)\s*\n/.match( classdef ) - load_buffer_module( $2 ) if mixre != nil + nm = "%s(::.*)*\", %s, \"" % [ name, nums.last ] + nums = eval( VIM::evaluate( vimfun % nm ) ) + dprint "nm: \"%s\"" % nm + dprint "vimfun: %s" % (vimfun % nm) + dprint "got nums: %s" % nums.to_s + end + if classdef.length > 1 + classdef += "end\n"*clscnt + # classdef = "class %s\n%s\nend\n" % [ bufname.gsub( /\/|\\/, "_" ), classdef ] + end - eval classdef -end + dprint "get_buffer_entity END" + dprint "classdef====start" + lns = classdef.split( "\n" ) + lns.each { |x| dprint x } + dprint "classdef====end" + return classdef + end -def load_buffer_module(name) - classdef = get_buffer_entity(name, 'GetBufferRubyModule("%s")') - return if classdef == nil + def get_var_type( receiver ) + if /(\"|\')+/.match( receiver ) + "String" + else + VIM::evaluate("s:GetRubyVarType('%s')" % receiver) + end + end - eval classdef -end + def dprint( txt ) + print txt if @@debug + end -def get_buffer_entity(name, vimfun) - return nil if /(\"|\')+/.match( name ) - buf = VIM::Buffer.current - nums = eval( VIM::evaluate( vimfun % name ) ) - return nil if nums == nil - return nil if nums.min == nums.max && nums.min == 0 - - cur_line = VIM::Buffer.current.line_number - classdef = "" - nums.each do |x| - if x != cur_line - ln = buf[x] - classdef += "%s\n" % ln + def get_buffer_entity_list( type ) + # this will be a little expensive. + loading_allowed = VIM::evaluate("exists('g:rubycomplete_buffer_loading') && g:rubycomplete_buffer_loading") + allow_aggressive_load = VIM::evaluate("exists('g:rubycomplete_classes_in_global') && g:rubycomplete_classes_in_global") + return [] if allow_aggressive_load != '1' || loading_allowed != '1' + + buf = VIM::Buffer.current + eob = buf.length + ret = [] + rg = 1..eob + re = eval( "/^\s*%s\s*([A-Za-z0-9_:-]*)(\s*<\s*([A-Za-z0-9_:-]*))?\s*/" % type ) + + rg.each do |x| + if re.match( buf[x] ) + next if type == "def" && eval( VIM::evaluate("s:IsPosInClassDef(%s)" % x) ) != nil + ret.push $1 + end end + + return ret end - return classdef -end + def get_buffer_modules + return get_buffer_entity_list( "modules" ) + end -def get_var_type( receiver ) - if /(\"|\')+/.match( receiver ) - "String" - else - VIM::evaluate("GetRubyVarType('%s')" % receiver) + def get_buffer_methods + return get_buffer_entity_list( "def" ) end -end -def get_buffer_classes() - # this will be a little expensive. - allow_aggressive_load = VIM::evaluate('g:rubycomplete_classes_in_global') - return [] if allow_aggressive_load != '1' + def get_buffer_classes + return get_buffer_entity_list( "class" ) + end + + + def load_rails + allow_rails = VIM::evaluate("exists('g:rubycomplete_rails') && g:rubycomplete_rails") + return if allow_rails != '1' + + buf_path = VIM::evaluate('expand("%:p")') + file_name = VIM::evaluate('expand("%:t")') + vim_dir = VIM::evaluate('getcwd()') + file_dir = buf_path.gsub( file_name, '' ) + file_dir.gsub!( /\\/, "/" ) + vim_dir.gsub!( /\\/, "/" ) + vim_dir << "/" + dirs = [ vim_dir, file_dir ] + sdirs = [ "", "./", "../", "../../", "../../../", "../../../../" ] + rails_base = nil + + dirs.each do |dir| + sdirs.each do |sub| + trail = "%s%s" % [ dir, sub ] + tcfg = "%sconfig" % trail + + if File.exists?( tcfg ) + rails_base = trail + break + end + end + break if rails_base + end - buf = VIM::Buffer.current - eob = buf.length - ret = [] - rg = 1..eob + return if rails_base == nil + $:.push rails_base unless $:.index( rails_base ) - rg.each do |x| - if /^\s*class\s*([A-Za-z0-9_-]*)(\s*<\s*([A-Za-z0-9_:-]*))?\s*/.match( buf[x] ) - ret.push $1 + rails_config = rails_base + "config/" + rails_lib = rails_base + "lib/" + $:.push rails_config unless $:.index( rails_config ) + $:.push rails_lib unless $:.index( rails_lib ) + + bootfile = rails_config + "boot.rb" + envfile = rails_config + "environment.rb" + if File.exists?( bootfile ) && File.exists?( envfile ) + begin + require bootfile + require envfile + begin + require 'console_app' + require 'console_with_helpers' + rescue Exception + dprint "Rails 1.1+ Error %s" % $! + # assume 1.0 + end + #eval( "Rails::Initializer.run" ) #not necessary? + VIM::command('let s:rubycomplete_rails_loaded = 1') + dprint "rails loaded" + rescue Exception + dprint "Rails Error %s" % $! + VIM::evaluate( "s:ErrMsg('Error loading rails environment')" ) + end end end - return ret -end + def get_rails_helpers + allow_rails = VIM::evaluate("exists('g:rubycomplete_rails') && g:rubycomplete_rails") + rails_loaded = VIM::evaluate('s:rubycomplete_rails_loaded') + return [] if allow_rails != '1' || rails_loaded != '1' + + buf_path = VIM::evaluate('expand("%:p")') + buf_path.gsub!( /\\/, "/" ) + path_elm = buf_path.split( "/" ) + dprint "buf_path: %s" % buf_path + types = [ "app", "db", "lib", "test", "components", "script" ] + + i = nil + ret = [] + type = nil + types.each do |t| + i = path_elm.index( t ) + break if i + end + type = path_elm[i] + type.downcase! + + dprint "type: %s" % type + case type + when "app" + i += 1 + subtype = path_elm[i] + subtype.downcase! + + dprint "subtype: %s" % subtype + case subtype + when "views" + ret += ActionView::Base.instance_methods + ret += ActionView::Base.methods + when "controllers" + ret += ActionController::Base.instance_methods + ret += ActionController::Base.methods + when "models" + ret += ActiveRecord::Base.instance_methods + ret += ActiveRecord::Base.methods + end -def load_rails() - allow_rails = VIM::evaluate('g:rubycomplete_rails') - return if allow_rails != '1' - - buf_path = VIM::evaluate('expand("%:p")') - file_name = VIM::evaluate('expand("%:t")') - path = buf_path.gsub( file_name, '' ) - path.gsub!( /\\/, "/" ) - pup = [ "./", "../", "../../", "../../../", "../../../../" ] - pok = nil - - pup.each do |sup| - tpok = "%s%sconfig" % [ path, sup ] - if File.exists?( tpok ) - pok = tpok - break + when "db" + ret += ActiveRecord::ConnectionAdapters::SchemaStatements.instance_methods + ret += ActiveRecord::ConnectionAdapters::SchemaStatements.methods end + + + return ret end - return if pok == nil + def add_rails_columns( cls ) + allow_rails = VIM::evaluate("exists('g:rubycomplete_rails') && g:rubycomplete_rails") + rails_loaded = VIM::evaluate('s:rubycomplete_rails_loaded') + return [] if allow_rails != '1' || rails_loaded != '1' - bootfile = pok + "/boot.rb" - envfile = pok + "/environment.rb" - if File.exists?( bootfile ) && File.exists?( envfile ) begin - require bootfile - require envfile - require 'console_app' - require 'console_with_helpers' - VIM::command('let g:rubycomplete_rails_loaded = 1') + eval( "#{cls}.establish_connection" ) + return [] unless eval( "#{cls}.ancestors.include?(ActiveRecord::Base).to_s" ) + col = eval( "#{cls}.column_names" ) + return col if col rescue - print "Error loading rails environment" + dprint "add_rails_columns err: (cls: %s) %s" % [ cls, $! ] + return [] end + return [] end -end -def get_rails_helpers - allow_rails = VIM::evaluate('g:rubycomplete_rails') - rails_loaded = VIM::evaluate('g:rubycomplete_rails_loaded') - return [] if allow_rails != '1' || rails_loaded != '1' - return RailsWords -end + def clean_sel(sel, msg) + sel.delete_if { |x| x == nil } + sel.uniq! + sel.grep(/^#{Regexp.quote(msg)}/) if msg != nil + end -def get_completions(base) - load_requires - load_rails + def get_rails_view_methods + allow_rails = VIM::evaluate("exists('g:rubycomplete_rails') && g:rubycomplete_rails") + rails_loaded = VIM::evaluate('s:rubycomplete_rails_loaded') + return [] if allow_rails != '1' || rails_loaded != '1' - input = VIM::Buffer.current.line - cpos = VIM::Window.current.cursor[1] - 1 - input = input[0..cpos] if cpos != 0 - input += base + buf_path = VIM::evaluate('expand("%:p")') + buf_path.gsub!( /\\/, "/" ) + pelm = buf_path.split( "/" ) + idx = pelm.index( "views" ) - rip = input.rindex(/\s/,cpos) - if rip - input = input[rip..input.length] - end + return [] unless idx + idx += 1 - asn = /^.*(\+|\-|\*|=|\(|\[)=?(\s*[A-Za-z0-9_:@.-]*)(\s*(\{|\+|\-|\*|\%|\/)?\s*).*/ - if asn.match(input) - input = $2 - end + clspl = pelm[idx].camelize.pluralize + cls = clspl.singularize - input.strip! - message = nil - receiver = nil - candidates = [] - - case input - when /^(\/[^\/]*\/)\.([^.]*)$/ # Regexp - receiver = $1 - message = Regexp.quote($2) - candidates = Regexp.instance_methods(true) - - when /^([^\]]*\])\.([^.]*)$/ # Array - receiver = $1 - message = Regexp.quote($2) - candidates = Array.instance_methods(true) - - when /^([^\}]*\})\.([^.]*)$/ # Proc or Hash - receiver = $1 - message = Regexp.quote($2) - candidates = Proc.instance_methods(true) | Hash.instance_methods(true) - - when /^(:[^:.]*)$/ # Symbol - if Symbol.respond_to?(:all_symbols) - receiver = $1 - candidates = Symbol.all_symbols.collect{|s| s.id2name} - candidates.delete_if { |c| c.match( /'/ ) } - end + ret = [] + begin + ret += eval( "#{cls}.instance_methods" ) + ret += eval( "#{clspl}Helper.instance_methods" ) + rescue Exception + dprint "Error: Unable to load rails view helpers for %s: %s" % [ cls, $! ] + end - when /^::([A-Z][^:\.\(]*)$/ # Absolute Constant or class methods - receiver = $1 - candidates = Object.constants - candidates.grep(/^#{receiver}/).collect{|e| "::" + e} + return ret + end +# }}} buffer analysis magic - when /^(((::)?[A-Z][^:.\(]*)+)::?([^:.]*)$/ # Constant or class methods - receiver = $1 - message = Regexp.quote($4) +# {{{ main completion code + def self.preload_rails + a = VimRubyCompletion.new + require 'Thread' + Thread.new(a) do |b| begin - candidates = eval("#{receiver}.constants | #{receiver}.methods") - rescue Exception - candidates = [] + b.load_rails + rescue end - candidates.grep(/^#{message}/).collect{|e| receiver + "::" + e} + end + a.load_rails + rescue + end - when /^(:[^:.]+)\.([^.]*)$/ # Symbol - receiver = $1 - message = Regexp.quote($2) - candidates = Symbol.instance_methods(true) + def self.get_completions(base) + b = VimRubyCompletion.new + b.get_completions base + end - when /^([0-9_]+(\.[0-9_]+)?(e[0-9]+)?)\.([^.]*)$/ # Numeric - receiver = $1 - message = Regexp.quote($4) - begin - candidates = eval(receiver).methods - rescue Exception - candidates - end + def get_completions(base) + loading_allowed = VIM::evaluate("exists('g:rubycomplete_buffer_loading') && g:rubycomplete_buffer_loading") + if loading_allowed == '1' + load_requires + load_rails + end - when /^(\$[^.]*)$/ #global - candidates = global_variables.grep(Regexp.new(Regexp.quote($1))) + input = VIM::Buffer.current.line + cpos = VIM::Window.current.cursor[1] - 1 + input = input[0..cpos] + input += base + input.sub!(/.*[ \t\n\"\\'`><=;|&{(]/, '') # Readline.basic_word_break_characters + input.sub!(/self\./, '') + input.sub!(/.*((\.\.[\[(]?)|([\[(]))/, '') + + dprint 'input %s' % input + message = nil + receiver = nil + methods = [] + variables = [] + classes = [] + constants = [] + + case input + when /^(\/[^\/]*\/)\.([^.]*)$/ # Regexp + receiver = $1 + message = Regexp.quote($2) + methods = Regexp.instance_methods(true) - when /^((\.?[^.]+)+)\.([^.]*)$/ # variable - receiver = $1 - message = Regexp.quote($3) - load_buffer_class( receiver ) + when /^([^\]]*\])\.([^.]*)$/ # Array + receiver = $1 + message = Regexp.quote($2) + methods = Array.instance_methods(true) - cv = eval("self.class.constants") - vartype = get_var_type( receiver ) - if vartype != '' - load_buffer_class( vartype ) + when /^([^\}]*\})\.([^.]*)$/ # Proc or Hash + receiver = $1 + message = Regexp.quote($2) + methods = Proc.instance_methods(true) | Hash.instance_methods(true) + + when /^(:[^:.]*)$/ # Symbol + dprint "symbol" + if Symbol.respond_to?(:all_symbols) + receiver = $1 + message = $1.sub( /:/, '' ) + methods = Symbol.all_symbols.collect{|s| s.id2name} + methods.delete_if { |c| c.match( /'/ ) } + end + + when /^::([A-Z][^:\.\(]*)$/ # Absolute Constant or class methods + dprint "const or cls" + receiver = $1 + methods = Object.constants + methods.grep(/^#{receiver}/).collect{|e| "::" + e} + when /^(((::)?[A-Z][^:.\(]*)+)::?([^:.]*)$/ # Constant or class methods + receiver = $1 + message = Regexp.quote($4) + dprint "const or cls 2 [recv: \'%s\', msg: \'%s\']" % [ receiver, message ] + load_buffer_class( receiver ) begin - candidates = eval("#{vartype}.instance_methods") + classes = eval("#{receiver}.constants") + #methods = eval("#{receiver}.methods") rescue Exception - candidates = [] + dprint "exception: %s" % $! + methods = [] end - elsif (cv).include?(receiver) - # foo.func and foo is local var. - candidates = eval("#{receiver}.methods") - elsif /^[A-Z]/ =~ receiver and /\./ !~ receiver - # Foo::Bar.func + methods.grep(/^#{message}/).collect{|e| receiver + "::" + e} + + when /^(:[^:.]+)\.([^.]*)$/ # Symbol + dprint "symbol" + receiver = $1 + message = Regexp.quote($2) + methods = Symbol.instance_methods(true) + + when /^([0-9_]+(\.[0-9_]+)?(e[0-9]+)?)\.([^.]*)$/ # Numeric + dprint "numeric" + receiver = $1 + message = Regexp.quote($4) begin - candidates = eval("#{receiver}.methods") + methods = eval(receiver).methods rescue Exception - candidates = [] + methods = [] end - else - # func1.func2 - candidates = [] - ObjectSpace.each_object(Module){|m| - next if m.name != "IRB::Context" and - /^(IRB|SLex|RubyLex|RubyToken)/ =~ m.name - candidates.concat m.instance_methods(false) - } - end - when /^\(?\s*[A-Za-z0-9:^@.%\/+*\(\)]+\.\.\.?[A-Za-z0-9:^@.%\/+*\(\)]+\s*\)?\.([^.]*)/ - message = $1 - candidates = Range.instance_methods(true) + when /^(\$[^.]*)$/ #global + dprint "global" + methods = global_variables.grep(Regexp.new(Regexp.quote($1))) - when /^\[(\s*[A-Za-z0-9:^@.%\/+*\(\)\[\]\{\}.\'\"],?)*\].([^.]*)/ - message = $2 - candidates = Array.instance_methods(true) + when /^((\.?[^.]+)+)\.([^.]*)$/ # variable + dprint "variable" + receiver = $1 + message = Regexp.quote($3) + load_buffer_class( receiver ) - when /^\.([^.]*)$/ # unknown(maybe String) - message = Regexp.quote($1) - candidates = String.instance_methods(true) + cv = eval("self.class.constants") + vartype = get_var_type( receiver ) + dprint "vartype: %s" % vartype + if vartype != '' + load_buffer_class( vartype ) + + begin + methods = eval("#{vartype}.instance_methods") + variables = eval("#{vartype}.instance_variables") + rescue Exception + dprint "load_buffer_class err: %s" % $! + end + elsif (cv).include?(receiver) + # foo.func and foo is local var. + methods = eval("#{receiver}.methods") + vartype = receiver + elsif /^[A-Z]/ =~ receiver and /\./ !~ receiver + vartype = receiver + # Foo::Bar.func + begin + methods = eval("#{receiver}.methods") + rescue Exception + end + else + # func1.func2 + ObjectSpace.each_object(Module){|m| + next if m.name != "IRB::Context" and + /^(IRB|SLex|RubyLex|RubyToken)/ =~ m.name + methods.concat m.instance_methods(false) + } + end + variables += add_rails_columns( "#{vartype}" ) if vartype && vartype.length > 0 - else - inclass = eval( VIM::evaluate("IsInClassDef()") ) + when /^\(?\s*[A-Za-z0-9:^@.%\/+*\(\)]+\.\.\.?[A-Za-z0-9:^@.%\/+*\(\)]+\s*\)?\.([^.]*)/ + message = $1 + methods = Range.instance_methods(true) - if inclass != nil - classdef = "%s\n" % VIM::Buffer.current[ inclass.min ] - found = /^\s*class\s*([A-Za-z0-9_-]*)(\s*<\s*([A-Za-z0-9_:-]*))?\s*\n$/.match( classdef ) + when /^\.([^.]*)$/ # unknown(maybe String) + message = Regexp.quote($1) + methods = String.instance_methods(true) - if found != nil - receiver = $1 - message = input - load_buffer_class( receiver ) - begin - candidates = eval( "#{receiver}.instance_methods" ) - candidates += get_rails_helpers - rescue Exception - found = nil + else + dprint "default/other" + inclass = eval( VIM::evaluate("s:IsInClassDef()") ) + + if inclass != nil + dprint "inclass" + classdef = "%s\n" % VIM::Buffer.current[ inclass.min ] + found = /^\s*class\s*([A-Za-z0-9_-]*)(\s*<\s*([A-Za-z0-9_:-]*))?\s*\n$/.match( classdef ) + + if found != nil + receiver = $1 + message = input + load_buffer_class( receiver ) + begin + methods = eval( "#{receiver}.instance_methods" ) + variables += add_rails_columns( "#{receiver}" ) + rescue Exception + found = nil + end end end - end - if inclass == nil || found == nil - candidates = eval("self.class.constants") - candidates += get_buffer_classes - message = receiver = input + if inclass == nil || found == nil + dprint "inclass == nil" + methods = get_buffer_methods + methods += get_rails_view_methods + + cls_const = Class.constants + constants = cls_const.select { |c| /^[A-Z_-]+$/.match( c ) } + classes = eval("self.class.constants") - constants + classes += get_buffer_classes + classes += get_buffer_modules + + include_objectspace = VIM::evaluate("exists('g:rubycomplete_include_objectspace') && g:rubycomplete_include_objectspace") + ObjectSpace.each_object(Class) { |cls| classes << cls.to_s } if include_objectspace == "1" + message = receiver = input + end + + methods += get_rails_helpers + methods += Kernel.public_methods end - end - candidates.delete_if { |x| x == nil } - candidates.uniq! - candidates.sort! - candidates = candidates.grep(/^#{Regexp.quote(message)}/) if message != nil - outp = "" - valid = (candidates-Object.instance_methods) + include_object = VIM::evaluate("exists('g:rubycomplete_include_object') && g:rubycomplete_include_object") + methods = clean_sel( methods, message ) + methods = (methods-Object.instance_methods) if include_object == "0" + rbcmeth = (VimRubyCompletion.instance_methods-Object.instance_methods) # lets remove those rubycomplete methods + methods = (methods-rbcmeth) + + variables = clean_sel( variables, message ) + classes = clean_sel( classes, message ) - ["VimRubyCompletion"] + constants = clean_sel( constants, message ) - rg = 0..valid.length - rg.step(150) do |x| - stpos = 0+x - enpos = 150+x - valid[stpos..enpos].each { |c| outp += "{'word':'%s','item':'%s'}," % [ c, c ] } - outp.sub!(/,$/, '') + valid = [] + valid += methods.collect { |m| { :name => m, :type => 'm' } } + valid += variables.collect { |v| { :name => v, :type => 'v' } } + valid += classes.collect { |c| { :name => c, :type => 't' } } + valid += constants.collect { |d| { :name => d, :type => 'd' } } + valid.sort! { |x,y| x[:name] <=> y[:name] } - VIM::command("call extend(g:rubycomplete_completions, [%s])" % outp) outp = "" + + rg = 0..valid.length + rg.step(150) do |x| + stpos = 0+x + enpos = 150+x + valid[stpos..enpos].each { |c| outp += "{'word':'%s','item':'%s','kind':'%s'}," % [ c[:name], c[:name], c[:type] ] } + outp.sub!(/,$/, '') + + VIM::command("call extend(g:rubycomplete_completions, [%s])" % outp) + outp = "" + end end -end +# }}} main completion code +end # VimRubyCompletion # }}} ruby completion RUBYEOF endfunction -let g:rubycomplete_rails_loaded = 0 +let s:rubycomplete_rails_loaded = 0 call s:DefRuby() -" vim:tw=78:sw=4:ts=8:et:ft=vim:norl: +"}}} ruby-side code + + +" vim:tw=78:sw=4:ts=8:et:fdm=marker:ft=vim:norl: diff --git a/runtime/autoload/syntaxcomplete.vim b/runtime/autoload/syntaxcomplete.vim index 5e0d013c6..36bd9f426 100644 --- a/runtime/autoload/syntaxcomplete.vim +++ b/runtime/autoload/syntaxcomplete.vim @@ -1,8 +1,8 @@ " Vim completion script " Language: All languages, uses existing syntax highlighting rules " Maintainer: David Fishburn <fishburn@ianywhere.com> -" Version: 2.0 -" Last Change: Fri May 05 2006 10:34:57 PM +" Version: 3.0 +" Last Change: Wed Nov 08 2006 10:46:46 AM " Usage: For detailed help, ":help ft-syntax-omni" " Set completion with CTRL-X CTRL-O to autoloaded function. @@ -19,13 +19,31 @@ endif if exists('g:loaded_syntax_completion') finish endif -let g:loaded_syntax_completion = 20 +let g:loaded_syntax_completion = 30 " Set ignorecase to the ftplugin standard +" This is the default setting, but if you define a buffer local +" variable you can override this on a per filetype. if !exists('g:omni_syntax_ignorecase') let g:omni_syntax_ignorecase = &ignorecase endif +" Indicates whether we should use the iskeyword option to determine +" how to split words. +" This is the default setting, but if you define a buffer local +" variable you can override this on a per filetype. +if !exists('g:omni_syntax_use_iskeyword') + let g:omni_syntax_use_iskeyword = 1 +endif + +" Only display items in the completion window that are at least +" this many characters in length. +" This is the default setting, but if you define a buffer local +" variable you can override this on a per filetype. +if !exists('g:omni_syntax_minimum_length') + let g:omni_syntax_minimum_length = 0 +endif + " This script will build a completion list based on the syntax " elements defined by the files in $VIMRUNTIME/syntax. let s:syn_remove_words = 'match,matchgroup=,contains,'. @@ -38,21 +56,28 @@ let s:prepended = '' " This function is used for the 'omnifunc' option. function! syntaxcomplete#Complete(findstart, base) + " Only display items in the completion window that are at least + " this many characters in length + if !exists('b:omni_syntax_ignorecase') + if exists('g:omni_syntax_ignorecase') + let b:omni_syntax_ignorecase = g:omni_syntax_ignorecase + else + let b:omni_syntax_ignorecase = &ignorecase + endif + endif + if a:findstart " Locate the start of the item, including "." let line = getline('.') let start = col('.') - 1 let lastword = -1 while start > 0 - if line[start - 1] =~ '\w' + " if line[start - 1] =~ '\S' + " let start -= 1 + " elseif line[start - 1] =~ '\.' + if line[start - 1] =~ '\k' let start -= 1 - elseif line[start - 1] =~ '\.' - " The user must be specifying a column name - if lastword == -1 - let lastword = start - endif - let start -= 1 - let b:sql_compl_type = 'column' + let lastword = a:findstart else break endif @@ -64,11 +89,12 @@ function! syntaxcomplete#Complete(findstart, base) let s:prepended = '' return start endif - let s:prepended = strpart(line, start, lastword - start) - return lastword + let s:prepended = strpart(line, start, (col('.') - 1) - start) + return start endif - let base = s:prepended . a:base + " let base = s:prepended . a:base + let base = s:prepended let filetype = substitute(&filetype, '\.', '_', 'g') let list_idx = index(s:cache_name, filetype, 0, &ignorecase) @@ -82,11 +108,16 @@ function! syntaxcomplete#Complete(findstart, base) " Return list of matches. - if base =~ '\w' - let compstr = join(compl_list, ' ') - let expr = (g:omni_syntax_ignorecase==0?'\C':'').'\<\%('.base.'\)\@!\w\+\s*' - let compstr = substitute(compstr, expr, '', 'g') - let compl_list = split(compstr, '\s\+') + if base != '' + " let compstr = join(compl_list, ' ') + " let expr = (b:omni_syntax_ignorecase==0?'\C':'').'\<\%('.base.'\)\@!\w\+\s*' + " let compstr = substitute(compstr, expr, '', 'g') + " let compl_list = split(compstr, '\s\+') + + " Filter the list based on the first few characters the user + " entered + let expr = 'v:val '.(g:omni_syntax_ignorecase==1?'=~?':'=~#')." '^".escape(base, '\\/.*$^~[]').".*'" + let compl_list = filter(deepcopy(compl_list), expr) endif return compl_list @@ -100,6 +131,26 @@ function! OmniSyntaxList() " let use_dictionary = a:1 " endif + " Only display items in the completion window that are at least + " this many characters in length + if !exists('b:omni_syntax_use_iskeyword') + if exists('g:omni_syntax_use_iskeyword') + let b:omni_syntax_use_iskeyword = g:omni_syntax_use_iskeyword + else + let b:omni_syntax_use_iskeyword = 1 + endif + endif + + " Only display items in the completion window that are at least + " this many characters in length + if !exists('b:omni_syntax_minimum_length') + if exists('g:omni_syntax_minimum_length') + let b:omni_syntax_minimum_length = g:omni_syntax_minimum_length + else + let b:omni_syntax_minimum_length = 0 + endif + endif + let saveL = @l " Loop through all the syntax groupnames, and build a @@ -294,14 +345,32 @@ function! s:SyntaxCSyntaxGroupItems( group_name, syntax_full ) \ , "", 'g' \ ) - " There are a number of items which have non-word characters in - " them, *'T_F1'*. vim.vim is one such file. - " This will replace non-word characters with spaces. - let syn_list = substitute( syn_list, '[^0-9A-Za-z_ ]', ' ', 'g' ) + if b:omni_syntax_use_iskeyword == 0 + " There are a number of items which have non-word characters in + " them, *'T_F1'*. vim.vim is one such file. + " This will replace non-word characters with spaces. + let syn_list = substitute( syn_list, '[^0-9A-Za-z_ ]', ' ', 'g' ) + else + let accept_chars = ','.&iskeyword.',' + " Remove all character ranges + let accept_chars = substitute(accept_chars, ',[^,]\+-[^,]\+,', ',', 'g') + " Remove all numeric specifications + let accept_chars = substitute(accept_chars, ',\d\{-},', ',', 'g') + " Remove all commas + let accept_chars = substitute(accept_chars, ',', '', 'g') + " Escape special regex characters + let accept_chars = escape(accept_chars, '\\/.*$^~[]' ) + " Remove all characters that are not acceptable + let syn_list = substitute( syn_list, '[^0-9A-Za-z_ '.accept_chars.']', ' ', 'g' ) + endif + + if b:omni_syntax_minimum_length > 0 + " If the user specified a minimum length, enforce it + let syn_list = substitute(' '.syn_list.' ', ' \S\{,'.b:omni_syntax_minimum_length.'}\ze ', ' ', 'g') + endif else let syn_list = '' endif return syn_list endfunction - diff --git a/runtime/autoload/xmlcomplete.vim b/runtime/autoload/xmlcomplete.vim index 78d30582a..79d913d63 100644 --- a/runtime/autoload/xmlcomplete.vim +++ b/runtime/autoload/xmlcomplete.vim @@ -1,7 +1,12 @@ " Vim completion script " Language: XML " Maintainer: Mikolaj Machowski ( mikmach AT wp DOT pl ) -" Last Change: 2006 Apr 30 +" Last Change: 2006 Jul 18 +" Version: 1.8 +" +" Changelog: +" 1.8 - 2006 Jul 18 +" - allow for closing of xml tags even when data file isn't available " This function will create Dictionary with users namespace strings and values " canonical (system) names of data files. Names should be lowercase, @@ -80,7 +85,7 @@ function! xmlcomplete#CompleteTags(findstart, base) let context_line = getline(curline-i) if context_line =~ '<[^>]*$' " Yep, this is this line - let context_lines = getline(curline-i, curline) + let context_lines = getline(curline-i, curline-1) + [b:compl_context] let b:compl_context = join(context_lines, ' ') break elseif context_line =~ '>[^<]*$' || i == curline @@ -106,10 +111,6 @@ function! xmlcomplete#CompleteTags(findstart, base) return start else - " There is no connection of namespace and data file. Abandon action - if !exists("g:xmldata_connection") || g:xmldata_connection == {} - return [] - endif " Initialize base return lists let res = [] let res2 = [] @@ -119,6 +120,17 @@ function! xmlcomplete#CompleteTags(findstart, base) endif let context = matchstr(b:compl_context, '^<\zs.*') unlet! b:compl_context + " There is no connection of namespace and data file. + if !exists("g:xmldata_connection") || g:xmldata_connection == {} + " There is still possibility we may do something - eg. close tag + let b:unaryTagsStack = "base meta link hr br param img area input col" + if context =~ '^\/' + let opentag = xmlcomplete#GetLastOpenTag("b:unaryTagsStack") + return [opentag.">"] + else + return [] + endif + endif " Make entities completion if exists("b:entitiescompl") diff --git a/runtime/autoload/zip.vim b/runtime/autoload/zip.vim index e0ae9b8b7..2a15deeaf 100644 --- a/runtime/autoload/zip.vim +++ b/runtime/autoload/zip.vim @@ -1,9 +1,9 @@ " zip.vim: Handles browsing zipfiles " AUTOLOAD PORTION -" Date: May 01, 2006 -" Version: 9 -" Maintainer: Charles E Campbell, Jr <drchipNOSPAM at campbellfamily dot biz> -" License: Vim License (see vim's :help license) +" Date: Sep 29, 2006 +" Version: 12 +" Maintainer: Charles E Campbell, Jr <NdrOchip@ScampbellPfamily.AbizM-NOSPAM> +" License: Vim License (see vim's :help license) " Copyright: Copyright (C) 2005 Charles E. Campbell, Jr. {{{1 " Permission is hereby granted to use and distribute this code, " with or without modifications, provided that this copyright @@ -15,15 +15,28 @@ " of this software. " --------------------------------------------------------------------- -" Initialization: {{{1 +" Load Once: {{{1 let s:keepcpo= &cpo set cpo&vim -if exists("g:loaded_zip") +if &cp || exists("g:loaded_zip") || v:version < 700 finish endif -let g:loaded_zip = "v9" +let g:loaded_zip = "v12" let s:zipfile_escape = ' ?&;\' +let s:ERROR = 2 +let s:WARNING = 1 +let s:NOTE = 0 + +" --------------------------------------------------------------------- +" Global Values: {{{1 +if !exists("g:zip_shq") + if has("unix") + let g:zip_shq= "'" + else + let g:zip_shq= '"' + endif +endif " ---------------- " Functions: {{{1 @@ -38,8 +51,9 @@ fun! zip#Browse(zipfile) " sanity checks if !executable("unzip") + redraw! echohl Error | echo "***error*** (zip#Browse) unzip not available on your system" - call inputsave()|call input("Press <cr> to continue")|call inputrestore() +" call inputsave()|call input("Press <cr> to continue")|call inputrestore() let &report= repkeep " call Dret("zip#Browse") return @@ -47,8 +61,9 @@ fun! zip#Browse(zipfile) if !filereadable(a:zipfile) if a:zipfile !~# '^\a\+://' " if its an url, don't complain, let url-handlers such as vim do its thing + redraw! echohl Error | echo "***error*** (zip#Browse) File not readable<".a:zipfile.">" | echohl None - call inputsave()|call input("Press <cr> to continue")|call inputrestore() +" call inputsave()|call input("Press <cr> to continue")|call inputrestore() endif let &report= repkeep " call Dret("zip#Browse : file<".a:zipfile."> not readable") @@ -75,11 +90,12 @@ fun! zip#Browse(zipfile) 0d $ -" call Decho("exe silent r! unzip -l '".a:zipfile."'") - exe "silent r! unzip -l '".a:zipfile."'" +" call Decho("exe silent r! unzip -l ".s:QuoteFileDir(a:zipfile)) + exe "silent r! unzip -l ".s:QuoteFileDir(a:zipfile) if v:shell_error != 0 + redraw! echohl WarningMsg | echo "***warning*** (zip#Browse) ".a:zipfile." is not a zip file" | echohl None - call inputsave()|call input("Press <cr> to continue")|call inputrestore() +" call inputsave()|call input("Press <cr> to continue")|call inputrestore() silent %d let eikeep= &ei set ei=BufReadCmd,FileReadCmd @@ -121,8 +137,9 @@ fun! s:ZipBrowseSelect() return endif if fname =~ '/$' + redraw! echohl Error | echo "***error*** (zip#Browse) Please specify a file, not a directory" | echohl None - call inputsave()|call input("Press <cr> to continue")|call inputrestore() +" call inputsave()|call input("Press <cr> to continue")|call inputrestore() let &report= repkeep " call Dret("ZipBrowseSelect") return @@ -131,7 +148,7 @@ fun! s:ZipBrowseSelect() " call Decho("fname<".fname.">") " get zipfile to the new-window - let zipfile= substitute(w:zipfile,'.zip$','','e') + let zipfile = w:zipfile let curfile= expand("%") " call Decho("zipfile<".zipfile.">") " call Decho("curfile<".curfile.">") @@ -160,12 +177,15 @@ fun! zip#Read(fname,mode) else let zipfile = substitute(a:fname,'^.\{-}zipfile:\(.\{-}\)::[^\\].*$','\1','') let fname = substitute(a:fname,'^.\{-}zipfile:.\{-}::\([^\\].*\)$','\1','') + + " TODO Needs to predicated to using InfoZIP's unzip on Windows + let fname = substitute(fname, '[', '[[]', 'g') endif " call Decho("zipfile<".zipfile.">") " call Decho("fname <".fname.">") -" call Decho("exe r! unzip -p '".zipfile."' '".fname."'") - exe "silent r! unzip -p '".zipfile."' '".fname."'" +" call Decho("exe r! unzip -p ".s:QuoteFileDir(zipfile)." ".s:QuoteFileDir(fname)) + exe "silent r! unzip -p ".s:QuoteFileDir(zipfile)." ".s:QuoteFileDir(fname) " cleanup 0d @@ -184,15 +204,17 @@ fun! zip#Write(fname) " sanity checks if !executable("zip") + redraw! echohl Error | echo "***error*** (zip#Write) sorry, your system doesn't appear to have the zip pgm" | echohl None - call inputsave()|call input("Press <cr> to continue")|call inputrestore() +" call inputsave()|call input("Press <cr> to continue")|call inputrestore() let &report= repkeep " call Dret("zip#Write") return endif if !exists("*mkdir") + redraw! echohl Error | echo "***error*** (zip#Write) sorry, mkdir() doesn't work on your system" | echohl None - call inputsave()|call input("Press <cr> to continue")|call inputrestore() +" call inputsave()|call input("Press <cr> to continue")|call inputrestore() let &report= repkeep " call Dret("zip#Write") return @@ -208,15 +230,11 @@ fun! zip#Write(fname) call mkdir(tmpdir,"p") " attempt to change to the indicated directory - try - exe "cd ".escape(tmpdir,' \') - catch /^Vim\%((\a\+)\)\=:E344/ - echohl Error | echo "***error*** (zip#Write) cannot cd to temporary directory" | Echohl None - call inputsave()|call input("Press <cr> to continue")|call inputrestore() + if s:ChgDir(tmpdir,s:ERROR,"(zip#Write) cannot cd to temporary directory") let &report= repkeep " call Dret("zip#Write") return - endtry + endif " call Decho("current directory now: ".getcwd()) " place temporary files under .../_ZIPVIM_/ @@ -255,21 +273,27 @@ fun! zip#Write(fname) let zipfile = substitute(system("cygpath ".zipfile),'\n','','e') endif -" call Decho("zip -u '".zipfile.".zip' '".fname."'") - call system("zip -u '".zipfile.".zip' '".fname."'") + " TODO Needs to predicated to using InfoZIP's unzip + if (has("win32") || has("win95") || has("win64") || has("win16")) && &shell !~? 'sh$' + let fname = substitute(fname, '[', '[[]', 'g') + endif + +" call Decho("zip -u ".s:QuoteFileDir(zipfile)." ".s:QuoteFileDir(fname)) + call system("zip -u ".s:QuoteFileDir(zipfile)." ".s:QuoteFileDir(fname)) if v:shell_error != 0 + redraw! echohl Error | echo "***error*** (zip#Write) sorry, unable to update ".zipfile." with ".fname | echohl None - call inputsave()|call input("Press <cr> to continue")|call inputrestore() +" call inputsave()|call input("Press <cr> to continue")|call inputrestore() elseif s:zipfile_{winnr()} =~ '^\a\+://' " support writing zipfiles across a network let netzipfile= s:zipfile_{winnr()} -" call Decho("handle writing <".zipfile.".zip> across network as <".netzipfile.">") +" call Decho("handle writing <".zipfile."> across network as <".netzipfile.">") 1split|enew let binkeep= &binary let eikeep = &ei set binary ei=all - exe "e! ".zipfile.".zip" + exe "e! ".zipfile call netrw#NetWrite(netzipfile) let &ei = eikeep let &binary = binkeep @@ -280,7 +304,8 @@ fun! zip#Write(fname) " cleanup and restore current directory cd .. call s:Rmdir("_ZIPVIM_") - exe "cd ".escape(curdir,' \') + call s:ChgDir(curdir,s:WARNING,"(zip#Write) unable to return to ".curdir."!") + call s:Rmdir(tmpdir) setlocal nomod let &report= repkeep @@ -288,17 +313,52 @@ fun! zip#Write(fname) endfun " --------------------------------------------------------------------- +" QuoteFileDir: {{{2 +fun! s:QuoteFileDir(fname) +" call Dfunc("QuoteFileDir(fname<".a:fname.">)") +" call Dret("QuoteFileDir") + return g:zip_shq.a:fname.g:zip_shq +endfun + +" --------------------------------------------------------------------- +" ChgDir: {{{2 +fun! s:ChgDir(newdir,errlvl,errmsg) +" call Dfunc("ChgDir(newdir<".a:newdir."> errlvl=".a:errlvl." errmsg<".a:errmsg.">)") + + if (has("win32") || has("win95") || has("win64") || has("win16")) && &shell !~? 'sh$' + let newdir= escape(a:newdir,' ') + else + let newdir= escape(a:newdir,'\ ') + endif + + try + exe "cd ".newdir + catch /^Vim\%((\a\+)\)\=:E344/ + redraw! + if a:errlvl == s:NOTE + echo "***note*** ".a:errmsg + elseif a:errlvl == s:WARNING + echohl WarningMsg | echo "***warning*** ".a:errmsg | echohl NONE + elseif a:errlvl == s:ERROR + echohl Error | echo "***error*** ".a:errmsg | echohl NONE + endif +" call inputsave()|call input("Press <cr> to continue")|call inputrestore() +" call Dret("ChgDir 1") + return 1 + endtry + +" call Dret("ChgDir 0") + return 0 +endfun + +" --------------------------------------------------------------------- " Rmdir: {{{2 fun! s:Rmdir(fname) " call Dfunc("Rmdir(fname<".a:fname.">)") - if has("unix") - call system("/bin/rm -rf ".a:fname) - elseif has("win32") || has("win95") || has("win64") || has("win16") - if &shell =~? "sh$" - call system("/bin/rm -rf ".a:fname) - else - call system("del /S ".a:fname) - endif + if (has("win32") || has("win95") || has("win64") || has("win16")) && &shell !~? 'sh$' + call system("rmdir /S/Q ".s:QuoteFileDir(a:fname)) + else + call system("/bin/rm -rf ".s:QuoteFileDir(a:fname)) endif " call Dret("Rmdir") endfun @@ -307,4 +367,4 @@ endfun " Modelines And Restoration: {{{1 let &cpo= s:keepcpo unlet s:keepcpo -" vim:ts=8 fdm=marker +" vim:ts=8 fdm=marker |