diff options
Diffstat (limited to 'runtime/autoload')
-rw-r--r-- | runtime/autoload/clojurecomplete.vim | 16 | ||||
-rw-r--r-- | runtime/autoload/csscomplete.vim | 1155 | ||||
-rw-r--r-- | runtime/autoload/health.vim | 178 | ||||
-rw-r--r-- | runtime/autoload/health/nvim.vim | 152 | ||||
-rw-r--r-- | runtime/autoload/health/provider.vim | 461 | ||||
-rw-r--r-- | runtime/autoload/man.vim | 387 | ||||
-rw-r--r-- | runtime/autoload/msgpack.vim | 8 | ||||
-rw-r--r-- | runtime/autoload/netrw.vim | 1778 | ||||
-rw-r--r-- | runtime/autoload/provider/clipboard.vim | 102 | ||||
-rw-r--r-- | runtime/autoload/provider/python.vim | 2 | ||||
-rw-r--r-- | runtime/autoload/provider/python3.vim | 2 | ||||
-rw-r--r-- | runtime/autoload/provider/pythonx.vim | 84 | ||||
-rw-r--r-- | runtime/autoload/provider/ruby.vim | 68 | ||||
-rw-r--r-- | runtime/autoload/provider/script_host.rb | 8 | ||||
-rw-r--r-- | runtime/autoload/remote/host.vim | 78 | ||||
-rw-r--r-- | runtime/autoload/shada.vim | 13 | ||||
-rw-r--r-- | runtime/autoload/sqlcomplete.vim | 35 | ||||
-rw-r--r-- | runtime/autoload/vimball.vim | 775 | ||||
-rw-r--r-- | runtime/autoload/vimexpect.vim | 2 |
19 files changed, 3113 insertions, 2191 deletions
diff --git a/runtime/autoload/clojurecomplete.vim b/runtime/autoload/clojurecomplete.vim index 708bb31104..030785e901 100644 --- a/runtime/autoload/clojurecomplete.vim +++ b/runtime/autoload/clojurecomplete.vim @@ -1,14 +1,14 @@ " Vim completion script -" Language: Clojure -" Maintainer: Sung Pae <self@sungpae.com> -" URL: https://github.com/guns/vim-clojure-static -" License: Same as Vim -" Last Change: 27 March 2014 +" Language: Clojure +" Maintainer: Sung Pae <self@sungpae.com> +" URL: https://github.com/guns/vim-clojure-static +" License: Same as Vim +" Last Change: 18 July 2016 " -*- COMPLETION WORDS -*- -" Generated from https://github.com/guns/vim-clojure-static/blob/vim-release-010/clj/src/vim_clojure_static/generate.clj -" Clojure version 1.6.0 -let s:words = ["*","*'","*1","*2","*3","*agent*","*allow-unresolved-vars*","*assert*","*clojure-version*","*command-line-args*","*compile-files*","*compile-path*","*compiler-options*","*data-readers*","*default-data-reader-fn*","*e","*err*","*file*","*flush-on-newline*","*fn-loader*","*in*","*math-context*","*ns*","*out*","*print-dup*","*print-length*","*print-level*","*print-meta*","*print-readably*","*read-eval*","*source-path*","*unchecked-math*","*use-context-classloader*","*verbose-defrecords*","*warn-on-reflection*","+","+'","-","-'","->","->>","->ArrayChunk","->Vec","->VecNode","->VecSeq","-cache-protocol-fn","-reset-methods",".","..","/","<","<=","=","==",">",">=","EMPTY-NODE","accessor","aclone","add-classpath","add-watch","agent","agent-error","agent-errors","aget","alength","alias","all-ns","alter","alter-meta!","alter-var-root","amap","ancestors","and","apply","areduce","array-map","as->","aset","aset-boolean","aset-byte","aset-char","aset-double","aset-float","aset-int","aset-long","aset-short","assert","assoc!","assoc","assoc-in","associative?","atom","await","await-for","await1","bases","bean","bigdec","bigint","biginteger","binding","bit-and","bit-and-not","bit-clear","bit-flip","bit-not","bit-or","bit-set","bit-shift-left","bit-shift-right","bit-test","bit-xor","boolean","boolean-array","booleans","bound-fn","bound-fn*","bound?","butlast","byte","byte-array","bytes","case","cast","catch","char","char-array","char-escape-string","char-name-string","char?","chars","chunk","chunk-append","chunk-buffer","chunk-cons","chunk-first","chunk-next","chunk-rest","chunked-seq?","class","class?","clear-agent-errors","clojure-version","coll?","comment","commute","comp","comparator","compare","compare-and-set!","compile","complement","concat","cond","cond->","cond->>","condp","conj!","conj","cons","constantly","construct-proxy","contains?","count","counted?","create-ns","create-struct","cycle","dec","dec'","decimal?","declare","def","default-data-readers","definline","definterface","defmacro","defmethod","defmulti","defn","defn-","defonce","defprotocol","defrecord","defstruct","deftype","delay","delay?","deliver","denominator","deref","derive","descendants","destructure","disj!","disj","dissoc!","dissoc","distinct","distinct?","do","doall","dorun","doseq","dosync","dotimes","doto","double","double-array","doubles","drop","drop-last","drop-while","empty","empty?","ensure","enumeration-seq","error-handler","error-mode","eval","even?","every-pred","every?","ex-data","ex-info","extend","extend-protocol","extend-type","extenders","extends?","false?","ffirst","file-seq","filter","filterv","finally","find","find-keyword","find-ns","find-protocol-impl","find-protocol-method","find-var","first","flatten","float","float-array","float?","floats","flush","fn","fn","fn?","fnext","fnil","for","force","format","frequencies","future","future-call","future-cancel","future-cancelled?","future-done?","future?","gen-class","gen-interface","gensym","get","get-in","get-method","get-proxy-class","get-thread-bindings","get-validator","group-by","hash","hash-combine","hash-map","hash-ordered-coll","hash-set","hash-unordered-coll","identical?","identity","if","if-let","if-not","if-some","ifn?","import","in-ns","inc","inc'","init-proxy","instance?","int","int-array","integer?","interleave","intern","interpose","into","into-array","ints","io!","isa?","iterate","iterator-seq","juxt","keep","keep-indexed","key","keys","keyword","keyword?","last","lazy-cat","lazy-seq","let","let","letfn","line-seq","list","list*","list?","load","load-file","load-reader","load-string","loaded-libs","locking","long","long-array","longs","loop","loop","macroexpand","macroexpand-1","make-array","make-hierarchy","map","map-indexed","map?","mapcat","mapv","max","max-key","memfn","memoize","merge","merge-with","meta","method-sig","methods","min","min-key","mix-collection-hash","mod","monitor-enter","monitor-exit","munge","name","namespace","namespace-munge","neg?","new","newline","next","nfirst","nil?","nnext","not","not-any?","not-empty","not-every?","not=","ns","ns-aliases","ns-imports","ns-interns","ns-map","ns-name","ns-publics","ns-refers","ns-resolve","ns-unalias","ns-unmap","nth","nthnext","nthrest","num","number?","numerator","object-array","odd?","or","parents","partial","partition","partition-all","partition-by","pcalls","peek","persistent!","pmap","pop!","pop","pop-thread-bindings","pos?","pr","pr-str","prefer-method","prefers","primitives-classnames","print","print-ctor","print-dup","print-method","print-simple","print-str","printf","println","println-str","prn","prn-str","promise","proxy","proxy-call-with-super","proxy-mappings","proxy-name","proxy-super","push-thread-bindings","pvalues","quot","quote","rand","rand-int","rand-nth","range","ratio?","rational?","rationalize","re-find","re-groups","re-matcher","re-matches","re-pattern","re-seq","read","read-line","read-string","realized?","record?","recur","reduce","reduce-kv","reduced","reduced?","reductions","ref","ref-history-count","ref-max-history","ref-min-history","ref-set","refer","refer-clojure","reify","release-pending-sends","rem","remove","remove-all-methods","remove-method","remove-ns","remove-watch","repeat","repeatedly","replace","replicate","require","reset!","reset-meta!","resolve","rest","restart-agent","resultset-seq","reverse","reversible?","rseq","rsubseq","satisfies?","second","select-keys","send","send-off","send-via","seq","seq?","seque","sequence","sequential?","set!","set","set-agent-send-executor!","set-agent-send-off-executor!","set-error-handler!","set-error-mode!","set-validator!","set?","short","short-array","shorts","shuffle","shutdown-agents","slurp","some","some->","some->>","some-fn","some?","sort","sort-by","sorted-map","sorted-map-by","sorted-set","sorted-set-by","sorted?","special-symbol?","spit","split-at","split-with","str","string?","struct","struct-map","subs","subseq","subvec","supers","swap!","symbol","symbol?","sync","take","take-last","take-nth","take-while","test","the-ns","thread-bound?","throw","time","to-array","to-array-2d","trampoline","transient","tree-seq","true?","try","type","unchecked-add","unchecked-add-int","unchecked-byte","unchecked-char","unchecked-dec","unchecked-dec-int","unchecked-divide-int","unchecked-double","unchecked-float","unchecked-inc","unchecked-inc-int","unchecked-int","unchecked-long","unchecked-multiply","unchecked-multiply-int","unchecked-negate","unchecked-negate-int","unchecked-remainder-int","unchecked-short","unchecked-subtract","unchecked-subtract-int","underive","unquote","unquote-splicing","unsigned-bit-shift-right","update-in","update-proxy","use","val","vals","var","var-get","var-set","var?","vary-meta","vec","vector","vector-of","vector?","when","when-first","when-let","when-not","when-some","while","with-bindings","with-bindings*","with-in-str","with-loading-context","with-local-vars","with-meta","with-open","with-out-str","with-precision","with-redefs","with-redefs-fn","xml-seq","zero?","zipmap"] +" Generated from https://github.com/guns/vim-clojure-static/blob/vim-release-011/clj/src/vim_clojure_static/generate.clj +" Clojure version 1.8.0 +let s:words = ["*","*'","*1","*2","*3","*agent*","*allow-unresolved-vars*","*assert*","*clojure-version*","*command-line-args*","*compile-files*","*compile-path*","*compiler-options*","*data-readers*","*default-data-reader-fn*","*e","*err*","*file*","*flush-on-newline*","*fn-loader*","*in*","*math-context*","*ns*","*out*","*print-dup*","*print-length*","*print-level*","*print-meta*","*print-readably*","*read-eval*","*source-path*","*suppress-read*","*unchecked-math*","*use-context-classloader*","*verbose-defrecords*","*warn-on-reflection*","+","+'","-","-'","->","->>","->ArrayChunk","->Eduction","->Vec","->VecNode","->VecSeq","-cache-protocol-fn","-reset-methods",".","..","/","<","<=","=","==",">",">=","EMPTY-NODE","Throwable->map","accessor","aclone","add-classpath","add-watch","agent","agent-error","agent-errors","aget","alength","alias","all-ns","alter","alter-meta!","alter-var-root","amap","ancestors","and","apply","areduce","array-map","as->","aset","aset-boolean","aset-byte","aset-char","aset-double","aset-float","aset-int","aset-long","aset-short","assert","assoc!","assoc","assoc-in","associative?","atom","await","await-for","await1","bases","bean","bigdec","bigint","biginteger","binding","bit-and","bit-and-not","bit-clear","bit-flip","bit-not","bit-or","bit-set","bit-shift-left","bit-shift-right","bit-test","bit-xor","boolean","boolean-array","booleans","bound-fn","bound-fn*","bound?","butlast","byte","byte-array","bytes","case","cast","cat","catch","char","char-array","char-escape-string","char-name-string","char?","chars","chunk","chunk-append","chunk-buffer","chunk-cons","chunk-first","chunk-next","chunk-rest","chunked-seq?","class","class?","clear-agent-errors","clojure-version","coll?","comment","commute","comp","comparator","compare","compare-and-set!","compile","complement","completing","concat","cond","cond->","cond->>","condp","conj!","conj","cons","constantly","construct-proxy","contains?","count","counted?","create-ns","create-struct","cycle","dec","dec'","decimal?","declare","dedupe","def","default-data-readers","definline","definterface","defmacro","defmethod","defmulti","defn","defn-","defonce","defprotocol","defrecord","defstruct","deftype","delay","delay?","deliver","denominator","deref","derive","descendants","destructure","disj!","disj","dissoc!","dissoc","distinct","distinct?","do","doall","dorun","doseq","dosync","dotimes","doto","double","double-array","doubles","drop","drop-last","drop-while","eduction","empty","empty?","ensure","ensure-reduced","enumeration-seq","error-handler","error-mode","eval","even?","every-pred","every?","ex-data","ex-info","extend","extend-protocol","extend-type","extenders","extends?","false?","ffirst","file-seq","filter","filterv","finally","find","find-keyword","find-ns","find-protocol-impl","find-protocol-method","find-var","first","flatten","float","float-array","float?","floats","flush","fn","fn","fn?","fnext","fnil","for","force","format","frequencies","future","future-call","future-cancel","future-cancelled?","future-done?","future?","gen-class","gen-interface","gensym","get","get-in","get-method","get-proxy-class","get-thread-bindings","get-validator","group-by","hash","hash-combine","hash-map","hash-ordered-coll","hash-set","hash-unordered-coll","identical?","identity","if","if-let","if-not","if-some","ifn?","import","in-ns","inc","inc'","init-proxy","instance?","int","int-array","integer?","interleave","intern","interpose","into","into-array","ints","io!","isa?","iterate","iterator-seq","juxt","keep","keep-indexed","key","keys","keyword","keyword?","last","lazy-cat","lazy-seq","let","let","letfn","line-seq","list","list*","list?","load","load-file","load-reader","load-string","loaded-libs","locking","long","long-array","longs","loop","loop","macroexpand","macroexpand-1","make-array","make-hierarchy","map","map-entry?","map-indexed","map?","mapcat","mapv","max","max-key","memfn","memoize","merge","merge-with","meta","method-sig","methods","min","min-key","mix-collection-hash","mod","monitor-enter","monitor-exit","munge","name","namespace","namespace-munge","neg?","new","newline","next","nfirst","nil?","nnext","not","not-any?","not-empty","not-every?","not=","ns","ns-aliases","ns-imports","ns-interns","ns-map","ns-name","ns-publics","ns-refers","ns-resolve","ns-unalias","ns-unmap","nth","nthnext","nthrest","num","number?","numerator","object-array","odd?","or","parents","partial","partition","partition-all","partition-by","pcalls","peek","persistent!","pmap","pop!","pop","pop-thread-bindings","pos?","pr","pr-str","prefer-method","prefers","primitives-classnames","print","print-ctor","print-dup","print-method","print-simple","print-str","printf","println","println-str","prn","prn-str","promise","proxy","proxy-call-with-super","proxy-mappings","proxy-name","proxy-super","push-thread-bindings","pvalues","quot","quote","rand","rand-int","rand-nth","random-sample","range","ratio?","rational?","rationalize","re-find","re-groups","re-matcher","re-matches","re-pattern","re-seq","read","read-line","read-string","reader-conditional","reader-conditional?","realized?","record?","recur","reduce","reduce-kv","reduced","reduced?","reductions","ref","ref-history-count","ref-max-history","ref-min-history","ref-set","refer","refer-clojure","reify","release-pending-sends","rem","remove","remove-all-methods","remove-method","remove-ns","remove-watch","repeat","repeatedly","replace","replicate","require","reset!","reset-meta!","resolve","rest","restart-agent","resultset-seq","reverse","reversible?","rseq","rsubseq","run!","satisfies?","second","select-keys","send","send-off","send-via","seq","seq?","seque","sequence","sequential?","set!","set","set-agent-send-executor!","set-agent-send-off-executor!","set-error-handler!","set-error-mode!","set-validator!","set?","short","short-array","shorts","shuffle","shutdown-agents","slurp","some","some->","some->>","some-fn","some?","sort","sort-by","sorted-map","sorted-map-by","sorted-set","sorted-set-by","sorted?","special-symbol?","spit","split-at","split-with","str","string?","struct","struct-map","subs","subseq","subvec","supers","swap!","symbol","symbol?","sync","tagged-literal","tagged-literal?","take","take-last","take-nth","take-while","test","the-ns","thread-bound?","throw","time","to-array","to-array-2d","trampoline","transduce","transient","tree-seq","true?","try","type","unchecked-add","unchecked-add-int","unchecked-byte","unchecked-char","unchecked-dec","unchecked-dec-int","unchecked-divide-int","unchecked-double","unchecked-float","unchecked-inc","unchecked-inc-int","unchecked-int","unchecked-long","unchecked-multiply","unchecked-multiply-int","unchecked-negate","unchecked-negate-int","unchecked-remainder-int","unchecked-short","unchecked-subtract","unchecked-subtract-int","underive","unquote","unquote-splicing","unreduced","unsigned-bit-shift-right","update","update-in","update-proxy","use","val","vals","var","var-get","var-set","var?","vary-meta","vec","vector","vector-of","vector?","volatile!","volatile?","vreset!","vswap!","when","when-first","when-let","when-not","when-some","while","with-bindings","with-bindings*","with-in-str","with-loading-context","with-local-vars","with-meta","with-open","with-out-str","with-precision","with-redefs","with-redefs-fn","xml-seq","zero?","zipmap"] " Simple word completion for special forms and public vars in clojure.core function! clojurecomplete#Complete(findstart, base) diff --git a/runtime/autoload/csscomplete.vim b/runtime/autoload/csscomplete.vim index 9eebb87d5b..50048a37fd 100644 --- a/runtime/autoload/csscomplete.vim +++ b/runtime/autoload/csscomplete.vim @@ -1,429 +1,740 @@ " Vim completion script -" Language: CSS 2.1 -" Maintainer: Mikolaj Machowski ( mikmach AT wp DOT pl ) -" Last Change: 2007 May 5 +" Language: CSS +" Based on MDN CSS Reference at 2016 Jan <https://developer.mozilla.org/en-US/docs/Web/CSS/Reference> +" plus CSS Speech Module <http://www.w3.org/TR/css3-speech/> +" Maintainer: Kao, Wei-Ko(othree) ( othree AT gmail DOT com ) +" Original Author: Mikolaj Machowski ( mikmach AT wp DOT pl ) +" Last Change: 2016 Jan 11 - let s: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 s:values = split("all additive-symbols align-content align-items align-self animation animation-delay animation-direction animation-duration animation-fill-mode animation-iteration-count animation-name animation-play-state animation-timing-function backface-visibility background background-attachment background-blend-mode background-clip background-color background-image background-origin background-position background-repeat background-size block-size border border-block-end border-block-end-color border-block-end-style border-block-end-width border-block-start border-block-start-color border-block-start-style border-block-start-width border-bottom border-bottom-color border-bottom-left-radius border-bottom-right-radius border-bottom-style border-bottom-width border-collapse border-color border-image border-image-outset border-image-repeat border-image-slice border-image-source border-image-width border-inline-end border-inline-end-color border-inline-end-style border-inline-end-width border-inline-start border-inline-start-color border-inline-start-style border-inline-start-width border-left border-left-color border-left-style border-left-width border-radius border-right border-right-color border-right-style border-right-width border-spacing border-style border-top border-top-color border-top-left-radius border-top-right-radius border-top-style border-top-width border-width bottom box-decoration-break box-shadow box-sizing break-after break-before break-inside caption-side clear clip clip-path color columns column-count column-fill column-gap column-rule column-rule-color column-rule-style column-rule-width column-span column-width content counter-increment counter-reset cue cue-before cue-after cursor direction display empty-cells fallback filter flex flex-basis flex-direction flex-flow flex-grow flex-shrink flex-wrap float font font-family font-feature-settings font-kerning font-language-override font-size font-size-adjust font-stretch font-style font-synthesis font-variant font-variant-alternates font-variant-caps font-variant-east-asian font-variant-ligatures font-variant-numeric font-variant-position font-weight grid grid-area grid-auto-columns grid-auto-flow grid-auto-position grid-auto-rows grid-column grid-column-start grid-column-end grid-row grid-row-start grid-row-end grid-template grid-template-areas grid-template-rows grid-template-columns height hyphens image-rendering image-resolution image-orientation ime-mode inline-size isolation justify-content left letter-spacing line-break line-height list-style list-style-image list-style-position list-style-type margin margin-block-end margin-block-start margin-bottom margin-inline-end margin-inline-start margin-left margin-right margin-top marks mask mask-type max-block-size max-height max-inline-size max-width max-zoom min-block-size min-height min-inline-size min-width min-zoom mix-blend-mode negative object-fit object-position offset-block-end offset-block-start offset-inline-end offset-inline-start opacity order orientation orphans outline outline-color outline-offset outline-style outline-width overflow overflow-wrap overflow-x overflow-y pad padding padding-block-end padding-block-start padding-bottom padding-inline-end padding-inline-start padding-left padding-right padding-top page-break-after page-break-before page-break-inside pause-before pause-after pause perspective perspective-origin pointer-events position prefix quotes range resize rest rest-before rest-after right ruby-align ruby-merge ruby-position scroll-behavior scroll-snap-coordinate scroll-snap-destination scroll-snap-points-x scroll-snap-points-y scroll-snap-type scroll-snap-type-x scroll-snap-type-y shape-image-threshold shape-margin shape-outside speak speak-as suffix symbols system table-layout tab-size text-align text-align-last text-combine-upright text-decoration text-decoration-color text-decoration-line text-emphasis text-emphasis-color text-emphasis-position text-emphasis-style text-indent text-orientation text-overflow text-rendering text-shadow text-transform text-underline-position top touch-action transform transform-box transform-origin transform-style transition transition-delay transition-duration transition-property transition-timing-function unicode-bidi unicode-range user-zoom vertical-align visibility voice-balance voice-duration voice-family voice-pitch voice-rate voice-range voice-stress voice-volume white-space widows width will-change word-break word-spacing word-wrap writing-mode z-index zoom") -function! csscomplete#CompleteCSS(findstart, base) - -if a:findstart - " We need whole line to proper checking - let line = getline('.') - let start = col('.') - 1 - let compl_begin = col('.') - 2 - while start >= 0 && line[start - 1] =~ '\%(\k\|-\)' - let start -= 1 - endwhile - let b:compl_context = line[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 - 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 entered_property = matchstr(line, '.\{-}\zs[a-zA-Z-]*$') - - for m in s: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 [] - 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 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' - 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' - 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 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' - 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 - 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[max(keys(borders))] == 'closebrace' - - return [] - -elseif borders[max(keys(borders))] == 'exclam' - - " Complete values - let entered_imp = matchstr(line, '.\{-}!\s*\zs[a-zA-Z ]*$') - - let values = ["important"] - - for m in values - if m =~? '^'.entered_imp - call add(res, m) - endif - endfor - - return res - -elseif borders[max(keys(borders))] == 'atrule' - - let afterat = matchstr(line, '.*@\zs.*') - - if afterat =~ '\s' - - let atrulename = matchstr(line, '.*@\zs[a-zA-Z-]\+\ze') - - if atrulename == 'media' - let values = ["screen", "tty", "tv", "projection", "handheld", "print", "braille", "aural", "all"] - - let entered_atruleafter = matchstr(line, '.*@media\s\+\zs.*$') - - elseif atrulename == 'import' - let entered_atruleafter = matchstr(line, '.*@import\s\+\zs.*$') - - 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 - let values = ['"', 'url('] - - endif - - else - return [] - - 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 - - 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 .' ') - endif - endfor - - return res + res2 - -endif +function! csscomplete#CompleteCSS(findstart, base) -return [] + if a:findstart + " We need whole line to proper checking + let line = getline('.') + let start = col('.') - 1 + let compl_begin = col('.') - 2 + while start >= 0 && line[start - 1] =~ '\%(\k\|-\)' + let start -= 1 + endwhile + let b:after = line[compl_begin :] + let b:compl_context = line[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 + let after = b:after + unlet! b:compl_context + else + 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 entered_property = matchstr(line, '.\{-}\zs[a-zA-Z-]*$') + + for m in s: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*:[^:]\{-}$')) + + let wide_keywords = ["initial", "inherit", "unset"] + let color_values = ["transparent", "rgb(", "rgba(", "hsl(", "hsla(", "#"] + let border_style_values = ["none", "hidden", "dotted", "dashed", "solid", "double", "groove", "ridge", "inset", "outset"] + let border_width_values = ["thin", "thick", "medium"] + let list_style_type_values = ["decimal", "decimal-leading-zero", "arabic-indic", "armenian", "upper-armenian", "lower-armenian", "bengali", "cambodian", "khmer", "cjk-decimal", "devanagari", "georgian", "gujarati", "gurmukhi", "hebrew", "kannada", "lao", "malayalam", "mongolian", "myanmar", "oriya", "persian", "lower-roman", "upper-roman", "tamil", "telugu", "thai", "tibetan", "lower-alpha", "lower-latin", "upper-alpha", "upper-latin", "cjk-earthly-branch", "cjk-heavenly-stem", "lower-greek", "hiragana", "hiragana-iroha", "katakana", "katakana-iroha", "disc", "circle", "square", "disclosure-open", "disclosure-closed"] + let timing_functions = ["cubic-bezier(", "steps(", "linear", "ease", "ease-in", "ease-in-out", "ease-out", "step-start", "step-end"] + + if prop == 'all' + let values = [] + elseif prop == 'additive-symbols' + let values = [] + elseif prop == 'align-content' + let values = ["flex-start", "flex-end", "center", "space-between", "space-around", "stretch"] + elseif prop == 'align-items' + let values = ["flex-start", "flex-end", "center", "baseline", "stretch"] + elseif prop == 'align-self' + let values = ["auto", "flex-start", "flex-end", "center", "baseline", "stretch"] + elseif prop == 'animation' + let values = timing_functions + ["normal", "reverse", "alternate", "alternate-reverse"] + ["none", "forwards", "backwards", "both"] + ["running", "paused"] + elseif prop == 'animation-delay' + let values = [] + elseif prop == 'animation-direction' + let values = ["normal", "reverse", "alternate", "alternate-reverse"] + elseif prop == 'animation-duration' + let values = [] + elseif prop == 'animation-fill-mode' + let values = ["none", "forwards", "backwards", "both"] + elseif prop == 'animation-iteration-count' + let values = [] + elseif prop == 'animation-name' + let values = [] + elseif prop == 'animation-play-state' + let values = ["running", "paused"] + elseif prop == 'animation-timing-function' + let values = timing_functions + elseif prop == 'background-attachment' + let values = ["scroll", "fixed"] + elseif prop == 'background-color' + let values = color_values + 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-size' + let values = ["auto", "contain", "cover"] + elseif prop == 'background' + let values = ["scroll", "fixed"] + color_values + ["url(", "none"] + ["top", "center", "bottom", "left", "right"] + ["repeat", "repeat-x", "repeat-y", "no-repeat"] + ["auto", "contain", "cover"] + elseif prop =~ 'border\%(-top\|-right\|-bottom\|-left\|-block-start\|-block-end\)\?$' + let vals = matchstr(line, '.*:\s*\zs.*') + if vals =~ '^\%([a-zA-Z0-9.]\+\)\?$' + let values = border_width_values + elseif vals =~ '^[a-zA-Z0-9.]\+\s\+\%([a-zA-Z]\+\)\?$' + let values = border_style_values + elseif vals =~ '^[a-zA-Z0-9.]\+\s\+[a-zA-Z]\+\s\+\%([a-zA-Z(]\+\)\?$' + let values = color_values + else + return [] + endif + elseif prop =~ 'border-\%(top\|right\|bottom\|left\|block-start\|block-end\)-color' + let values = color_values + elseif prop =~ 'border-\%(top\|right\|bottom\|left\|block-start\|block-end\)-style' + let values = border_style_values + elseif prop =~ 'border-\%(top\|right\|bottom\|left\|block-start\|block-end\)-width' + let values = border_width_values + elseif prop == 'border-color' + let values = color_values + elseif prop == 'border-style' + let values = border_style_values + elseif prop == 'border-width' + let values = border_width_values + elseif prop == 'bottom' + let values = ["auto"] + elseif prop == 'box-decoration-break' + let values = ["slice", "clone"] + elseif prop == 'box-shadow' + let values = ["inset"] + elseif prop == 'box-sizing' + let values = ["border-box", "content-box"] + elseif prop =~ 'break-\%(before\|after\)' + let values = ["auto", "always", "avoid", "left", "right", "page", "column", "region", "recto", "verso", "avoid-page", "avoid-column", "avoid-region"] + elseif prop == 'break-inside' + let values = ["auto", "avoid", "avoid-page", "avoid-column", "avoid-region"] + 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 == 'clip-path' + let values = ["fill-box", "stroke-box", "view-box", "none"] + elseif prop == 'color' + let values = color_values + elseif prop == 'columns' + let values = [] + elseif prop == 'column-count' + let values = ['auto'] + elseif prop == 'column-fill' + let values = ['auto', 'balance'] + elseif prop == 'column-rule-color' + let values = color_values + elseif prop == 'column-rule-style' + let values = border_style_values + elseif prop == 'column-rule-width' + let values = border_width_values + elseif prop == 'column-rule' + let vals = matchstr(line, '.*:\s*\zs.*') + if vals =~ '^\%([a-zA-Z0-9.]\+\)\?$' + let values = border_width_values + elseif vals =~ '^[a-zA-Z0-9.]\+\s\+\%([a-zA-Z]\+\)\?$' + let values = border_style_values + elseif vals =~ '^[a-zA-Z0-9.]\+\s\+[a-zA-Z]\+\s\+\%([a-zA-Z(]\+\)\?$' + let values = color_values + else + return [] + endif + elseif prop == 'column-span' + let values = ["none", "all"] + elseif prop == 'column-width' + let values = ["auto"] + 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\|-before\)\=$' + let values = ["url("] + 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", "inline-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", "flex", "inline-flex", "grid", "inline-grid", "ruby", "ruby-base", "ruby-text", "ruby-base-container", "ruby-text-container", "contents"] + elseif prop == 'elevation' + let values = ["below", "level", "above", "higher", "lower"] + elseif prop == 'empty-cells' + let values = ["show", "hide"] + elseif prop == 'fallback' + let values = list_style_type_values + elseif prop == 'filter' + let values = ["blur(", "brightness(", "contrast(", "drop-shadow(", "grayscale(", "hue-rotate(", "invert(", "opacity(", "sepia(", "saturate("] + elseif prop == 'flex-basis' + let values = ["auto", "content"] + elseif prop == 'flex-flow' + let values = ["row", "row-reverse", "column", "column-reverse", "nowrap", "wrap", "wrap-reverse"] + elseif prop == 'flex-grow' + let values = [] + elseif prop == 'flex-shrink' + let values = [] + elseif prop == 'flex-wrap' + let values = ["nowrap", "wrap", "wrap-reverse"] + elseif prop == 'flex' + let values = ["nowrap", "wrap", "wrap-reverse"] + ["row", "row-reverse", "column", "column-reverse", "nowrap", "wrap", "wrap-reverse"] + ["auto", "content"] + elseif prop == 'float' + let values = ["left", "right", "none"] + elseif prop == 'font-family' + let values = ["sans-serif", "serif", "monospace", "cursive", "fantasy"] + elseif prop == 'font-feature-settings' + let values = ["normal", '"aalt"', '"abvf"', '"abvm"', '"abvs"', '"afrc"', '"akhn"', '"blwf"', '"blwm"', '"blws"', '"calt"', '"case"', '"ccmp"', '"cfar"', '"cjct"', '"clig"', '"cpct"', '"cpsp"', '"cswh"', '"curs"', '"cv', '"c2pc"', '"c2sc"', '"dist"', '"dlig"', '"dnom"', '"dtls"', '"expt"', '"falt"', '"fin2"', '"fin3"', '"fina"', '"flac"', '"frac"', '"fwid"', '"half"', '"haln"', '"halt"', '"hist"', '"hkna"', '"hlig"', '"hngl"', '"hojo"', '"hwid"', '"init"', '"isol"', '"ital"', '"jalt"', '"jp78"', '"jp83"', '"jp90"', '"jp04"', '"kern"', '"lfbd"', '"liga"', '"ljmo"', '"lnum"', '"locl"', '"ltra"', '"ltrm"', '"mark"', '"med2"', '"medi"', '"mgrk"', '"mkmk"', '"mset"', '"nalt"', '"nlck"', '"nukt"', '"numr"', '"onum"', '"opbd"', '"ordn"', '"ornm"', '"palt"', '"pcap"', '"pkna"', '"pnum"', '"pref"', '"pres"', '"pstf"', '"psts"', '"pwid"', '"qwid"', '"rand"', '"rclt"', '"rkrf"', '"rlig"', '"rphf"', '"rtbd"', '"rtla"', '"rtlm"', '"ruby"', '"salt"', '"sinf"', '"size"', '"smcp"', '"smpl"', '"ss01"', '"ss02"', '"ss03"', '"ss04"', '"ss05"', '"ss06"', '"ss07"', '"ss08"', '"ss09"', '"ss10"', '"ss11"', '"ss12"', '"ss13"', '"ss14"', '"ss15"', '"ss16"', '"ss17"', '"ss18"', '"ss19"', '"ss20"', '"ssty"', '"stch"', '"subs"', '"sups"', '"swsh"', '"titl"', '"tjmo"', '"tnam"', '"tnum"', '"trad"', '"twid"', '"unic"', '"valt"', '"vatu"', '"vert"', '"vhal"', '"vjmo"', '"vkna"', '"vkrn"', '"vpal"', '"vrt2"', '"zero"'] + elseif prop == 'font-kerning' + let values = ["auto", "normal", "none"] + elseif prop == 'font-language-override' + let values = ["normal"] + elseif prop == 'font-size' + let values = ["xx-small", "x-small", "small", "medium", "large", "x-large", "xx-large", "larger", "smaller"] + elseif prop == 'font-size-adjust' + let values = [] + elseif prop == 'font-stretch' + let values = ["normal", "ultra-condensed", "extra-condensed", "condensed", "semi-condensed", "semi-expanded", "expanded", "extra-expanded", "ultra-expanded"] + elseif prop == 'font-style' + let values = ["normal", "italic", "oblique"] + elseif prop == 'font-synthesis' + let values = ["none", "weight", "style"] + elseif prop == 'font-variant-alternates' + let values = ["normal", "historical-forms", "stylistic(", "styleset(", "character-variant(", "swash(", "ornaments(", "annotation("] + elseif prop == 'font-variant-caps' + let values = ["normal", "small-caps", "all-small-caps", "petite-caps", "all-petite-caps", "unicase", "titling-caps"] + elseif prop == 'font-variant-asian' + let values = ["normal", "ruby", "jis78", "jis83", "jis90", "jis04", "simplified", "traditional"] + elseif prop == 'font-variant-ligatures' + let values = ["normal", "none", "common-ligatures", "no-common-ligatures", "discretionary-ligatures", "no-discretionary-ligatures", "historical-ligatures", "no-historical-ligatures", "contextual", "no-contextual"] + elseif prop == 'font-variant-numeric' + let values = ["normal", "ordinal", "slashed-zero", "lining-nums", "oldstyle-nums", "proportional-nums", "tabular-nums", "diagonal-fractions", "stacked-fractions"] + elseif prop == 'font-variant-position' + let values = ["normal", "sub", "super"] + elseif prop == 'font-variant' + let values = ["normal", "historical-forms", "stylistic(", "styleset(", "character-variant(", "swash(", "ornaments(", "annotation("] + ["small-caps", "all-small-caps", "petite-caps", "all-petite-caps", "unicase", "titling-caps"] + ["ruby", "jis78", "jis83", "jis90", "jis04", "simplified", "traditional"] + ["none", "common-ligatures", "no-common-ligatures", "discretionary-ligatures", "no-discretionary-ligatures", "historical-ligatures", "no-historical-ligatures", "contextual", "no-contextual"] + ["ordinal", "slashed-zero", "lining-nums", "oldstyle-nums", "proportional-nums", "tabular-nums", "diagonal-fractions", "stacked-fractions"] + ["sub", "super"] + 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", "border-box", "content-box", "max-content", "min-content", "available", "fit-content"] + elseif prop =~ '^\%(left\|rigth\)$' + let values = ["auto"] + elseif prop == 'image-rendering' + let values = ["auto", "crisp-edges", "pixelated"] + elseif prop == 'image-orientation' + let values = ["from-image", "flip"] + elseif prop == 'ime-mode' + let values = ["auto", "normal", "active", "inactive", "disabled"] + elseif prop == 'inline-size' + let values = ["auto", "border-box", "content-box", "max-content", "min-content", "available", "fit-content"] + elseif prop == 'isolation' + let values = ["auto", "isolate"] + elseif prop == 'justify-content' + let values = ["flex-start", "flex-end", "center", "space-between", "space-around"] + elseif prop == 'letter-spacing' + let values = ["normal"] + elseif prop == 'line-break' + let values = ["auto", "loose", "normal", "strict"] + 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 = list_style_type_values + elseif prop == 'list-style' + let values = list_style_type_values + ["inside", "outside"] + ["url(", "none"] + elseif prop == 'margin' + let values = ["auto"] + elseif prop =~ 'margin-\%(right\|left\|top\|bottom\|block-start\|block-end\|inline-start\|inline-end\)$' + let values = ["auto"] + elseif prop == 'marks' + let values = ["crop", "cross", "none"] + elseif prop == 'mask' + let values = ["url("] + elseif prop == 'mask-type' + let values = ["luminance", "alpha"] + elseif prop == '\%(max\|min\)-\%(block\|inline\)-size' + let values = ["auto", "border-box", "content-box", "max-content", "min-content", "available", "fit-content"] + elseif prop == '\%(max\|min\)-\%(height\|width\)' + let values = ["auto", "border-box", "content-box", "max-content", "min-content", "available", "fit-content"] + elseif prop == '\%(max\|min\)-zoom' + let values = ["auto"] + elseif prop == 'mix-blend-mode' + let values = ["normal", "multiply", "screen", "overlay", "darken", "lighten", "color-dodge", "color-burn", "hard-light", "soft-light", "difference", "exclusion", "hue", "saturation", "color", "luminosity"] + elseif prop == 'opacity' + let values = [] + elseif prop == 'orientation' + let values = ["auto", "portrait", "landscape"] + elseif prop == 'orphans' + let values = [] + elseif prop == 'outline-offset' + let values = [] + elseif prop == 'outline-color' + let values = color_values + 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 = color_values + 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-wrap' + let values = ["normal", "break-word"] + elseif prop =~ 'overflow\%(-x\|-y\)\=' + let values = ["visible", "hidden", "scroll", "auto"] + elseif prop == 'pad' + let values = [] + elseif prop == 'padding' + let values = [] + elseif prop =~ 'padding-\%(top\|right\|bottom\|left\|inline-start\|inline-end\|block-start\|block-end\)$' + let values = [] + elseif prop =~ 'page-break-\%(after\|before\)$' + let values = ["auto", "always", "avoid", "left", "right", "recto", "verso"] + elseif prop == 'page-break-inside' + let values = ["auto", "avoid"] + elseif prop =~ 'pause\%(-after\|-before\)\=$' + let values = ["none", "x-weak", "weak", "medium", "strong", "x-strong"] + elseif prop == 'perspective' + let values = ["none"] + elseif prop == 'perspective-origin' + let values = ["top", "bottom", "left", "center", " right"] + elseif prop == 'pointer-events' + let values = ["auto", "none", "visiblePainted", "visibleFill", "visibleStroke", "visible", "painted", "fill", "stroke", "all"] + elseif prop == 'position' + let values = ["static", "relative", "absolute", "fixed", "sticky"] + elseif prop == 'prefix' + let values = [] + elseif prop == 'quotes' + let values = ["none"] + elseif prop == 'range' + let values = ["auto", "infinite"] + elseif prop == 'resize' + let values = ["none", "both", "horizontal", "vertical"] + elseif prop =~ 'rest\%(-after\|-before\)\=$' + let values = ["none", "x-weak", "weak", "medium", "strong", "x-strong"] + elseif prop == 'ruby-align' + let values = ["start", "center", "space-between", "space-around"] + elseif prop == 'ruby-merge' + let values = ["separate", "collapse", "auto"] + elseif prop == 'ruby-position' + let values = ["over", "under", "inter-character"] + elseif prop == 'scroll-behavior' + let values = ["auto", "smooth"] + elseif prop == 'scroll-snap-coordinate' + let values = ["none"] + elseif prop == 'scroll-snap-destination' + return [] + elseif prop == 'scroll-snap-points-\%(x\|y\)$' + let values = ["none", "repeat("] + elseif prop == 'scroll-snap-type\%(-x\|-y\)\=$' + let values = ["none", "mandatory", "proximity"] + elseif prop == 'shape-image-threshold' + let values = [] + elseif prop == 'shape-margin' + let values = [] + elseif prop == 'shape-outside' + let values = ["margin-box", "border-box", "padding-box", "content-box", 'inset(', 'circle(', 'ellipse(', 'polygon(', 'url('] + elseif prop == 'speak' + let values = ["auto", "none", "normal"] + elseif prop == 'speak-as' + let values = ["auto", "normal", "spell-out", "digits"] + elseif prop == 'src' + let values = ["url("] + elseif prop == 'suffix' + let values = [] + elseif prop == 'symbols' + let values = [] + elseif prop == 'system' + let vals = matchstr(line, '.*:\s*\zs.*') + if vals =~ '^extends' + let values = list_style_type_values + else + let values = ["cyclic", "numeric", "alphabetic", "symbolic", "additive", "fixed", "extends"] + endif + elseif prop == 'table-layout' + let values = ["auto", "fixed"] + elseif prop == 'tab-size' + let values = [] + elseif prop == 'text-align' + let values = ["start", "end", "left", "right", "center", "justify", "match-parent"] + elseif prop == 'text-align-last' + let values = ["auto", "start", "end", "left", "right", "center", "justify"] + elseif prop == 'text-combine-upright' + let values = ["none", "all", "digits"] + elseif prop == 'text-decoration-line' + let values = ["none", "underline", "overline", "line-through", "blink"] + elseif prop == 'text-decoration-color' + let values = color_values + elseif prop == 'text-decoration-style' + let values = ["solid", "double", "dotted", "dashed", "wavy"] + elseif prop == 'text-decoration' + let values = ["none", "underline", "overline", "line-through", "blink"] + ["solid", "double", "dotted", "dashed", "wavy"] + color_values + elseif prop == 'text-emphasis-color' + let values = color_values + elseif prop == 'text-emphasis-position' + let values = ["over", "under", "left", "right"] + elseif prop == 'text-emphasis-style' + let values = ["none", "filled", "open", "dot", "circle", "double-circle", "triangle", "sesame"] + elseif prop == 'text-emphasis' + let values = color_values + ["over", "under", "left", "right"] + ["none", "filled", "open", "dot", "circle", "double-circle", "triangle", "sesame"] + elseif prop == 'text-indent' + let values = ["hanging", "each-line"] + elseif prop == 'text-orientation' + let values = ["mixed", "upright", "sideways", "sideways-right", "use-glyph-orientation"] + elseif prop == 'text-overflow' + let values = ["clip", "ellipsis"] + elseif prop == 'text-rendering' + let values = ["auto", "optimizeSpeed", "optimizeLegibility", "geometricPrecision"] + elseif prop == 'text-shadow' + let values = color_values + elseif prop == 'text-transform' + let values = ["capitalize", "uppercase", "lowercase", "full-width", "none"] + elseif prop == 'text-underline-position' + let values = ["auto", "under", "left", "right"] + elseif prop == 'touch-action' + let values = ["auto", "none", "pan-x", "pan-y", "manipulation", "pan-left", "pan-right", "pan-top", "pan-down"] + elseif prop == 'transform' + let values = ["matrix(", "translate(", "translateX(", "translateY(", "scale(", "scaleX(", "scaleY(", "rotate(", "skew(", "skewX(", "skewY(", "matrix3d(", "translate3d(", "translateZ(", "scale3d(", "scaleZ(", "rotate3d(", "rotateX(", "rotateY(", "rotateZ(", "perspective("] + elseif prop == 'transform-box' + let values = ["border-box", "fill-box", "view-box"] + elseif prop == 'transform-origin' + let values = ["left", "center", "right", "top", "bottom"] + elseif prop == 'transform-style' + let values = ["flat", "preserve-3d"] + elseif prop == 'top' + let values = ["auto"] + elseif prop == 'transition-property' + let values = ["all", "none"] + s:values + elseif prop == 'transition-duration' + let values = [] + elseif prop == 'transition-delay' + let values = [] + elseif prop == 'transition-timing-function' + let values = timing_functions + elseif prop == 'transition' + let values = ["all", "none"] + s:values + timing_functions + elseif prop == 'unicode-bidi' + let values = ["normal", "embed", "isolate", "bidi-override", "isolate-override", "plaintext"] + elseif prop == 'unicode-range' + let values = ["U+"] + elseif prop == 'user-zoom' + let values = ["zoom", "fixed"] + 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-volume' + let values = ["silent", "x-soft", "soft", "medium", "loud", "x-loud"] + elseif prop == 'voice-balance' + let values = ["left", "center", "right", "leftwards", "rightwards"] + elseif prop == 'voice-family' + let values = [] + elseif prop == 'voice-rate' + let values = ["normal", "x-slow", "slow", "medium", "fast", "x-fast"] + elseif prop == 'voice-pitch' + let values = ["absolute", "x-low", "low", "medium", "high", "x-high"] + elseif prop == 'voice-range' + let values = ["absolute", "x-low", "low", "medium", "high", "x-high"] + elseif prop == 'voice-stress' + let values = ["normal", "strong", "moderate", "none", "reduced "] + elseif prop == 'voice-duration' + let values = ["auto"] + elseif prop == 'white-space' + let values = ["normal", "pre", "nowrap", "pre-wrap", "pre-line"] + elseif prop == 'widows' + let values = [] + elseif prop == 'will-change' + let values = ["auto", "scroll-position", "contents"] + s:values + elseif prop == 'word-break' + let values = ["normal", "break-all", "keep-all"] + elseif prop == 'word-spacing' + let values = ["normal"] + elseif prop == 'word-wrap' + let values = ["normal", "break-word"] + elseif prop == 'writing-mode' + let values = ["horizontal-tb", "vertical-rl", "vertical-lr", "sideways-rl", "sideways-lr"] + elseif prop == 'z-index' + let values = ["auto"] + elseif prop == 'zoom' + 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,address,area,article,aside,audio,b,base,bdi,bdo,bgsound,blockquote,body,br,button,canvas,caption,center,cite,code,col,colgroup,command,content,data,datalist,dd,del,details,dfn,dialog,div,dl,dt,element,em,embed,fieldset,figcaption,figure,font,footer,form,frame,frameset,head,header,hgroup,hr,html,i,iframe,image,img,input,ins,isindex,kbd,keygen,label,legend,li,link,main,map,mark,menu,menuitem,meta,meter,nav,nobr,noframes,noscript,object,ol,optgroup,option,output,p,param,picture,pre,progress,q,rp,rt,rtc,ruby,s,samp,script,section,select,shadow,small,source,span,strong,style,sub,summary,sup,table,tbody,td,template,textarea,tfoot,th,thead,time,title,tr,track,u,ul,var,video,wbr', ','.element.',') > -1 + let values = ["active", "any", "checked", "default", "dir(", "disabled", "empty", "enabled", "first", "first-child", "first-of-type", "fullscreen", "focus", "hover", "indeterminate", "in-range", "invalid", "lang(", "last-child", "last-of-type", "left", "link", "not(", "nth-child(", "nth-last-child(", "nth-last-of-type(", "nth-of-type(", "only-child", "only-of-type", "optional", "out-of-range", "read-only", "read-write", "required", "right", "root", "scope", "target", "valid", "visited", "first-line", "first-letter", "before", "after", "selection", "backdrop"] + else + return [] + endif + endif + + let values = wide_keywords + values + " 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[max(keys(borders))] == 'closebrace' + + return [] + + elseif borders[max(keys(borders))] == 'exclam' + + " Complete values + let entered_imp = matchstr(line, '.\{-}!\s*\zs[a-zA-Z ]*$') + + let values = ["important"] + + for m in values + if m =~? '^'.entered_imp + call add(res, m) + endif + endfor + + return res + + elseif borders[max(keys(borders))] == 'atrule' + + let afterat = matchstr(line, '.*@\zs.*') + + if afterat =~ '\s' + + let atrulename = matchstr(line, '.*@\zs[a-zA-Z-]\+\ze') + + if atrulename == 'media' + let entered_atruleafter = matchstr(line, '.*@media\s\+\zs.*$') + + if entered_atruleafter =~ "([^)]*$" + let entered_atruleafter = matchstr(entered_atruleafter, '(\s*\zs[^)]*$') + let values = ["max-width", "min-width", "width", "max-height", "min-height", "height", "max-aspect-ration", "min-aspect-ration", "aspect-ratio", "orientation", "max-resolution", "min-resolution", "resolution", "scan", "grid", "update-frequency", "overflow-block", "overflow-inline", "max-color", "min-color", "color", "max-color-index", "min-color-index", "color-index", "monochrome", "inverted-colors", "pointer", "hover", "any-pointer", "any-hover", "light-level", "scripting"] + else + let values = ["screen", "print", "speech", "all", "not", "and", "("] + endif + + elseif atrulename == 'supports' + let entered_atruleafter = matchstr(line, '.*@supports\s\+\zs.*$') + + if entered_atruleafter =~ "([^)]*$" + let entered_atruleafter = matchstr(entered_atruleafter, '(\s*\zs.*$') + let values = s:values + else + let values = ["("] + endif + + elseif atrulename == 'charset' + let entered_atruleafter = matchstr(line, '.*@charset\s\+\zs.*$') + let values = [ + \ '"UTF-8";', '"ANSI_X3.4-1968";', '"ISO_8859-1:1987";', '"ISO_8859-2:1987";', '"ISO_8859-3:1988";', '"ISO_8859-4:1988";', '"ISO_8859-5:1988";', + \ '"ISO_8859-6:1987";', '"ISO_8859-7:1987";', '"ISO_8859-8:1988";', '"ISO_8859-9:1989";', '"ISO-8859-10";', '"ISO_6937-2-add";', '"JIS_X0201";', + \ '"JIS_Encoding";', '"Shift_JIS";', '"Extended_UNIX_Code_Packed_Format_for_Japanese";', '"Extended_UNIX_Code_Fixed_Width_for_Japanese";', + \ '"BS_4730";', '"SEN_850200_C";', '"IT";', '"ES";', '"DIN_66003";', '"NS_4551-1";', '"NF_Z_62-010";', '"ISO-10646-UTF-1";', '"ISO_646.basic:1983";', + \ '"INVARIANT";', '"ISO_646.irv:1983";', '"NATS-SEFI";', '"NATS-SEFI-ADD";', '"NATS-DANO";', '"NATS-DANO-ADD";', '"SEN_850200_B";', '"KS_C_5601-1987";', + \ '"ISO-2022-KR";', '"EUC-KR";', '"ISO-2022-JP";', '"ISO-2022-JP-2";', '"JIS_C6220-1969-jp";', '"JIS_C6220-1969-ro";', '"PT";', '"greek7-old";', + \ '"latin-greek";', '"NF_Z_62-010_(1973)";', '"Latin-greek-1";', '"ISO_5427";', '"JIS_C6226-1978";', '"BS_viewdata";', '"INIS";', '"INIS-8";', + \ '"INIS-cyrillic";', '"ISO_5427:1981";', '"ISO_5428:1980";', '"GB_1988-80";', '"GB_2312-80";', '"NS_4551-2";', '"videotex-suppl";', '"PT2";', + \ '"ES2";', '"MSZ_7795.3";', '"JIS_C6226-1983";', '"greek7";', '"ASMO_449";', '"iso-ir-90";', '"JIS_C6229-1984-a";', '"JIS_C6229-1984-b";', + \ '"JIS_C6229-1984-b-add";', '"JIS_C6229-1984-hand";', '"JIS_C6229-1984-hand-add";', '"JIS_C6229-1984-kana";', '"ISO_2033-1983";', + \ '"ANSI_X3.110-1983";', '"T.61-7bit";', '"T.61-8bit";', '"ECMA-cyrillic";', '"CSA_Z243.4-1985-1";', '"CSA_Z243.4-1985-2";', '"CSA_Z243.4-1985-gr";', + \ '"ISO_8859-6-E";', '"ISO_8859-6-I";', '"T.101-G2";', '"ISO_8859-8-E";', '"ISO_8859-8-I";', '"CSN_369103";', '"JUS_I.B1.002";', '"IEC_P27-1";', + \ '"JUS_I.B1.003-serb";', '"JUS_I.B1.003-mac";', '"greek-ccitt";', '"NC_NC00-10:81";', '"ISO_6937-2-25";', '"GOST_19768-74";', '"ISO_8859-supp";', + \ '"ISO_10367-box";', '"latin-lap";', '"JIS_X0212-1990";', '"DS_2089";', '"us-dk";', '"dk-us";', '"KSC5636";', '"UNICODE-1-1-UTF-7";', '"ISO-2022-CN";', + \ '"ISO-2022-CN-EXT";', '"ISO-8859-13";', '"ISO-8859-14";', '"ISO-8859-15";', '"ISO-8859-16";', '"GBK";', '"GB18030";', '"OSD_EBCDIC_DF04_15";', + \ '"OSD_EBCDIC_DF03_IRV";', '"OSD_EBCDIC_DF04_1";', '"ISO-11548-1";', '"KZ-1048";', '"ISO-10646-UCS-2";', '"ISO-10646-UCS-4";', '"ISO-10646-UCS-Basic";', + \ '"ISO-10646-Unicode-Latin1";', '"ISO-10646-J-1";', '"ISO-Unicode-IBM-1261";', '"ISO-Unicode-IBM-1268";', '"ISO-Unicode-IBM-1276";', + \ '"ISO-Unicode-IBM-1264";', '"ISO-Unicode-IBM-1265";', '"UNICODE-1-1";', '"SCSU";', '"UTF-7";', '"UTF-16BE";', '"UTF-16LE";', '"UTF-16";', '"CESU-8";', + \ '"UTF-32";', '"UTF-32BE";', '"UTF-32LE";', '"BOCU-1";', '"ISO-8859-1-Windows-3.0-Latin-1";', '"ISO-8859-1-Windows-3.1-Latin-1";', + \ '"ISO-8859-2-Windows-Latin-2";', '"ISO-8859-9-Windows-Latin-5";', '"hp-roman8";', '"Adobe-Standard-Encoding";', '"Ventura-US";', + \ '"Ventura-International";', '"DEC-MCS";', '"IBM850";', '"PC8-Danish-Norwegian";', '"IBM862";', '"PC8-Turkish";', '"IBM-Symbols";', '"IBM-Thai";', + \ '"HP-Legal";', '"HP-Pi-font";', '"HP-Math8";', '"Adobe-Symbol-Encoding";', '"HP-DeskTop";', '"Ventura-Math";', '"Microsoft-Publishing";', + \ '"Windows-31J";', '"GB2312";', '"Big5";', '"macintosh";', '"IBM037";', '"IBM038";', '"IBM273";', '"IBM274";', '"IBM275";', '"IBM277";', '"IBM278";', + \ '"IBM280";', '"IBM281";', '"IBM284";', '"IBM285";', '"IBM290";', '"IBM297";', '"IBM420";', '"IBM423";', '"IBM424";', '"IBM437";', '"IBM500";', '"IBM851";', + \ '"IBM852";', '"IBM855";', '"IBM857";', '"IBM860";', '"IBM861";', '"IBM863";', '"IBM864";', '"IBM865";', '"IBM868";', '"IBM869";', '"IBM870";', '"IBM871";', + \ '"IBM880";', '"IBM891";', '"IBM903";', '"IBM904";', '"IBM905";', '"IBM918";', '"IBM1026";', '"EBCDIC-AT-DE";', '"EBCDIC-AT-DE-A";', '"EBCDIC-CA-FR";', + \ '"EBCDIC-DK-NO";', '"EBCDIC-DK-NO-A";', '"EBCDIC-FI-SE";', '"EBCDIC-FI-SE-A";', '"EBCDIC-FR";', '"EBCDIC-IT";', '"EBCDIC-PT";', '"EBCDIC-ES";', + \ '"EBCDIC-ES-A";', '"EBCDIC-ES-S";', '"EBCDIC-UK";', '"EBCDIC-US";', '"UNKNOWN-8BIT";', '"MNEMONIC";', '"MNEM";', '"VISCII";', '"VIQR";', '"KOI8-R";', + \ '"HZ-GB-2312";', '"IBM866";', '"IBM775";', '"KOI8-U";', '"IBM00858";', '"IBM00924";', '"IBM01140";', '"IBM01141";', '"IBM01142";', '"IBM01143";', + \ '"IBM01144";', '"IBM01145";', '"IBM01146";', '"IBM01147";', '"IBM01148";', '"IBM01149";', '"Big5-HKSCS";', '"IBM1047";', '"PTCP154";', '"Amiga-1251";', + \ '"KOI7-switched";', '"BRF";', '"TSCII";', '"windows-1250";', '"windows-1251";', '"windows-1252";', '"windows-1253";', '"windows-1254";', '"windows-1255";', + \ '"windows-1256";', '"windows-1257";', '"windows-1258";', '"TIS-620";'] + + elseif atrulename == 'namespace' + let entered_atruleafter = matchstr(line, '.*@namespace\s\+\zs.*$') + let values = ["url("] + + elseif atrulename == 'document' + let entered_atruleafter = matchstr(line, '.*@document\s\+\zs.*$') + let values = ["url(", "url-prefix(", "domain(", "regexp("] + + elseif atrulename == 'import' + let entered_atruleafter = matchstr(line, '.*@import\s\+\zs.*$') + + 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 + let values = ['"', 'url('] + + endif + + else + return [] + + endif + + for m in values + if m =~? '^'.entered_atruleafter + if entered_atruleafter =~? '^"' && m =~? '^"' + let m = m[1:] + endif + if b:after =~? '"' && stridx(m, '"') > -1 + let m = m[0:stridx(m, '"')-1] + endif + call add(res, m) + elseif m =~? entered_atruleafter + if m =~? '^"' + let m = m[1:] + endif + call add(res2, m) + endif + endfor + + return res + res2 + + endif + + let values = ["charset", "page", "media", "import", "font-face", "namespace", "supports", "keyframes", "viewport", "document"] + + 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 [] endfunction diff --git a/runtime/autoload/health.vim b/runtime/autoload/health.vim new file mode 100644 index 0000000000..93ca4dfc54 --- /dev/null +++ b/runtime/autoload/health.vim @@ -0,0 +1,178 @@ +function! s:enhance_syntax() abort + syntax case match + + syntax keyword healthError ERROR + \ containedin=markdownCodeBlock,mkdListItemLine + highlight link healthError Error + + syntax keyword healthWarning WARNING + \ containedin=markdownCodeBlock,mkdListItemLine + highlight link healthWarning WarningMsg + + syntax keyword healthInfo INFO + \ containedin=markdownCodeBlock,mkdListItemLine + highlight link healthInfo ModeMsg + + syntax keyword healthSuccess SUCCESS + \ containedin=markdownCodeBlock,mkdListItemLine + highlight link healthSuccess ModeMsg + + syntax keyword healthSuggestion SUGGESTIONS + \ containedin=markdownCodeBlock,mkdListItemLine + highlight link healthSuggestion String + + syntax match healthHelp "|.\{-}|" contains=healthBar + \ containedin=markdownCodeBlock,mkdListItemLine + syntax match healthBar "|" contained conceal + highlight link healthHelp Identifier + + " We do not care about markdown syntax errors in :CheckHealth output. + highlight! link markdownError Normal +endfunction + +" Runs the specified healthchecks. +" Runs all discovered healthchecks if a:plugin_names is empty. +function! health#check(plugin_names) abort + let healthchecks = empty(a:plugin_names) + \ ? s:discover_health_checks() + \ : s:to_fn_names(a:plugin_names) + + tabnew + setlocal wrap breakindent + setlocal filetype=markdown + setlocal conceallevel=2 concealcursor=nc + setlocal keywordprg=:help + call s:enhance_syntax() + + if empty(healthchecks) + call setline(1, 'ERROR: No healthchecks found.') + else + redraw|echo 'Running healthchecks...' + for c in healthchecks + let output = '' + call append('$', split(printf("\n%s\n%s", c, repeat('=',72)), "\n")) + try + let output = "\n\n".execute('call '.c.'()') + catch + if v:exception =~# '^Vim\%((\a\+)\)\=:E117.*\V'.c + let output = execute( + \ 'call health#report_error(''No healthcheck found for "' + \ .s:to_plugin_name(c) + \ .'" plugin.'')') + else + let output = execute( + \ 'call health#report_error(''Failed to run healthcheck for "' + \ .s:to_plugin_name(c) + \ .'" plugin. Exception:''."\n".v:throwpoint."\n".v:exception)') + endif + endtry + call append('$', split(output, "\n") + ['']) + redraw + endfor + endif + + " needed for plasticboy/vim-markdown, because it uses fdm=expr + normal! zR + setlocal nomodified + redraw|echo '' +endfunction + +" Starts a new report. +function! health#report_start(name) abort + echo "\n## " . a:name +endfunction + +" Indents lines *except* line 1 of a string if it contains newlines. +function! s:indent_after_line1(s, columns) abort + let lines = split(a:s, "\n", 0) + if len(lines) < 2 " We do not indent line 1, so nothing to do. + return a:s + endif + for i in range(1, len(lines)-1) " Indent lines after the first. + let lines[i] = substitute(lines[i], '^\s*', repeat(' ', a:columns), 'g') + endfor + return join(lines, "\n") +endfunction + +" Changes ':h clipboard' to ':help |clipboard|'. +function! s:help_to_link(s) abort + return substitute(a:s, '\v[''"]?:h%[elp] ([^''"]+)[''"]?', '":help |\1|"', 'g') +endfunction + +" Format a message for a specific report item +function! s:format_report_message(status, msg, ...) abort " {{{ + let output = ' - ' . a:status . ': ' . s:indent_after_line1(a:msg, 4) + let suggestions = [] + + " Optional parameters + if a:0 > 0 + let suggestions = type(a:1) == type("") ? [a:1] : a:1 + if type(suggestions) != type([]) + echoerr "Expected String or List" + endif + endif + + " Report each suggestion + if len(suggestions) > 0 + let output .= "\n - SUGGESTIONS:" + endif + for suggestion in suggestions + let output .= "\n - " . s:indent_after_line1(suggestion, 10) + endfor + + return s:help_to_link(output) +endfunction " }}} + +" Use {msg} to report information in the current section +function! health#report_info(msg) abort " {{{ + echo s:format_report_message('INFO', a:msg) +endfunction " }}} + +" Reports a successful healthcheck. +function! health#report_ok(msg) abort " {{{ + echo s:format_report_message('SUCCESS', a:msg) +endfunction " }}} + +" Reports a health warning. +function! health#report_warn(msg, ...) abort " {{{ + if a:0 > 0 + echo s:format_report_message('WARNING', a:msg, a:1) + else + echo s:format_report_message('WARNING', a:msg) + endif +endfunction " }}} + +" Reports a failed healthcheck. +function! health#report_error(msg, ...) abort " {{{ + if a:0 > 0 + echo s:format_report_message('ERROR', a:msg, a:1) + else + echo s:format_report_message('ERROR', a:msg) + endif +endfunction " }}} + +function! s:filepath_to_function(name) abort + return substitute(substitute(substitute(a:name, '.*autoload[\/]', '', ''), + \ '\.vim', '#check', ''), '[\/]', '#', 'g') +endfunction + +function! s:discover_health_checks() abort + let healthchecks = globpath(&runtimepath, 'autoload/health/*.vim', 1, 1) + let healthchecks = map(healthchecks, '<SID>filepath_to_function(v:val)') + return healthchecks +endfunction + +" Translates a list of plugin names to healthcheck function names. +function! s:to_fn_names(plugin_names) abort + let healthchecks = [] + for p in a:plugin_names + call add(healthchecks, 'health#'.p.'#check') + endfor + return healthchecks +endfunction + +" Extracts 'foo' from 'health#foo#check'. +function! s:to_plugin_name(fn_name) abort + return substitute(a:fn_name, + \ '\v.*health\#(.+)\#check.*', '\1', '') +endfunction diff --git a/runtime/autoload/health/nvim.vim b/runtime/autoload/health/nvim.vim new file mode 100644 index 0000000000..e2ad9f7ccb --- /dev/null +++ b/runtime/autoload/health/nvim.vim @@ -0,0 +1,152 @@ +let s:suggest_faq = 'See https://github.com/neovim/neovim/wiki/FAQ' + +function! s:check_config() abort + call health#report_start('Configuration') + if !get(g:, 'loaded_sensible', 0) + call health#report_ok('no issues found') + else + let sensible_pi = globpath(&runtimepath, '**/sensible.vim', 1, 1) + call health#report_info("found sensible.vim plugin:\n".join(sensible_pi, "\n")) + call health#report_error("sensible.vim plugin is not needed; Nvim has the same defaults built-in." + \ ." Also, sensible.vim sets 'ttimeoutlen' to a sub-optimal value.", + \ ["Remove sensible.vim plugin, or wrap it in a `if !has('nvim')` check."]) + endif +endfunction + +" Load the remote plugin manifest file and check for unregistered plugins +function! s:check_rplugin_manifest() abort + call health#report_start('Remote Plugins') + let existing_rplugins = {} + + for item in remote#host#PluginsForHost('python') + let existing_rplugins[item.path] = 'python' + endfor + + for item in remote#host#PluginsForHost('python3') + let existing_rplugins[item.path] = 'python3' + endfor + + let require_update = 0 + + for path in map(split(&runtimepath, ','), 'resolve(v:val)') + let python_glob = glob(path.'/rplugin/python*', 1, 1) + if empty(python_glob) + continue + endif + + let python_dir = python_glob[0] + let python_version = fnamemodify(python_dir, ':t') + + for script in glob(python_dir.'/*.py', 1, 1) + \ + glob(python_dir.'/*/__init__.py', 1, 1) + let contents = join(readfile(script)) + if contents =~# '\<\%(from\|import\)\s\+neovim\>' + if script =~# '[\/]__init__\.py$' + let script = fnamemodify(script, ':h') + endif + + if !has_key(existing_rplugins, script) + let msg = printf('"%s" is not registered.', fnamemodify(path, ':t')) + if python_version ==# 'pythonx' + if !has('python2') && !has('python3') + let msg .= ' (python2 and python3 not available)' + endif + elseif !has(python_version) + let msg .= printf(' (%s not available)', python_version) + else + let require_update = 1 + endif + + call health#report_warn(msg) + endif + + break + endif + endfor + endfor + + if require_update + call health#report_warn('Out of date', ['Run `:UpdateRemotePlugins`']) + else + call health#report_ok('Up to date') + endif +endfunction + +function! s:check_performance() abort + call health#report_start('Performance') + + " check buildtype + let buildtype = matchstr(execute('version'), '\v\cbuild type:?\s*[^\n\r\t ]+') + if empty(buildtype) + call health#report_error('failed to get build type from :version') + elseif buildtype =~# '\v(MinSizeRel|Release|RelWithDebInfo)' + call health#report_ok(buildtype) + else + call health#report_info(buildtype) + call health#report_warn( + \ "Non-optimized build-type. Nvim will be slower.", + \ ["Install a different Nvim package, or rebuild with `CMAKE_BUILD_TYPE=RelWithDebInfo`.", + \ s:suggest_faq]) + endif +endfunction + +function! s:check_tmux() abort + if empty($TMUX) || !executable('tmux') + return + endif + call health#report_start('tmux') + + " check escape-time + let suggestions = ["Set escape-time in ~/.tmux.conf:\nset-option -sg escape-time 10", + \ s:suggest_faq] + let cmd = 'tmux show-option -qvgs escape-time' + let out = system(cmd) + let tmux_esc_time = substitute(out, '\v(\s|\r|\n)', '', 'g') + if v:shell_error + call health#report_error('command failed: '.cmd."\n".out) + elseif empty(tmux_esc_time) + call health#report_error('escape-time is not set', suggestions) + elseif tmux_esc_time > 300 + call health#report_error( + \ 'escape-time ('.tmux_esc_time.') is higher than 300ms', suggestions) + else + call health#report_ok('escape-time: '.tmux_esc_time.'ms') + endif + + " check $TERM + call health#report_info('$TERM: '.$TERM) + if $TERM !~# '\v(tmux-256color|screen-256color)' + call health#report_error( + \ '$TERM should be "screen-256color" or "tmux-256color" when running tmux.', + \ ["Set default-terminal in ~/.tmux.conf:\nset-option -g default-terminal \"screen-256color\"", + \ s:suggest_faq]) + endif +endfunction + +function! s:check_terminal() abort + if !executable('infocmp') + return + endif + call health#report_start('terminal') + let cmd = 'infocmp -L' + let out = system(cmd) + let kbs_entry = matchstr(out, 'key_backspace=[^,[:space:]]*') + let kdch1_entry = matchstr(out, 'key_dc=[^,[:space:]]*') + + if v:shell_error + call health#report_error('command failed: '.cmd."\n".out) + else + call health#report_info('key_backspace (kbs) terminfo entry: ' + \ .(empty(kbs_entry) ? '? (not found)' : kbs_entry)) + call health#report_info('key_dc (kdch1) terminfo entry: ' + \ .(empty(kbs_entry) ? '? (not found)' : kdch1_entry)) + endif +endfunction + +function! health#nvim#check() abort + call s:check_config() + call s:check_performance() + call s:check_rplugin_manifest() + call s:check_terminal() + call s:check_tmux() +endfunction diff --git a/runtime/autoload/health/provider.vim b/runtime/autoload/health/provider.vim new file mode 100644 index 0000000000..417426c101 --- /dev/null +++ b/runtime/autoload/health/provider.vim @@ -0,0 +1,461 @@ +let s:shell_error = 0 + +function! s:is_bad_response(s) abort + return a:s =~? '\v(^unable)|(^error)|(^outdated)' +endfunction + +function! s:trim(s) abort + return substitute(a:s, '^\_s*\|\_s*$', '', 'g') +endfunction + +" Simple version comparison. +function! s:version_cmp(a, b) abort + let a = split(a:a, '\.', 0) + let b = split(a:b, '\.', 0) + + for i in range(len(a)) + if str2nr(a[i]) > str2nr(b[i]) + return 1 + elseif str2nr(a[i]) < str2nr(b[i]) + return -1 + endif + endfor + + return 0 +endfunction + +" Handler for s:system() function. +function! s:system_handler(jobid, data, event) dict abort + if a:event == 'stdout' || a:event == 'stderr' + let self.output .= join(a:data, '') + elseif a:event == 'exit' + let s:shell_error = a:data + endif +endfunction + +" Run a system command and timeout after 30 seconds. +function! s:system(cmd, ...) abort + let stdin = a:0 ? a:1 : '' + let ignore_stderr = a:0 > 1 ? a:2 : 0 + let ignore_error = a:0 > 2 ? a:3 : 0 + let opts = { + \ 'output': '', + \ 'on_stdout': function('s:system_handler'), + \ 'on_exit': function('s:system_handler'), + \ } + if !ignore_stderr + let opts.on_stderr = function('s:system_handler') + endif + let jobid = jobstart(a:cmd, opts) + + if jobid < 1 + call health#report_error(printf('Command error %d: %s', jobid, + \ type(a:cmd) == type([]) ? join(a:cmd) : a:cmd))) + let s:shell_error = 1 + return opts.output + endif + + if !empty(stdin) + call jobsend(jobid, stdin) + endif + + let res = jobwait([jobid], 30000) + if res[0] == -1 + call health#report_error(printf('Command timed out: %s', + \ type(a:cmd) == type([]) ? join(a:cmd) : a:cmd)) + call jobstop(jobid) + elseif s:shell_error != 0 && !ignore_error + call health#report_error(printf("Command error (%d) %s: %s", jobid, + \ type(a:cmd) == type([]) ? join(a:cmd) : a:cmd, + \ opts.output)) + endif + + return opts.output +endfunction + +function! s:systemlist(cmd, ...) abort + let stdout = split(s:system(a:cmd, a:0 ? a:1 : ''), "\n") + if a:0 > 1 && !empty(a:2) + return filter(stdout, '!empty(v:val)') + endif + return stdout +endfunction + +" Fetch the contents of a URL. +function! s:download(url) abort + if executable('curl') + let rv = s:system(['curl', '-sL', a:url], '', 1, 1) + return s:shell_error ? 'curl error with '.a:url.': '.s:shell_error : rv + elseif executable('python') + let script = " + \try:\n + \ from urllib.request import urlopen\n + \except ImportError:\n + \ from urllib2 import urlopen\n + \\n + \response = urlopen('".a:url."')\n + \print(response.read().decode('utf8'))\n + \" + let rv = s:system(['python', '-c', script]) + return empty(rv) && s:shell_error + \ ? 'python urllib.request error: '.s:shell_error + \ : rv + endif + return 'missing `curl` and `python`, cannot make pypi request' +endfunction + +" Check for clipboard tools. +function! s:check_clipboard() abort + call health#report_start('Clipboard') + + let clipboard_tool = provider#clipboard#Executable() + if empty(clipboard_tool) + call health#report_warn( + \ "No clipboard tool found. Clipboard registers will not work.", + \ ['See ":help clipboard".']) + else + call health#report_ok('Clipboard tool found: '. clipboard_tool) + endif +endfunction + +" Get the latest Neovim Python client version from PyPI. +function! s:latest_pypi_version() abort + let pypi_version = 'unable to get pypi response' + let pypi_response = s:download('https://pypi.python.org/pypi/neovim/json') + if !empty(pypi_response) + try + let pypi_data = json_decode(pypi_response) + catch /E474/ + return 'error: '.pypi_response + endtry + let pypi_version = get(get(pypi_data, 'info', {}), 'version', 'unable to parse') + endif + return pypi_version +endfunction + +" Get version information using the specified interpreter. The interpreter is +" used directly in case breaking changes were introduced since the last time +" Neovim's Python client was updated. +" +" Returns: [ +" {python executable version}, +" {current nvim version}, +" {current pypi nvim status}, +" {installed version status} +" ] +function! s:version_info(python) abort + let pypi_version = s:latest_pypi_version() + let python_version = s:trim(s:system([ + \ a:python, + \ '-c', + \ 'import sys; print(".".join(str(x) for x in sys.version_info[:3]))', + \ ])) + + if empty(python_version) + let python_version = 'unable to parse python response' + endif + + let nvim_path = s:trim(s:system([ + \ a:python, '-c', 'import neovim; print(neovim.__file__)'])) + if s:shell_error || empty(nvim_path) + return [python_version, 'unable to load neovim Python module', pypi_version, + \ nvim_path] + endif + + " Assuming that multiple versions of a package are installed, sort them + " numerically in descending order. + function! s:compare(metapath1, metapath2) + let a = matchstr(fnamemodify(a:metapath1, ':p:h:t'), '[0-9.]\+') + let b = matchstr(fnamemodify(a:metapath2, ':p:h:t'), '[0-9.]\+') + return a == b ? 0 : a > b ? 1 : -1 + endfunction + + " Try to get neovim.VERSION (added in 0.1.11dev). + let nvim_version = s:system(['python', '-c', + \ 'from neovim import VERSION as v; '. + \ 'print("{}.{}.{}{}".format(v.major, v.minor, v.patch, v.prerelease))'], + \ '', 1, 1) + if empty(nvim_version) + let nvim_version = 'unable to find neovim Python module version' + let base = fnamemodify(nvim_path, ':h') + let metas = glob(base.'-*/METADATA', 1, 1) + \ + glob(base.'-*/PKG-INFO', 1, 1) + \ + glob(base.'.egg-info/PKG-INFO', 1, 1) + let metas = sort(metas, 's:compare') + + if !empty(metas) + for meta_line in readfile(metas[0]) + if meta_line =~# '^Version:' + let nvim_version = matchstr(meta_line, '^Version: \zs\S\+') + break + endif + endfor + endif + endif + + let nvim_path_base = fnamemodify(nvim_path, ':~:h') + let version_status = 'unknown; '.nvim_path_base + if !s:is_bad_response(nvim_version) && !s:is_bad_response(pypi_version) + if s:version_cmp(nvim_version, pypi_version) == -1 + let version_status = 'outdated; from '.nvim_path_base + else + let version_status = 'up to date' + endif + endif + + return [python_version, nvim_version, pypi_version, version_status] +endfunction + +" Check the Python interpreter's usability. +function! s:check_bin(bin) abort + if !filereadable(a:bin) + call health#report_error(printf('"%s" was not found.', a:bin)) + return 0 + elseif executable(a:bin) != 1 + call health#report_error(printf('"%s" is not executable.', a:bin)) + return 0 + endif + return 1 +endfunction + +function! s:check_python(version) abort + call health#report_start('Python ' . a:version . ' provider') + + let python_bin_name = 'python'.(a:version == 2 ? '' : '3') + let pyenv = resolve(exepath('pyenv')) + let pyenv_root = exists('$PYENV_ROOT') ? resolve($PYENV_ROOT) : 'n' + let venv = exists('$VIRTUAL_ENV') ? resolve($VIRTUAL_ENV) : '' + let host_prog_var = python_bin_name.'_host_prog' + let python_bin = '' + let python_multiple = [] + + if exists('g:'.host_prog_var) + call health#report_info(printf('Using: g:%s = "%s"', host_prog_var, get(g:, host_prog_var))) + endif + + let [python_bin_name, pythonx_errs] = provider#pythonx#Detect(a:version) + if empty(python_bin_name) + call health#report_warn('No Python interpreter was found with the neovim ' + \ . 'module. Using the first available for diagnostics.') + if !empty(pythonx_errs) + call health#report_warn(pythonx_errs) + endif + endif + + if !empty(python_bin_name) + if exists('g:'.host_prog_var) + let python_bin = exepath(python_bin_name) + endif + let python_bin_name = fnamemodify(python_bin_name, ':t') + endif + + if !empty(pythonx_errs) + call health#report_error('Python provider error', pythonx_errs) + endif + + if !empty(python_bin_name) && empty(python_bin) && empty(pythonx_errs) + if !exists('g:'.host_prog_var) + call health#report_info(printf('`g:%s` is not set. Searching for ' + \ . '%s in the environment.', host_prog_var, python_bin_name)) + endif + + if !empty(pyenv) + if empty(pyenv_root) + call health#report_warn( + \ 'pyenv was found, but $PYENV_ROOT is not set.', + \ ['Did you follow the final install instructions?'] + \ ) + else + call health#report_ok(printf('pyenv found: "%s"', pyenv)) + endif + + let python_bin = s:trim(s:system([pyenv, 'which', python_bin_name], '', 1)) + + if empty(python_bin) + call health#report_warn(printf('pyenv could not find %s.', python_bin_name)) + endif + endif + + if empty(python_bin) + let python_bin = exepath(python_bin_name) + + if exists('$PATH') + for path in split($PATH, ':') + let path_bin = path.'/'.python_bin_name + if path_bin != python_bin && index(python_multiple, path_bin) == -1 + \ && executable(path_bin) + call add(python_multiple, path_bin) + endif + endfor + + if len(python_multiple) + " This is worth noting since the user may install something + " that changes $PATH, like homebrew. + call health#report_info(printf('Multiple %s executables found. ' + \ . 'Set `g:%s` to avoid surprises.', python_bin_name, host_prog_var)) + endif + + if python_bin =~# '\<shims\>' + call health#report_warn(printf('`%s` appears to be a pyenv shim.', python_bin), [ + \ 'The `pyenv` executable is not in $PATH,', + \ 'Your pyenv installation is broken. You should set ' + \ . '`g:'.host_prog_var.'` to avoid surprises.', + \ ]) + endif + endif + endif + endif + + if !empty(python_bin) + if empty(venv) && !empty(pyenv) && !exists('g:'.host_prog_var) + \ && !empty(pyenv_root) && resolve(python_bin) !~# '^'.pyenv_root.'/' + call health#report_warn('pyenv is not set up optimally.', [ + \ printf('Create a virtualenv specifically ' + \ . 'for Neovim using pyenv, and set `g:%s`. This will avoid ' + \ . 'the need to install Neovim''s Python module in each ' + \ . 'version/virtualenv.', host_prog_var) + \ ]) + elseif !empty(venv) && exists('g:'.host_prog_var) + if !empty(pyenv_root) + let venv_root = pyenv_root + else + let venv_root = fnamemodify(venv, ':h') + endif + + if resolve(python_bin) !~# '^'.venv_root.'/' + call health#report_warn('Your virtualenv is not set up optimally.', [ + \ printf('Create a virtualenv specifically ' + \ . 'for Neovim and use `g:%s`. This will avoid ' + \ . 'the need to install Neovim''s Python module in each ' + \ . 'virtualenv.', host_prog_var) + \ ]) + endif + endif + endif + + if empty(python_bin) && !empty(python_bin_name) + " An error message should have already printed. + call health#report_error(printf('`%s` was not found.', python_bin_name)) + elseif !empty(python_bin) && !s:check_bin(python_bin) + let python_bin = '' + endif + + " Check if $VIRTUAL_ENV is active + let virtualenv_inactive = 0 + + if exists('$VIRTUAL_ENV') + if !empty(pyenv) + let pyenv_prefix = resolve(s:trim(s:system([pyenv, 'prefix']))) + if $VIRTUAL_ENV != pyenv_prefix + let virtualenv_inactive = 1 + endif + elseif !empty(python_bin_name) && exepath(python_bin_name) !~# '^'.$VIRTUAL_ENV.'/' + let virtualenv_inactive = 1 + endif + endif + + if virtualenv_inactive + call health#report_warn( + \ '$VIRTUAL_ENV exists but appears to be inactive. ' + \ . 'This could lead to unexpected results.', + \ [ 'If you are using Zsh, see: http://vi.stackexchange.com/a/7654/5229' ]) + endif + + " Diagnostic output + call health#report_info('Executable: ' . (empty(python_bin) ? 'Not found' : python_bin)) + if len(python_multiple) + for path_bin in python_multiple + call health#report_info('Other python executable: ' . path_bin) + endfor + endif + + if !empty(python_bin) + let [pyversion, current, latest, status] = s:version_info(python_bin) + if a:version != str2nr(pyversion) + call health#report_warn('Unexpected Python version.' . + \ ' This could lead to confusing error messages.') + endif + if a:version == 3 && str2float(pyversion) < 3.3 + call health#report_warn('Python 3.3+ is recommended.') + endif + + call health#report_info('Python'.a:version.' version: ' . pyversion) + if s:is_bad_response(status) + call health#report_info(printf('%s-neovim version: %s (%s)', python_bin_name, current, status)) + else + call health#report_info(printf('%s-neovim version: %s', python_bin_name, current)) + endif + + if s:is_bad_response(current) + call health#report_error( + \ "Neovim Python client is not installed.\nError: ".current, + \ ['Run in shell: pip' . a:version . ' install neovim']) + endif + + if s:is_bad_response(latest) + call health#report_warn('Could not contact PyPI to get latest version.') + call health#report_error('HTTP request failed: '.latest) + elseif s:is_bad_response(status) + call health#report_warn(printf('Latest %s-neovim is NOT installed: %s', + \ python_bin_name, latest)) + elseif !s:is_bad_response(current) + call health#report_ok(printf('Latest %s-neovim is installed: %s', + \ python_bin_name, latest)) + endif + endif + +endfunction + +function! s:check_ruby() abort + call health#report_start('Ruby provider') + + if !executable('ruby') || !executable('gem') + call health#report_warn( + \ "`ruby` and `gem` must be in $PATH.", + \ ["Install Ruby and verify that `ruby` and `gem` commands work."]) + return + endif + call health#report_info('Ruby: '. s:system('ruby -v')) + + let host = provider#ruby#Detect() + if empty(host) + call health#report_warn('Missing "neovim" gem.', + \ ['Run in shell: gem install neovim']) + return + endif + call health#report_info('Host: '. host) + + let latest_gem_cmd = 'gem list -ra ^neovim$' + let latest_gem = s:system(split(latest_gem_cmd)) + if s:shell_error || empty(latest_gem) + call health#report_error('Failed to run: '. latest_gem_cmd, + \ ["Make sure you're connected to the internet.", + \ "Are you behind a firewall or proxy?"]) + return + endif + let latest_gem = get(split(latest_gem, ' (\|, \|)$' ), 1, 'not found') + + let current_gem_cmd = host .' --version' + let current_gem = s:system(current_gem_cmd) + if s:shell_error + call health#report_error('Failed to run: '. current_gem_cmd, + \ ["Report this issue with the output of: ", current_gem_cmd]) + return + endif + + if s:version_cmp(current_gem, latest_gem) == -1 + call health#report_warn( + \ printf('Gem "neovim" is out-of-date. Installed: %s, latest: %s', + \ current_gem, latest_gem), + \ ['Run in shell: gem update neovim']) + else + call health#report_ok('Gem "neovim" is up-to-date: '. current_gem) + endif +endfunction + +function! health#provider#check() abort + call s:check_clipboard() + call s:check_python(2) + call s:check_python(3) + call s:check_ruby() +endfunction diff --git a/runtime/autoload/man.vim b/runtime/autoload/man.vim index 0dfcc424e2..a6be00c0a9 100644 --- a/runtime/autoload/man.vim +++ b/runtime/autoload/man.vim @@ -1,137 +1,338 @@ -let s:man_tag_depth = 0 -let s:man_sect_arg = '' -let s:man_find_arg = '-w' +" Maintainer: Anmol Sethi <anmol@aubble.com> +let s:man_find_arg = "-w" + +" TODO(nhooyr) Completion may work on SunOS; I'm not sure if `man -l` displays +" the list of searched directories. try - if !has('win32') && $OSTYPE !~? 'cygwin\|linux' && system('uname -s') =~? 'SunOS' && system('uname -r') =~? '^5' - let s:man_sect_arg = '-s' + if !has('win32') && $OSTYPE !~? 'cygwin\|linux' && system('uname -s') =~? 'SunOS' && system('uname -r') =~# '^5' let s:man_find_arg = '-l' endif catch /E145:/ " Ignore the error in restricted mode endtry -" Load man page {page} from {section} -" call man#get_page([{section}, ]{page}) -function man#get_page(...) abort - let invoked_from_man = (&filetype ==# 'man') - - if a:0 == 0 - echoerr 'argument required' - return - elseif a:0 > 2 - echoerr 'too many arguments' +function! man#open_page(count, count1, mods, ...) abort + if a:0 > 2 + call s:error('too many arguments') return + elseif a:0 == 0 + let ref = &filetype ==# 'man' ? expand('<cWORD>') : expand('<cword>') + if empty(ref) + call s:error('no identifier under cursor') + return + endif + elseif a:0 ==# 1 + let ref = a:1 + else + " Combine the name and sect into a manpage reference so that all + " verification/extraction can be kept in a single function. + " If a:2 is a reference as well, that is fine because it is the only + " reference that will match. + let ref = a:2.'('.a:1.')' endif + try + let [sect, name] = man#extract_sect_and_name_ref(ref) + if a:count ==# a:count1 + " v:count defaults to 0 which is a valid section, and v:count1 defaults to + " 1, also a valid section. If they are equal, count explicitly set. + let sect = string(a:count) + endif + let [sect, name, path] = s:verify_exists(sect, name) + catch + call s:error(v:exception) + return + endtry - let sect = get(a:000, 0) - let page = get(a:000, 1, sect) + call s:push_tag() + let bufname = 'man://'.name.(empty(sect)?'':'('.sect.')') + if a:mods !~# 'tab' && s:find_man() + noautocmd execute 'silent edit' fnameescape(bufname) + else + noautocmd execute 'silent' a:mods 'split' fnameescape(bufname) + endif - let [page, sect] = s:parse_page_and_section(sect, page) + try + let page = s:get_page(path) + catch + close + call s:error(v:exception) + return + endtry - if !empty(sect) && s:find_page(sect, page) == 0 - let sect = '' - endif + let b:man_sect = sect + call s:put_page(page) +endfunction - if s:find_page(sect, page) == 0 - echo 'No manual entry for '.page +function! man#read_page(ref) abort + try + let [sect, name] = man#extract_sect_and_name_ref(a:ref) + let [b:man_sect, name, path] = s:verify_exists(sect, name) + let page = s:get_page(path) + catch + " call to s:error() is unnecessary return + endtry + call s:put_page(page) +endfunction + +" Handler for s:system() function. +function! s:system_handler(jobid, data, event) dict abort + if a:event == 'stdout' + let self.stdout .= join(a:data, "\n") + elseif a:event == 'stderr' + let self.stderr .= join(a:data, "\n") + else + let self.exit_code = a:data endif +endfunction - exec 'let s:man_tag_buf_'.s:man_tag_depth.' = '.bufnr('%') - exec 'let s:man_tag_lin_'.s:man_tag_depth.' = '.line('.') - exec 'let s:man_tag_col_'.s:man_tag_depth.' = '.col('.') - let s:man_tag_depth = s:man_tag_depth + 1 - - let editcmd = 'edit' - " Use an existing 'man' window, else open a new one. - if &filetype !=# 'man' - let thiswin = winnr() - wincmd b - if winnr() > 1 - exec thiswin . 'wincmd w' - while 1 - if &filetype ==# 'man' - break - endif - wincmd w - if thiswin == winnr() - break - endif - endwhile - endif +" Run a system command and timeout after 30 seconds. +function! s:system(cmd, ...) abort + let opts = { + \ 'stdout': '', + \ 'stderr': '', + \ 'exit_code': 0, + \ 'on_stdout': function('s:system_handler'), + \ 'on_stderr': function('s:system_handler'), + \ 'on_exit': function('s:system_handler'), + \ } + let jobid = jobstart(a:cmd, opts) - if &filetype !=# 'man' - let editcmd = 'tabnew' - endif + if jobid < 1 + throw printf('command error %d: %s', jobid, join(a:cmd)) + endif + + let res = jobwait([jobid], 30000) + if res[0] == -1 + try + call jobstop(jobid) + throw printf('command timed out: %s', join(a:cmd)) + catch /^Vim\%((\a\+)\)\=:E900/ + endtry + elseif res[0] == -2 + throw printf('command interrupted: %s', join(a:cmd)) + endif + if opts.exit_code != 0 + throw printf("command error (%d) %s: %s", jobid, join(a:cmd), substitute(opts.stderr, '\_s\+$', '', &gdefault ? '' : 'g')) endif - silent exec editcmd.' man://'.page.(empty(sect)?'':'('.sect.')') + return opts.stdout +endfunction +function! s:get_page(path) abort + " Respect $MANWIDTH or default to window width. + let manwidth = empty($MANWIDTH) ? winwidth(0) : $MANWIDTH + " Force MANPAGER=cat to ensure Vim is not recursively invoked (by man-db). + " http://comments.gmane.org/gmane.editors.vim.devel/29085 + return s:system(['env', 'MANPAGER=cat', 'MANWIDTH='.manwidth, 'man', a:path]) +endfunction + +function! s:put_page(page) abort setlocal modifiable - silent keepjumps norm! 1G"_dG - if empty($MANWIDTH) - let $MANWIDTH = winwidth(0) - endif - silent exec 'r!/usr/bin/man '.s:cmd(sect, page).' | col -b' - " Remove blank lines from top and bottom. + setlocal noreadonly + silent keepjumps %delete _ + silent put =a:page + " Remove all backspaced/escape characters. + execute 'silent keeppatterns keepjumps %substitute,.\b\|\e\[\d\+m,,e'.(&gdefault?'':'g') while getline(1) =~# '^\s*$' silent keepjumps 1delete _ endwhile - while getline('$') =~# '^\s*$' - silent keepjumps $delete _ - endwhile - setlocal nomodified setlocal filetype=man +endfunction + +" attempt to extract the name and sect out of 'name(sect)' +" otherwise just return the largest string of valid characters in ref +function! man#extract_sect_and_name_ref(ref) abort + if a:ref[0] ==# '-' " try ':Man -pandoc' with this disabled. + throw 'manpage name cannot start with ''-''' + endif + let ref = matchstr(a:ref, '[^()]\+([^()]\+)') + if empty(ref) + let name = matchstr(a:ref, '[^()]\+') + if empty(name) + throw 'manpage reference cannot contain only parentheses' + endif + return [get(b:, 'man_default_sects', ''), name] + endif + let left = split(ref, '(') + " see ':Man 3X curses' on why tolower. + " TODO(nhooyr) Not sure if this is portable across OSs + " but I have not seen a single uppercase section. + return [tolower(split(left[1], ')')[0]), left[0]] +endfunction - if invoked_from_man || editcmd ==# 'tabnew' - call s:set_window_local_options() +function! s:get_path(sect, name) abort + if empty(a:sect) + return s:system(['man', s:man_find_arg, a:name]) endif + " '-s' flag handles: + " - tokens like 'printf(echo)' + " - sections starting with '-' + " - 3pcap section (found on macOS) + " - commas between sections (for section priority) + return s:system(['man', s:man_find_arg, '-s', a:sect, a:name]) endfunction -function s:set_window_local_options() abort - setlocal colorcolumn=0 foldcolumn=0 nonumber - setlocal nolist norelativenumber nofoldenable +function! s:verify_exists(sect, name) abort + let path = s:get_path(a:sect, a:name) + if path !~# '^\/' + let path = s:get_path(get(b:, 'man_default_sects', ''), a:name) + if path !~# '^\/' + let path = s:get_path('', a:name) + endif + endif + " We need to extract the section from the path because sometimes + " the actual section of the manpage is more specific than the section + " we provided to `man`. Try ':Man 3 App::CLI'. + " Also on linux, it seems that the name is case insensitive. So if one does + " ':Man PRIntf', we still want the name of the buffer to be 'printf' or + " whatever the correct capitilization is. + let path = path[:len(path)-2] + return s:extract_sect_and_name_path(path) + [path] endfunction -function man#pop_page() abort - if s:man_tag_depth > 0 - let s:man_tag_depth = s:man_tag_depth - 1 - exec "let s:man_tag_buf=s:man_tag_buf_".s:man_tag_depth - exec "let s:man_tag_lin=s:man_tag_lin_".s:man_tag_depth - exec "let s:man_tag_col=s:man_tag_col_".s:man_tag_depth - exec s:man_tag_buf."b" - exec s:man_tag_lin - exec "norm! ".s:man_tag_col."|" - exec "unlet s:man_tag_buf_".s:man_tag_depth - exec "unlet s:man_tag_lin_".s:man_tag_depth - exec "unlet s:man_tag_col_".s:man_tag_depth - unlet s:man_tag_buf s:man_tag_lin s:man_tag_col +let s:tag_stack = [] + +function! s:push_tag() abort + let s:tag_stack += [{ + \ 'buf': bufnr('%'), + \ 'lnum': line('.'), + \ 'col': col('.'), + \ }] +endfunction + +function! man#pop_tag() abort + if !empty(s:tag_stack) + let tag = remove(s:tag_stack, -1) + execute 'silent' tag['buf'].'buffer' + call cursor(tag['lnum'], tag['col']) endif endfunction -" Expects a string like 'access' or 'access(2)'. -function s:parse_page_and_section(sect, str) abort - try - let [page, sect] = matchlist(a:str, '\v\C([-.[:alnum:]_]+)%(\(([-.[:alnum:]_]+)\))?')[1:2] - if empty(sect) - let sect = a:sect +" extracts the name and sect out of 'path/name.sect' +function! s:extract_sect_and_name_path(path) abort + let tail = fnamemodify(a:path, ':t') + if a:path =~# '\.\%([glx]z\|bz2\|lzma\|Z\)$' " valid extensions + let tail = fnamemodify(tail, ':r') + endif + let sect = matchstr(tail, '\.\zs[^.]\+$') + let name = matchstr(tail, '^.\+\ze\.') + return [sect, name] +endfunction + +function! s:find_man() abort + if &filetype ==# 'man' + return 1 + elseif winnr('$') ==# 1 + return 0 + endif + let thiswin = winnr() + while 1 + wincmd w + if &filetype ==# 'man' + return 1 + elseif thiswin ==# winnr() + return 0 + endif + endwhile +endfunction + +function! s:error(msg) abort + redraw + echohl ErrorMsg + echon 'man.vim: ' a:msg + echohl None +endfunction + +" see man#extract_sect_and_name_ref on why tolower(sect) +function! man#complete(arg_lead, cmd_line, cursor_pos) abort + let args = split(a:cmd_line) + let l = len(args) + if l > 3 + return + elseif l ==# 1 + let name = '' + let sect = '' + elseif a:arg_lead =~# '^[^()]\+([^()]*$' + " cursor (|) is at ':Man printf(|' or ':Man 1 printf(|' + " The later is is allowed because of ':Man pri<TAB>'. + " It will offer 'priclass.d(1m)' even though section is specified as 1. + let tmp = split(a:arg_lead, '(') + let name = tmp[0] + let sect = tolower(get(tmp, 1, '')) + return s:complete(sect, '', name) + elseif args[1] !~# '^[^()]\+$' + " cursor (|) is at ':Man 3() |' or ':Man (3|' or ':Man 3() pri|' + " or ':Man 3() pri |' + return + elseif l ==# 2 + if empty(a:arg_lead) + " cursor (|) is at ':Man 1 |' + let name = '' + let sect = tolower(args[1]) + else + " cursor (|) is at ':Man pri|' + if a:arg_lead =~# '\/' + " if the name is a path, complete files + " TODO(nhooyr) why does this complete the last one automatically + return glob(a:arg_lead.'*', 0, 1) + endif + let name = a:arg_lead + let sect = '' endif + elseif a:arg_lead !~# '^[^()]\+$' + " cursor (|) is at ':Man 3 printf |' or ':Man 3 (pr)i|' + return + else + " cursor (|) is at ':Man 3 pri|' + let name = a:arg_lead + let sect = tolower(args[1]) + endif + return s:complete(sect, sect, name) +endfunction + +function! s:complete(sect, psect, name) abort + try + let mandirs = join(split(s:system(['man', s:man_find_arg]), ':\|\n'), ',') catch - echoerr 'man.vim: failed to parse: "'.a:str.'"' + call s:error(v:exception) + return endtry - - return [page, sect] + let pages = globpath(mandirs,'man?/'.a:name.'*.'.a:sect.'*', 0, 1) + " We remove duplicates in case the same manpage in different languages was found. + return uniq(sort(map(pages, 's:format_candidate(v:val, a:psect)'), 'i')) endfunction -function s:cmd(sect, page) abort - if !empty(a:sect) - return s:man_sect_arg.' '.a:sect.' '.a:page +function! s:format_candidate(path, psect) abort + if a:path =~# '\.\%(pdf\|in\)$' " invalid extensions + return + endif + let [sect, name] = s:extract_sect_and_name_path(a:path) + if sect ==# a:psect + return name + elseif sect =~# a:psect.'.\+$' + " We include the section if the user provided section is a prefix + " of the actual section. + return name.'('.sect.')' endif - return a:page endfunction -function s:find_page(sect, page) abort - let where = system('/usr/bin/man '.s:man_find_arg.' '.s:cmd(a:sect, a:page)) - return (where =~# '^ */') +function! man#init_pager() abort + " Remove all backspaced/escape characters. + execute 'silent keeppatterns keepjumps %substitute,.\b\|\e\[\d\+m,,e'.(&gdefault?'':'g') + if getline(1) =~# '^\s*$' + silent keepjumps 1delete _ + else + keepjumps 1 + endif + " This is not perfect. See `man glDrawArraysInstanced`. Since the title is + " all caps it is impossible to tell what the original capitilization was. + let ref = substitute(matchstr(getline(1), '^[^)]\+)'), ' ', '_', 'g') + try + let b:man_sect = man#extract_sect_and_name_ref(ref)[0] + catch + let b:man_sect = '' + endtry + execute 'silent file man://'.fnameescape(ref) endfunction diff --git a/runtime/autoload/msgpack.vim b/runtime/autoload/msgpack.vim index 2e2697c57f..a10ac32469 100644 --- a/runtime/autoload/msgpack.vim +++ b/runtime/autoload/msgpack.vim @@ -665,11 +665,15 @@ function msgpack#eval(s, special_objs) abort call add(expr, ']}') let s = s[1:] elseif s[0] is# '''' - let char = matchstr(s, '\m\C^''\zs.\ze''') + let char = matchstr(s, '\v\C^\''\zs%(\\\d+|.)\ze\''') if empty(char) throw 'char-invalid:Invalid integer character literal format: ' . s endif - call add(expr, char2nr(char)) + if char[0] is# '\' + call add(expr, +char[1:]) + else + call add(expr, char2nr(char)) + endif let s = s[len(char) + 2:] else throw 'unknown:Invalid non-space character: ' . s diff --git a/runtime/autoload/netrw.vim b/runtime/autoload/netrw.vim index 53668b15be..de85844d5d 100644 --- a/runtime/autoload/netrw.vim +++ b/runtime/autoload/netrw.vim @@ -1,10 +1,10 @@ " netrw.vim: Handles file transfer and remote directory listing across " AUTOLOAD SECTION -" Date: Oct 23, 2015 -" Version: 154 +" Date: Apr 20, 2016 +" Version: 156 " Maintainer: Charles E Campbell <NdrOchip@ScampbellPfamily.AbizM-NOSPAM> " GetLatestVimScripts: 1075 1 :AutoInstall: netrw.vim -" Copyright: Copyright (C) 1999-2015 Charles E. Campbell {{{1 +" Copyright: Copyright (C) 2016 Charles E. Campbell {{{1 " Permission is hereby granted to use and distribute this code, " with or without modifications, provided that this copyright " notice is copied with it. Like anything else that's free, @@ -13,7 +13,7 @@ " expressed or implied. By using this plugin, you agree that " in no event will the copyright holder be liable for any damages " resulting from the use of this software. -"redraw!|call DechoSep()|call inputsave()|call input("Press <cr> to continue")|call inputrestore(,'~'.expand("<slnum>")) +"redraw!|call DechoSep()|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) @@ -30,7 +30,7 @@ if v:version < 704 || !has("patch213") let s:needpatch213= 1 finish endif -let g:loaded_netrw = "v154" +let g:loaded_netrw = "v156" if !exists("s:NOTE") let s:NOTE = 0 let s:WARNING = 1 @@ -55,7 +55,7 @@ setl cpo&vim " Usage: netrw#ErrorMsg(s:NOTE | s:WARNING | s:ERROR,"some message",error-number) " netrw#ErrorMsg(s:NOTE | s:WARNING | s:ERROR,["message1","message2",...],error-number) " (this function can optionally take a list of messages) -" Oct 09, 2015 : max errnum currently is 102 +" Jan 19, 2016 : max errnum currently is 103 fun! netrw#ErrorMsg(level,msg,errnum) " call Dfunc("netrw#ErrorMsg(level=".a:level." msg<".a:msg."> errnum=".a:errnum.") g:netrw_use_errorwindow=".g:netrw_use_errorwindow) @@ -77,7 +77,7 @@ fun! netrw#ErrorMsg(level,msg,errnum) " (default) netrw creates a one-line window to show error/warning " messages (reliably displayed) - " record current window number for NetrwRestorePosn()'s benefit + " record current window number let s:winBeforeErr= winnr() " call Decho("s:winBeforeErr=".s:winBeforeErr,'~'.expand("<slnum>")) @@ -416,18 +416,20 @@ if !exists("g:netrw_localmovecmd") let g:netrw_localmovecmd= "" endif endif -if exists("g:netrw_local_rmdir") - let g:netrw_localrmdir= g:netrw_local_rmdir - call netrw#ErrorMsg(s:NOTE,"g:netrw_local_rmdir is deprecated in favor of g:netrw_localrmdir",86) -endif -if has("win32") || has("win95") || has("win64") || has("win16") - if g:netrw_cygwin - call s:NetrwInit("g:netrw_localrmdir","rmdir") - else - let g:netrw_localrmdir= expand("$COMSPEC")." /c rmdir" - endif -else - call s:NetrwInit("g:netrw_localrmdir","rmdir") +if v:version < 704 || !has("patch1109") + if exists("g:netrw_local_rmdir") + let g:netrw_localrmdir= g:netrw_local_rmdir + call netrw#ErrorMsg(s:NOTE,"g:netrw_local_rmdir is deprecated in favor of g:netrw_localrmdir",86) + endif + if has("win32") || has("win95") || has("win64") || has("win16") + if g:netrw_cygwin + call s:NetrwInit("g:netrw_localrmdir","rmdir") + else + let g:netrw_localrmdir= expand("$COMSPEC")." /c rmdir" + endif + else + call s:NetrwInit("g:netrw_localrmdir","rmdir") + endif endif call s:NetrwInit("g:netrw_liststyle" , s:THINLIST) " sanity checks @@ -442,7 +444,7 @@ call s:NetrwInit("g:netrw_markfileesc" , '*./[\~') call s:NetrwInit("g:netrw_maxfilenamelen", 32) call s:NetrwInit("g:netrw_menu" , 1) call s:NetrwInit("g:netrw_mkdir_cmd" , g:netrw_ssh_cmd." USEPORT HOSTNAME mkdir") -call s:NetrwInit("g:netrw_mousemaps" , (exists("+mouse") && &mouse =~ '[anh]')) +call s:NetrwInit("g:netrw_mousemaps" , (exists("+mouse") && &mouse =~# '[anh]')) call s:NetrwInit("g:netrw_retmap" , 0) if has("unix") || (exists("g:netrw_cygwin") && g:netrw_cygwin) call s:NetrwInit("g:netrw_chgperm" , "chmod PERM FILENAME") @@ -488,7 +490,9 @@ if !exists("g:netrw_sort_sequence") endif call s:NetrwInit("g:netrw_special_syntax" , 0) call s:NetrwInit("g:netrw_ssh_browse_reject", '^total\s\+\d\+$') +call s:NetrwInit("g:netrw_suppress_gx_mesg", 1) call s:NetrwInit("g:netrw_use_noswf" , 1) +call s:NetrwInit("g:netrw_sizestyle" ,"b") " Default values - t-w ---------- {{{3 call s:NetrwInit("g:netrw_timefmt","%c") if !exists("g:netrw_xstrlen") @@ -523,6 +527,7 @@ if has("gui_running") && (&enc == 'utf-8' || &enc == 'utf-16' || &enc == 'ucs-4' else let s:treedepthstring= "| " endif +call s:NetrwInit("s:netrw_nbcd",'{}') " BufEnter event ignored by decho when following variable is true " Has a side effect that doau BufReadPost doesn't work, so @@ -548,7 +553,7 @@ if v:version >= 700 && has("balloon_eval") && !exists("s:initbeval") && !exists( endif au WinEnter * if &ft == "netrw"|call s:NetrwInsureWinVars()|endif -if g:netrw_keepj =~ "keepj" +if g:netrw_keepj =~# "keepj" com! -nargs=* NetrwKeepj keepj <args> else let g:netrw_keepj= "" @@ -614,7 +619,7 @@ endif " == 4: Vexplore style == 5: Vexplore! " == 6: Texplore fun! netrw#Explore(indx,dosplit,style,...) -" call Dfunc("netrw#Explore(indx=".a:indx." dosplit=".a:dosplit." style=".a:style.",a:1<".a:1.">) &modified=".&modified." modifiable=".&modifiable." a:0=".a:0." win#".winnr()." buf#".bufnr("%")) +" call Dfunc("netrw#Explore(indx=".a:indx." dosplit=".a:dosplit." style=".a:style.",a:1<".a:1.">) &modified=".&modified." modifiable=".&modifiable." a:0=".a:0." win#".winnr()." buf#".bufnr("%")." ft=".&ft) " call Decho("tab#".tabpagenr()." win#".winnr()." buf#".bufnr("%")."<".bufname("%")."> line#".line(".")." col#".col(".")." winline#".winline()." wincol#".wincol(),'~'.expand("<slnum>")) if !exists("b:netrw_curdir") let b:netrw_curdir= getcwd() @@ -818,7 +823,7 @@ fun! netrw#Explore(indx,dosplit,style,...) let dirname= curfiledir " call Decho("..empty dirname, using current file's directory<".dirname.">",'~'.expand("<slnum>")) endif - if dirname =~ '^scp://' || dirname =~ '^ftp://' + if dirname =~# '^scp://' || dirname =~ '^ftp://' call netrw#Nread(2,dirname) else if dirname == "" @@ -1165,7 +1170,8 @@ fun! netrw#Lexplore(count,rightside,...) " call Decho("t:netrw_lexbufnr#".t:netrw_lexbufnr.": close down netrw window",'~'.expand("<slnum>")) exe lexwinnr."wincmd w" let g:netrw_winsize = -winwidth(0) - let t:netrw_lexposn = netrw#SavePosn() + let t:netrw_lexposn = winsaveview() +" call Decho("saving posn to t:netrw_lexposn<".string(t:netrw_lexposn).">",'~'.expand("<slnum>")) " call Decho("saving t:netrw_lexposn",'~'.expand("<slnum>")) close if lexwinnr < curwin @@ -1205,7 +1211,8 @@ fun! netrw#Lexplore(count,rightside,...) let t:netrw_lexbufnr = bufnr("%") if exists("t:netrw_lexposn") " call Decho("restoring to t:netrw_lexposn",'~'.expand("<slnum>")) - call netrw#RestorePosn(t:netrw_lexposn) +" call Decho("restoring posn to t:netrw_lexposn<".string(t:netrw_lexposn).">",'~'.expand("<slnum>")) + call winrestview(t:netrw_lexposn) unlet t:netrw_lexposn endif endif @@ -1273,7 +1280,8 @@ endfun fun! netrw#MakeTgt(dname) " call Dfunc("netrw#MakeTgt(dname<".a:dname.">)") " simplify the target (eg. /abc/def/../ghi -> /abc/ghi) - let svpos = netrw#SavePosn() + let svpos = winsaveview() +" call Decho("saving posn to svpos<".string(svpos).">",'~'.expand("<slnum>")) let s:netrwmftgt_islocal= (a:dname !~ '^\a\{3,}://') " call Decho("s:netrwmftgt_islocal=".s:netrwmftgt_islocal,'~'.expand("<slnum>")) if s:netrwmftgt_islocal @@ -1290,7 +1298,8 @@ fun! netrw#MakeTgt(dname) if g:netrw_fastbrowse <= 1 call s:NetrwRefresh((b:netrw_curdir !~ '\a\{3,}://'),b:netrw_curdir) endif - call netrw#RestorePosn(svpos) +" call Decho("restoring posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))" + call winrestview(svpos) " call Dret("netrw#MakeTgt") endfun @@ -1532,9 +1541,11 @@ endfun " netrw#Nread: save position, call netrw#NetRead(), and restore position {{{2 fun! netrw#Nread(mode,fname) " call Dfunc("netrw#Nread(mode=".a:mode." fname<".a:fname.">)") - call netrw#SavePosn() + let svpos= winsaveview() +" call Decho("saving posn to svpos<".string(svpos).">",'~'.expand("<slnum>")) call netrw#NetRead(a:mode,a:fname) - call netrw#RestorePosn() +" call Decho("restoring posn to svpos<".string(svpos).">",'~'.expand("<slnum>")) + call winrestview(svpos) if exists("w:netrw_liststyle") && w:netrw_liststyle != s:TREELIST if exists("w:netrw_bannercnt") @@ -1551,15 +1562,7 @@ fun! s:NetrwOptionRestore(vt) " call Dfunc("s:NetrwOptionRestore(vt<".a:vt.">) win#".winnr()." buf#".bufnr("%")."<".bufname("%")."> winnr($)=".winnr("$")) " call Decho("settings buf#".bufnr("%")."<".bufname("%").">: ".((&l:ma == 0)? "no" : "")."ma ".((&l:mod == 0)? "no" : "")."mod ".((&l:bl == 0)? "no" : "")."bl ".((&l:ro == 0)? "no" : "")."ro fo=".&l:fo." a:vt=".a:vt,'~'.expand("<slnum>")) if !exists("{a:vt}netrw_optionsave") - if exists("s:nbcd_curpos_{bufnr('%')}") -" call Decho("restoring previous position (s:nbcd_curpos_".bufnr('%')." exists)",'~'.expand("<slnum>")) - NetrwKeepj call netrw#RestorePosn(s:nbcd_curpos_{bufnr('%')}) -" call Decho("win#".winnr()." buf#".bufnr("%")."<".bufname("%")."> winnr($)=".winnr("$"),'~'.expand("<slnum>")) -" call Decho("unlet s:nbcd_curpos_".bufnr('%'),'~'.expand("<slnum>")) - unlet s:nbcd_curpos_{bufnr('%')} - else -" call Decho("no previous position",'~'.expand("<slnum>")) - endif + call s:RestorePosn(s:netrw_nbcd) " call Decho("settings buf#".bufnr("%")."<".bufname("%").">: ".((&l:ma == 0)? "no" : "")."ma ".((&l:mod == 0)? "no" : "")."mod ".((&l:bl == 0)? "no" : "")."bl ".((&l:ro == 0)? "no" : "")."ro fo=".&l:fo." a:vt=".a:vt,'~'.expand("<slnum>")) " call Decho("ro=".&l:ro." ma=".&l:ma." mod=".&l:mod." wrap=".&l:wrap." (filename<".expand("%")."> win#".winnr()." ft<".&ft.">)",'~'.expand("<slnum>")) " call Dret("s:NetrwOptionRestore : ".a:vt."netrw_optionsave doesn't exist") @@ -1629,8 +1632,10 @@ fun! s:NetrwOptionRestore(vt) setl directory= unlet {a:vt}netrw_swfkeep elseif &l:swf != {a:vt}netrw_swfkeep - " following line causes a Press ENTER in windows -- can't seem to work around it!!! - sil! let &l:swf= {a:vt}netrw_swfkeep + if !g:netrw_use_noswf + " following line causes a Press ENTER in windows -- can't seem to work around it!!! + sil! let &l:swf= {a:vt}netrw_swfkeep + endif unlet {a:vt}netrw_swfkeep endif endif @@ -1645,16 +1650,7 @@ fun! s:NetrwOptionRestore(vt) if exists("{a:vt}netrw_regstar") |sil! let @*= {a:vt}netrw_regstar |unlet {a:vt}netrw_regstar |endif endif if exists("{a:vt}netrw_regslash")|sil! let @/= {a:vt}netrw_regslash|unlet {a:vt}netrw_regslash|endif - if exists("s:nbcd_curpos_{bufnr('%')}") -" call Decho("restoring previous position (s:nbcd_curpos_".bufnr('%')." exists)",'~'.expand("<slnum>")) - NetrwKeepj call netrw#RestorePosn(s:nbcd_curpos_{bufnr('%')}) -" call Decho("unlet s:nbcd_curpos_".bufnr('%'),'~'.expand("<slnum>")) - if exists("s:nbcd_curpos_".bufnr('%')) - unlet s:nbcd_curpos_{bufnr('%')} - endif - else -" call Decho("no previous position",'~'.expand("<slnum>")) - endif + call s:RestorePosn(s:netrw_nbcd) " call Decho("g:netrw_keepdir=".g:netrw_keepdir.": getcwd<".getcwd()."> acd=".&acd,'~'.expand("<slnum>")) " call Decho("fo=".&fo.(exists("+acd")? " acd=".&acd : " acd doesn't exist"),'~'.expand("<slnum>")) @@ -1729,11 +1725,11 @@ fun! s:NetrwOptionSave(vt) let {a:vt}netrw_rokeep = &l:ro let {a:vt}netrw_selkeep = &l:sel let {a:vt}netrw_spellkeep = &l:spell - if g:netrw_use_noswf - let {a:vt}netrw_swfkeep = &l:swf + if !g:netrw_use_noswf + let {a:vt}netrw_swfkeep = &l:swf endif if has("clipboard") - let {a:vt}netrw_starkeep = @* + let {a:vt}netrw_starkeep = @* endif let {a:vt}netrw_tskeep = &l:ts let {a:vt}netrw_twkeep = &l:tw " textwidth @@ -2664,7 +2660,9 @@ fun! netrw#NetSource(...) " call Decho("exe so ".fnameescape(s:netrw_tmpfile),'~'.expand("<slnum>")) exe "so ".fnameescape(s:netrw_tmpfile) " call Decho("delete(".s:netrw_tmpfile.")",'~'.expand("<slnum>")) - call delete(s:netrw_tmpfile) + if delete(s:netrw_tmpfile) + call netrw#ErrorMsg(s:ERROR,"unable to delete directory <".s:netrw_tmpfile.">!",103) + endif unlet s:netrw_tmpfile else call netrw#ErrorMsg(s:ERROR,"unable to source <".a:{i}.">!",48) @@ -3003,10 +3001,10 @@ fun! s:NetrwMethod(choice) if exists("s:netrw_hup[host]") call NetUserPass("ftp:".host) - elseif (has("win32") || has("win95") || has("win64") || has("win16")) && s:netrw_ftp_cmd =~ '-[sS]:' + elseif (has("win32") || has("win95") || has("win64") || has("win16")) && s:netrw_ftp_cmd =~# '-[sS]:' " call Decho("has -s: : s:netrw_ftp_cmd<".s:netrw_ftp_cmd.">",'~'.expand("<slnum>")) " call Decho(" g:netrw_ftp_cmd<".g:netrw_ftp_cmd.">",'~'.expand("<slnum>")) - if g:netrw_ftp_cmd =~ '-[sS]:\S*MACHINE\>' + if g:netrw_ftp_cmd =~# '-[sS]:\S*MACHINE\>' let s:netrw_ftp_cmd= substitute(g:netrw_ftp_cmd,'\<MACHINE\>',g:netrw_machine,'') " call Decho("s:netrw_ftp_cmd<".s:netrw_ftp_cmd.">",'~'.expand("<slnum>")) endif @@ -3504,7 +3502,11 @@ fun! s:NetrwBookHistSave() let savefile= s:NetrwHome()."/.netrwhist" 1split call s:NetrwEnew() - setl cino= com= cpo-=a cpo-=A fo=nroql2 tw=0 report=10000 noswf + if g:netrw_use_noswf + setl cino= com= cpo-=a cpo-=A fo=nroql2 tw=0 report=10000 noswf + else + setl cino= com= cpo-=a cpo-=A fo=nroql2 tw=0 report=10000 + endif setl nocin noai noci magic nospell nohid wig= noaw setl ma noro write if exists("+acd") | setl noacd | endif @@ -3566,6 +3568,7 @@ fun! s:NetrwBrowse(islocal,dirname) " This is useful when one edits a local file, then :e ., then :Rex if a:islocal && !exists("w:netrw_rexfile") && bufname("#") != "" let w:netrw_rexfile= bufname("#") +" call Decho("setting w:netrw_rexfile<".w:netrw_rexfile."> win#".winnr(),'~'.expand("<slnum>")) endif " s:NetrwBrowse : initialize history {{{3 @@ -3683,7 +3686,8 @@ fun! s:NetrwBrowse(islocal,dirname) " get/set-up buffer {{{3 " call Decho("saving position across a buffer refresh",'~'.expand("<slnum>")) - let svpos = netrw#SavePosn() + let svpos = winsaveview() +" call Decho("saving posn to svpos<".string(svpos).">",'~'.expand("<slnum>")) let reusing= s:NetrwGetBuffer(a:islocal,dirname) " maintain markfile highlighting @@ -3754,7 +3758,7 @@ fun! s:NetrwBrowse(islocal,dirname) " analyze dirname and g:netrw_list_cmd {{{3 " call Decho("b:netrw_curdir<".(exists("b:netrw_curdir")? b:netrw_curdir : "doesn't exist")."> dirname<".dirname.">",'~'.expand("<slnum>")) - if dirname =~ "^NetrwTreeListing\>" + if dirname =~# "^NetrwTreeListing\>" let dirname= b:netrw_curdir " call Decho("(dirname was <NetrwTreeListing>) dirname<".dirname.">",'~'.expand("<slnum>")) elseif exists("w:netrw_liststyle") && w:netrw_liststyle == s:TREELIST && exists("b:netrw_curdir") @@ -3792,10 +3796,18 @@ fun! s:NetrwBrowse(islocal,dirname) NetrwKeepj call s:NetrwCommands(a:islocal) NetrwKeepj call s:PerformListing(a:islocal) + " restore option(s) + call s:NetrwOptionRestore("w:") +" call Decho("tab#".tabpagenr()." win#".winnr()." buf#".bufnr("%")."<".bufname("%")."> line#".line(".")." col#".col(".")." winline#".winline()." wincol#".wincol(),'~'.expand("<slnum>")) + " If there is a rexposn: restore position with rexposn " Otherwise : set rexposn if exists("s:rexposn_".bufnr("%")) - NetrwKeepj call netrw#RestorePosn(s:rexposn_{bufnr('%')}) +" call Decho("restoring posn to s:rexposn_".bufnr('%')."<".string(s:rexposn_{bufnr('%')}).">",'~'.expand("<slnum>")) + NetrwKeepj call winrestview(s:rexposn_{bufnr('%')}) + if exists("w:netrw_bannercnt") && line(".") < w:netrw_bannercnt + NetrwKeepj exe w:netrw_bannercnt + endif else NetrwKeepj call s:SetRexDir(a:islocal,b:netrw_curdir) endif @@ -3804,13 +3816,11 @@ fun! s:NetrwBrowse(islocal,dirname) " call Decho("set up balloon help: l:bexpr=".&l:bexpr,'~'.expand("<slnum>")) setl beval endif - call s:NetrwOptionRestore("w:") -" call Decho("tab#".tabpagenr()." win#".winnr()." buf#".bufnr("%")."<".bufname("%")."> line#".line(".")." col#".col(".")." winline#".winline()." wincol#".wincol(),'~'.expand("<slnum>")) " restore position if reusing -" call Decho("reusing=".reusing.": restoring position across buffer refresh",'~'.expand("<slnum>")) - call netrw#RestorePosn(svpos) +" call Decho("restoring posn to svpos<".string(svpos).">",'~'.expand("<slnum>")) + call winrestview(svpos) endif " The s:LocalBrowseRefresh() function is called by an autocmd @@ -3828,7 +3838,19 @@ endfun " differ from vim's. This function insures that netrw's idea of the current " directory is used. fun! s:NetrwFile(fname) -" call Dfunc("s:NetrwFile(fname<".a:fname.">)") +" call Dfunc("s:NetrwFile(fname<".a:fname.">) win#".winnr()) +" call Decho("g:netrw_keepdir =".(exists("g:netrw_keepdir")? g:netrw_keepdir : 'n/a'),'~'.expand("<slnum>")) +" call Decho("g:netrw_cygwin =".(exists("g:netrw_cygwin")? g:netrw_cygwin : 'n/a'),'~'.expand("<slnum>")) +" call Decho("g:netrw_liststyle=".(exists("g:netrw_liststyle")? g:netrw_liststyle : 'n/a'),'~'.expand("<slnum>")) +" call Decho("w:netrw_liststyle=".(exists("w:netrw_liststyle")? w:netrw_liststyle : 'n/a'),'~'.expand("<slnum>")) + + " clean up any leading treedepthstring + if exists("w:netrw_liststyle") && w:netrw_liststyle == s:TREELIST + let fname= substitute(a:fname,'^'.s:treedepthstring.'\+','','') +" call Decho("clean up any leading treedepthstring: fname<".fname.">",'~'.expand("<slnum>")) + else + let fname= a:fname + endif if g:netrw_keepdir " vim's idea of the current directory possibly may differ from netrw's @@ -3837,29 +3859,31 @@ fun! s:NetrwFile(fname) endif if !exists("g:netrw_cygwin") && (has("win32") || has("win95") || has("win64") || has("win16")) - if a:fname =~ '^\' || a:fname =~ '^\a:\' + if fname =~ '^\' || fname =~ '^\a:\' " windows, but full path given - let ret= a:fname -" call Decho("windows+full path: isdirectory(".a:fname.")",'~'.expand("<slnum>")) + let ret= fname +" call Decho("windows+full path: isdirectory(".fname.")",'~'.expand("<slnum>")) else " windows, relative path given - let ret= s:ComposePath(b:netrw_curdir,a:fname) -" call Decho("windows+rltv path: isdirectory(".a:fname.")",'~'.expand("<slnum>")) + let ret= s:ComposePath(b:netrw_curdir,fname) +" call Decho("windows+rltv path: isdirectory(".fname.")",'~'.expand("<slnum>")) endif - elseif a:fname =~ '^/' + elseif fname =~ '^/' " not windows, full path given - let ret= a:fname -" call Decho("unix+full path: isdirectory(".a:fname.")",'~'.expand("<slnum>")) + let ret= fname +" call Decho("unix+full path: isdirectory(".fname.")",'~'.expand("<slnum>")) else " not windows, relative path given - let ret= s:ComposePath(b:netrw_curdir,a:fname) -" call Decho("unix+rltv path: isdirectory(".a:fname.")",'~'.expand("<slnum>")) + let ret= s:ComposePath(b:netrw_curdir,fname) +" call Decho("unix+rltv path: isdirectory(".fname.")",'~'.expand("<slnum>")) endif else " vim and netrw agree on the current directory - let ret= a:fname + let ret= fname " call Decho("vim and netrw agree on current directory (g:netrw_keepdir=".g:netrw_keepdir.")",'~'.expand("<slnum>")) +" call Decho("vim directory: ".getcwd(),'~'.expand("<slnum>")) +" call Decho("netrw directory: ".(exists("b:netrw_curdir")? b:netrw_curdir : 'n/a'),'~'.expand("<slnum>")) endif " call Dret("s:NetrwFile ".ret) @@ -3872,23 +3896,29 @@ fun! s:NetrwFileInfo(islocal,fname) " call Dfunc("s:NetrwFileInfo(islocal=".a:islocal." fname<".a:fname.">) b:netrw_curdir<".b:netrw_curdir.">") let ykeep= @@ if a:islocal + let lsopt= "-lsad" + if g:netrw_sizestyle =~# 'H' + let lsopt= "-lsadh" + elseif g:netrw_sizestyle =~# 'h' + let lsopt= "-lsadh --si" + endif if (has("unix") || has("macunix")) && executable("/bin/ls") if getline(".") == "../" - echo system("/bin/ls -lsad ".s:ShellEscape("..")) + echo system("/bin/ls ".lsopt." ".s:ShellEscape("..")) " call Decho("#1: echo system(/bin/ls -lsad ".s:ShellEscape(..).")",'~'.expand("<slnum>")) elseif w:netrw_liststyle == s:TREELIST && getline(".") !~ '^'.s:treedepthstring - echo system("/bin/ls -lsad ".s:ShellEscape(b:netrw_curdir)) + echo system("/bin/ls ".lsopt." ".s:ShellEscape(b:netrw_curdir)) " call Decho("#2: echo system(/bin/ls -lsad ".s:ShellEscape(b:netrw_curdir).")",'~'.expand("<slnum>")) elseif exists("b:netrw_curdir") - echo system("/bin/ls -lsad ".s:ShellEscape(s:ComposePath(b:netrw_curdir,a:fname))) + echo system("/bin/ls ".lsopt." ".s:ShellEscape(s:ComposePath(b:netrw_curdir,a:fname))) " call Decho("#3: echo system(/bin/ls -lsad ".s:ShellEscape(b:netrw_curdir.a:fname).")",'~'.expand("<slnum>")) else " call Decho('using ls '.a:fname." using cwd<".getcwd().">",'~'.expand("<slnum>")) - echo system("/bin/ls -lsad ".s:ShellEscape(s:NetrwFile(a:fname))) + echo system("/bin/ls ".lsopt." ".s:ShellEscape(s:NetrwFile(a:fname))) " call Decho("#5: echo system(/bin/ls -lsad ".s:ShellEscape(a:fname).")",'~'.expand("<slnum>")) endif else @@ -3901,6 +3931,9 @@ fun! s:NetrwFileInfo(islocal,fname) endif let t = getftime(s:NetrwFile(fname)) let sz = getfsize(s:NetrwFile(fname)) + if g:netrw_sizestyle =~# "[hH]" + let sz= s:NetrwHumanReadable(sz) + endif echo a:fname.": ".sz." ".strftime(g:netrw_timefmt,getftime(s:NetrwFile(fname))) " call Decho("fname.": ".sz." ".strftime(g:netrw_timefmt,getftime(fname)),'~'.expand("<slnum>")) endif @@ -3912,108 +3945,49 @@ fun! s:NetrwFileInfo(islocal,fname) endfun " --------------------------------------------------------------------- +" s:NetrwFullPath: returns the full path to a directory and/or file {{{2 +fun! s:NetrwFullPath(filename) +" " call Dfunc("s:NetrwFullPath(filename<".a:filename.">)") + let filename= a:filename + if filename !~ '^/' + let filename= resolve(getcwd().'/'.filename) + endif + if filename != "/" && filename =~ '/$' + let filename= substitute(filename,'/$','','') + endif +" " call Dret("s:NetrwFullPath <".filename.">") + return filename +endfun + +" --------------------------------------------------------------------- " s:NetrwGetBuffer: {{{2 " returns 0=cleared buffer " 1=re-used buffer (buffer not cleared) fun! s:NetrwGetBuffer(islocal,dirname) " call Dfunc("s:NetrwGetBuffer(islocal=".a:islocal." dirname<".a:dirname.">) liststyle=".g:netrw_liststyle) " call Decho("settings buf#".bufnr("%")."<".bufname("%").">: ".((&l:ma == 0)? "no" : "")."ma ".((&l:mod == 0)? "no" : "")."mod ".((&l:bl == 0)? "no" : "")."bl ".((&l:ro == 0)? "no" : "")."ro fo=".&l:fo,'~'.expand("<slnum>")) +" call Decho("netrwbuf dictionary=".string(s:netrwbuf),'~'.expand("<slnum>")) let dirname= a:dirname " re-use buffer if possible {{{3 " call Decho("--re-use a buffer if possible--",'~'.expand("<slnum>")) - if exists("w:netrw_liststyle") && w:netrw_liststyle == s:TREELIST - " find NetrwTreeList buffer if there is one -" call Decho("case liststyle=treelist: find NetrwTreeList buffer if there is one",'~'.expand("<slnum>")) - if exists("w:netrw_treebufnr") && w:netrw_treebufnr > 0 -" call Decho(" re-using w:netrw_treebufnr=".w:netrw_treebufnr,'~'.expand("<slnum>")) - let eikeep= &ei - setl ei=all - exe "sil! keepj noswapfile keepalt b ".w:netrw_treebufnr - let &ei= eikeep - setl ma - sil! NetrwKeepj %d _ -" call Decho("settings buf#".bufnr("%")."<".bufname("%").">: ".((&l:ma == 0)? "no" : "")."ma ".((&l:mod == 0)? "no" : "")."mod ".((&l:bl == 0)? "no" : "")."bl ".((&l:ro == 0)? "no" : "")."ro fo=".&l:fo,'~'.expand("<slnum>")) -" call Decho("tab#".tabpagenr()." win#".winnr()." buf#".bufnr("%")."<".bufname("%")."> line#".line(".")." col#".col(".")." winline#".winline()." wincol#".wincol(),'~'.expand("<slnum>")) -" call Dret("s:NetrwGetBuffer 0<buffer cleared> : bufnum#".w:netrw_treebufnr."<NetrwTreeListing>") - return 0 + if !exists("s:netrwbuf") + let s:netrwbuf= {} + endif + if has_key(s:netrwbuf,s:NetrwFullPath(dirname)) + let bufnum= s:netrwbuf[s:NetrwFullPath(dirname)] +" call Decho("lookup netrwbuf dictionary: s:netrwbuf[".s:NetrwFullPath(dirname)."]=".bufnum) + if !bufexists(bufnum) + call remove(s:netrwbuf,s:NetrwFullPath(dirname)) + let bufnum= -1 endif - let bufnum= -1 -" call Decho(" liststyle=TREE but w:netrw_treebufnr doesn't exist",'~'.expand("<slnum>")) - else - " find buffer number of buffer named precisely the same as dirname {{{3 -" call Decho("case listtyle not treelist: find buffer numnber of buffer named precisely the same as dirname--",'~'.expand("<slnum>")) -" call Dredir("(NetrwGetBuffer) ls!","ls!") - - " get dirname and associated buffer number - let bufnum = bufnr(escape(dirname,'\')) -" call Decho(" find buffer<".dirname.">'s number ",'~'.expand("<slnum>")) -" call Decho(" bufnr(dirname<".escape(dirname,'\').">)=".bufnum,'~'.expand("<slnum>")) - - if bufnum < 0 && dirname !~ '/$' - " try appending a trailing / -" call Decho(" try appending a trailing / to dirname<".dirname.">",'~'.expand("<slnum>")) - let bufnum= bufnr(escape(dirname.'/','\')) - if bufnum > 0 - let dirname= dirname.'/' - endif - endif - - if bufnum < 0 && dirname =~ '/$' - " try removing a trailing / -" call Decho(" try removing a trailing / from dirname<".dirname.">",'~'.expand("<slnum>")) - let bufnum= bufnr(escape(substitute(dirname,'/$','',''),'\')) - if bufnum > 0 - let dirname= substitute(dirname,'/$','','') - endif - endif - -" call Decho(" findbuf1: bufnum=bufnr('".dirname."')=".bufnum." bufname(".bufnum.")<".bufname(bufnum)."> (initial)",'~'.expand("<slnum>")) - " note: !~ was used just below, but that means using ../ to go back would match (ie. abc/def/ and abc/ matches) - if bufnum > 0 && bufname(bufnum) != dirname && bufname(bufnum) != '.' - " handle approximate matches -" call Decho(" handling approx match: bufnum#".bufnum.">0 AND bufname<".bufname(bufnum).">!=dirname<".dirname."> AND bufname(".bufnum.")!='.'",'~'.expand("<slnum>")) - let ibuf = 1 - let buflast = bufnr("$") -" call Decho(" findbuf2: buflast=bufnr($)=".buflast,'~'.expand("<slnum>")) - while ibuf <= buflast - let bname= substitute(bufname(ibuf),'\\','/','g') - let bname= substitute(bname,'.\zs/$','','') -" call Decho(" findbuf3: while [ibuf=",ibuf."]<=[buflast=".buflast."]: dirname<".dirname."> bname=bufname(".ibuf.")<".bname.">",'~'.expand("<slnum>")) - if bname != '' && dirname =~ '/'.bname.'/\=$' && dirname !~ '^/' - " bname is not empty - " dirname ends with bname, - " dirname doesn't start with /, so its not a absolute path -" call Decho(" findbuf3a: passes test 1 : dirname<".dirname.'> =~ /'.bname.'/\=$ && dirname !~ ^/','~'.expand("<slnum>")) - break - endif - if bname =~ '^'.dirname.'/\=$' - " bname begins with dirname -" call Decho(' findbuf3b: passes test 2 : bname<'.bname.'>=~^'.dirname.'/\=$','~'.expand("<slnum>")) - break - endif - if dirname =~ '^'.bname.'/$' -" call Decho(' findbuf3c: passes test 3 : dirname<'.dirname.'>=~^'.bname.'/$','~'.expand("<slnum>")) - break - endif - if bname != '' && dirname =~ '/'.bname.'$' && bname == bufname("%") && line("$") == 1 -" call Decho(' findbuf3d: passes test 4 : dirname<'.dirname.'>=~ /'.bname.'$','~'.expand("<slnum>")) - break - endif - let ibuf= ibuf + 1 - endwhile - if ibuf > buflast - let bufnum= -1 - else - let bufnum= ibuf - endif -" call Decho(" findbuf4: bufnum=".bufnum." (ibuf=".ibuf." buflast=".buflast.")",'~'.expand("<slnum>")) - endif +" call Decho("lookup netrwbuf dictionary: s:netrwbuf[".s:NetrwFullPath(dirname)."] not a key") + let bufnum= -1 endif " get enew buffer and name it -or- re-use buffer {{{3 - if bufnum < 0 || !bufexists(bufnum) " get enew buffer and name it + if bufnum < 0 " get enew buffer and name it " call Decho("--get enew buffer and name it (bufnum#".bufnum."<0 OR bufexists(".bufnum.")=".bufexists(bufnum)."==0)",'~'.expand("<slnum>")) call s:NetrwEnew(dirname) " call Decho(" got enew buffer#".bufnr("%")." (altbuf<".expand("#").">)",'~'.expand("<slnum>")) @@ -4029,11 +4003,15 @@ fun! s:NetrwGetBuffer(islocal,dirname) let w:netrw_treebufnr= bufnr("%") " call Decho(" exe sil! keepalt file NetrwTreeListing ".fnameescape(s:netrw_treelistnum),'~'.expand("<slnum>")) exe 'sil! keepalt file NetrwTreeListing\ '.fnameescape(s:netrw_treelistnum) - setl bt=nofile noswf - nnoremap <silent> <buffer> [ :sil call <SID>TreeListMove('[')<cr> - nnoremap <silent> <buffer> ] :sil call <SID>TreeListMove(']')<cr> - nnoremap <silent> <buffer> [[ :sil call <SID>TreeListMove('[')<cr> - nnoremap <silent> <buffer> ]] :sil call <SID>TreeListMove(']')<cr> + if g:netrw_use_noswf + setl nobl bt=nofile noswf + else + setl nobl bt=nofile + endif + nnoremap <silent> <buffer> [[ :sil call <SID>TreeListMove('[[')<cr> + nnoremap <silent> <buffer> ]] :sil call <SID>TreeListMove(']]')<cr> + nnoremap <silent> <buffer> [] :sil call <SID>TreeListMove('[]')<cr> + nnoremap <silent> <buffer> ][ :sil call <SID>TreeListMove('][')<cr> " call Decho(" tree listing#".s:netrw_treelistnum." bufnr=".w:netrw_treebufnr,'~'.expand("<slnum>")) else " let v:errmsg = "" " Decho @@ -4043,6 +4021,10 @@ fun! s:NetrwGetBuffer(islocal,dirname) " let v:errmsg= "" " Decho exe 'sil! keepj keepalt file '.escdirname " call Decho(" errmsg<".v:errmsg."> bufnr(".escdirname.")=".bufnr(escdirname)."<".bufname(bufnr(escdirname)).">",'~'.expand("<slnum>")) + " enter the new buffer into the s:netrwbuf dictionary + let s:netrwbuf[s:NetrwFullPath(dirname)]= bufnr("%") +" call Decho("update netrwbuf dictionary: s:netrwbuf[".s:NetrwFullPath(dirname)."]=".bufnr("%"),'~'.expand("<slnum>")) +" call Decho("netrwbuf dictionary=".string(s:netrwbuf),'~'.expand("<slnum>")) endif " call Decho(" named enew buffer#".bufnr("%")."<".bufname("%").">",'~'.expand("<slnum>")) @@ -4050,7 +4032,7 @@ fun! s:NetrwGetBuffer(islocal,dirname) " call Decho("--re-use buffer#".bufnum." (bufnum#".bufnum.">=0 AND bufexists(".bufnum.")=".bufexists(bufnum)."!=0)",'~'.expand("<slnum>")) let eikeep= &ei setl ei=all - if getline(2) =~ '^" Netrw Directory Listing' + if getline(2) =~# '^" Netrw Directory Listing' " call Decho(" getline(2)<".getline(2).'> matches "Netrw Directory Listing" : using keepalt b '.bufnum,'~'.expand("<slnum>")) exe "sil! NetrwKeepj noswapfile keepalt b ".bufnum else @@ -4165,20 +4147,20 @@ fun! s:NetrwGetWord() let dirname= "./" let curline= getline('.') - if curline =~ '"\s*Sorted by\s' + if curline =~# '"\s*Sorted by\s' NetrwKeepj norm s let s:netrw_skipbrowse= 1 echo 'Pressing "s" also works' - elseif curline =~ '"\s*Sort sequence:' + elseif curline =~# '"\s*Sort sequence:' let s:netrw_skipbrowse= 1 echo 'Press "S" to edit sorting sequence' - elseif curline =~ '"\s*Quick Help:' + elseif curline =~# '"\s*Quick Help:' NetrwKeepj norm ? let s:netrw_skipbrowse= 1 - elseif curline =~ '"\s*\%(Hiding\|Showing\):' + elseif curline =~# '"\s*\%(Hiding\|Showing\):' NetrwKeepj norm a let s:netrw_skipbrowse= 1 echo 'Pressing "a" also works' @@ -4197,7 +4179,7 @@ fun! s:NetrwGetWord() NetrwKeepj norm! 0 let dirname= substitute(getline('.'),'^\(\%(\S\+ \)*\S\+\).\{-}$','\1','e') - elseif w:netrw_liststyle == s:TREELIST + elseif exists("w:netrw_liststyle") && w:netrw_liststyle == s:TREELIST " call Decho("treelist handling",'~'.expand("<slnum>")) let dirname= substitute(getline('.'),'^\('.s:treedepthstring.'\)*','','e') let dirname= substitute(dirname,'\t -->.*$','','') @@ -4286,7 +4268,8 @@ fun! s:NetrwListStyle(islocal) let ykeep = @@ let fname = s:NetrwGetWord() if !exists("w:netrw_liststyle")|let w:netrw_liststyle= g:netrw_liststyle|endif - let svpos = netrw#SavePosn() + let svpos = winsaveview() +" call Decho("saving posn to svpos<".string(svpos).">",'~'.expand("<slnum>")) let w:netrw_liststyle = (w:netrw_liststyle + 1) % s:MAXLIST " call Decho("fname<".fname.">",'~'.expand("<slnum>")) " call Decho("chgd w:netrw_liststyle to ".w:netrw_liststyle,'~'.expand("<slnum>")) @@ -4307,7 +4290,7 @@ fun! s:NetrwListStyle(islocal) " call Decho("use wide list",'~'.expand("<slnum>")) let g:netrw_list_cmd = substitute(g:netrw_list_cmd,' -l','','ge') - elseif w:netrw_liststyle == s:TREELIST + elseif exists("w:netrw_liststyle") && w:netrw_liststyle == s:TREELIST " call Decho("use tree list",'~'.expand("<slnum>")) let g:netrw_list_cmd = substitute(g:netrw_list_cmd,' -l','','ge') @@ -4334,7 +4317,8 @@ fun! s:NetrwListStyle(islocal) NetrwKeepj call s:NetrwCursor() " restore position; keep cursor on the filename - NetrwKeepj call netrw#RestorePosn(svpos) +" call Decho("restoring posn to svpos<".string(svpos).">",'~'.expand("<slnum>")) + NetrwKeepj call winrestview(svpos) let @@= ykeep " call Dret("NetrwListStyle".(exists("w:netrw_liststyle")? ' : w:netrw_liststyle='.w:netrw_liststyle : "")) @@ -4350,7 +4334,8 @@ fun! s:NetrwBannerCtrl(islocal) let g:netrw_banner= !g:netrw_banner " refresh the listing - let svpos= netrw#SavePosn() + let svpos= winsaveview() +" call Decho("saving posn to svpos<".string(svpos).">",'~'.expand("<slnum>")) call s:NetrwRefresh(a:islocal,s:NetrwBrowseChgDir(a:islocal,'./')) " keep cursor on the filename @@ -4385,7 +4370,8 @@ fun! s:NetrwBookmark(del,...) if exists("s:netrwmarkfilelist_{curbufnr}") " for every filename in the marked list " call Decho("bookmark every filename in marked list",'~'.expand("<slnum>")) - let svpos = netrw#SavePosn() + let svpos = winsaveview() +" call Decho("saving posn to svpos<".string(svpos).">",'~'.expand("<slnum>")) let islocal= expand("%") !~ '^\a\{3,}://' for fname in s:netrwmarkfilelist_{curbufnr} if a:del|call s:DeleteBookmark(fname)|else|call s:MakeBookmark(fname)|endif @@ -4393,7 +4379,8 @@ fun! s:NetrwBookmark(del,...) let curdir = exists("b:netrw_curdir")? b:netrw_curdir : getcwd() call s:NetrwUnmarkList(curbufnr,curdir) NetrwKeepj call s:NetrwRefresh(islocal,s:NetrwBrowseChgDir(islocal,'./')) - NetrwKeepj call netrw#RestorePosn(svpos) +" call Decho("restoring posn to svpos<".string(svpos).">",'~'.expand("<slnum>")) + NetrwKeepj call winrestview(svpos) else let fname= s:NetrwGetWord() if a:del|call s:DeleteBookmark(fname)|else|call s:MakeBookmark(fname)|endif @@ -4416,10 +4403,10 @@ fun! s:NetrwBookmark(del,...) let i = 1 while i <= a:0 if islocal - if v:version == 704 && has("patch656") - let mbfiles= glob(a:{i},0,1,1) + if v:version > 704 || (v:version == 704 && has("patch656")) + let mbfiles= glob(fnameescape(a:{i}),0,1,1) else - let mbfiles= glob(a:{i},0,1) + let mbfiles= glob(fnameescape(a:{i}),0,1) endif else let mbfiles= [a:{i}] @@ -4523,14 +4510,13 @@ fun! s:NetrwBrowseChgDir(islocal,newdir,...) " call Dret("s:NetrwBrowseChgDir") return endif +" call Decho("b:netrw_curdir<".b:netrw_curdir.">") " NetrwBrowseChgDir: save options and initialize {{{3 " call Decho("saving options",'~'.expand("<slnum>")) + call s:SavePosn(s:netrw_nbcd) NetrwKeepj call s:NetrwOptionSave("s:") NetrwKeepj call s:NetrwSafeOptions() - let nbcd_curpos = netrw#SavePosn() - let s:nbcd_curpos_{bufnr('%')} = nbcd_curpos -" call Decho("setting s:nbcd_curpos_".bufnr('%')." to SavePosn",'~'.expand("<slnum>")) if (has("win32") || has("win95") || has("win64") || has("win16")) let dirname = substitute(b:netrw_curdir,'\\','/','ge') else @@ -4546,14 +4532,14 @@ fun! s:NetrwBrowseChgDir(islocal,newdir,...) if g:netrw_banner " call Decho("w:netrw_bannercnt=".(exists("w:netrw_bannercnt")? w:netrw_bannercnt : 'n/a')." line(.)#".line('.')." line($)#".line("#"),'~'.expand("<slnum>")) if exists("w:netrw_bannercnt") && line(".") < w:netrw_bannercnt && line("$") >= w:netrw_bannercnt - if getline(".") =~ 'Quick Help' + if getline(".") =~# 'Quick Help' " call Decho("#1: quickhelp=".g:netrw_quickhelp." ro=".&l:ro." ma=".&l:ma." mod=".&l:mod." wrap=".&l:wrap." (filename<".expand("%")."> win#".winnr()." ft<".&ft.">)",'~'.expand("<slnum>")) let g:netrw_quickhelp= (g:netrw_quickhelp + 1)%len(s:QuickHelp) " call Decho("#2: quickhelp=".g:netrw_quickhelp." ro=".&l:ro." ma=".&l:ma." mod=".&l:mod." wrap=".&l:wrap." (filename<".expand("%")."> win#".winnr()." ft<".&ft.">)",'~'.expand("<slnum>")) setl ma noro nowrap NetrwKeepj call setline(line('.'),'" Quick Help: <F1>:help '.s:QuickHelp[g:netrw_quickhelp]) setl noma nomod nowrap - NetrwKeepj call netrw#RestorePosn(nbcd_curpos) + call s:RestorePosn(s:netrw_nbcd) NetrwKeepj call s:NetrwOptionRestore("s:") " call Decho("ro=".&l:ro." ma=".&l:ma." mod=".&l:mod." wrap=".&l:wrap." (filename<".expand("%")."> win#".winnr()." ft<".&ft.">)",'~'.expand("<slnum>")) endif @@ -4577,7 +4563,7 @@ fun! s:NetrwBrowseChgDir(islocal,newdir,...) " call Decho("adjusting dirname<".dirname.'> (put trailing "/" back)','~'.expand("<slnum>")) endif -" " call Decho("[newdir<".newdir."> ".((newdir =~ dirpat)? "=~" : "!~")." dirpat<".dirpat.">] && [islocal=".a:islocal."] && [newdir is ".(isdirectory(s:NetrwFile(newdir))? "" : "not ")."a directory]",'~'.expand("<slnum>")) +" call Decho("[newdir<".newdir."> ".((newdir =~ dirpat)? "=~" : "!~")." dirpat<".dirpat.">] && [islocal=".a:islocal."] && [newdir is ".(isdirectory(s:NetrwFile(newdir))? "" : "not ")."a directory]",'~'.expand("<slnum>")) if newdir !~ dirpat && !(a:islocal && isdirectory(s:NetrwFile(s:ComposePath(dirname,newdir)))) " ------------------------------ " NetrwBrowseChgDir: edit a file {{{3 @@ -4585,8 +4571,8 @@ fun! s:NetrwBrowseChgDir(islocal,newdir,...) " call Decho('edit-a-file: case "handling a file": newdir<'.newdir.'> !~ dirpat<'.dirpat.">",'~'.expand("<slnum>")) " save position for benefit of Rexplore - let s:rexposn_{bufnr("%")}= netrw#SavePosn() -" call Decho("edit-a-file: setting s:rexposn_".bufnr("%")."<".bufname("%")."> to SavePosn",'~'.expand("<slnum>")) + let s:rexposn_{bufnr("%")}= winsaveview() +" call Decho("edit-a-file: saving posn to s:rexposn_".bufnr("%")."<".string(s:rexposn_{bufnr("%")}).">",'~'.expand("<slnum>")) " call Decho("edit-a-file: win#".winnr()." buf#".bufnr("%")."<".bufname("%")."> ft=".&ft,'~'.expand("<slnum>")) " call Decho("edit-a-file: w:netrw_liststyle=".(exists("w:netrw_liststyle")? w:netrw_liststyle : 'n/a')." w:netrw_treedict:".(exists("w:netrw_treedict")? "exists" : 'n/a')." newdir<".newdir.">",'~'.expand("<slnum>")) @@ -4602,6 +4588,7 @@ fun! s:NetrwBrowseChgDir(islocal,newdir,...) " call Decho("edit-a-file: dirname<".dirname.">",'~'.expand("<slnum>")) " call Decho("edit-a-file: tree listing",'~'.expand("<slnum>")) elseif newdir =~ '^\(/\|\a:\)' +" call Decho("edit-a-file: handle an url or path starting with /: <".newdir.">",'~'.expand("<slnum>")) let dirname= newdir else let dirname= s:ComposePath(dirname,newdir) @@ -4609,8 +4596,9 @@ fun! s:NetrwBrowseChgDir(islocal,newdir,...) " call Decho("edit-a-file: handling a file: dirname<".dirname."> (a:0=".a:0.")",'~'.expand("<slnum>")) " this lets netrw#BrowseX avoid the edit if a:0 < 1 -" call Decho("edit-a-file: set up windows for editing<".fnameescape(dirname)."> didsplit=".(exists("s:didsplit")? s:didsplit : "doesn't exist"),'~'.expand("<slnum>")) +" call Decho("edit-a-file: (a:0=".a:0."<1) set up windows for editing<".fnameescape(dirname)."> didsplit=".(exists("s:didsplit")? s:didsplit : "doesn't exist"),'~'.expand("<slnum>")) NetrwKeepj call s:NetrwOptionRestore("s:") + let curdir= b:netrw_curdir if !exists("s:didsplit") " call Decho("edit-a-file: s:didsplit does not exist; g:netrw_browse_split=".string(g:netrw_browse_split)." win#".winnr(),'~'.expand("<slnum>")) if type(g:netrw_browse_split) == 3 @@ -4627,6 +4615,7 @@ fun! s:NetrwBrowseChgDir(islocal,newdir,...) if !&ea keepalt wincmd _ endif + call s:SetRexDir(a:islocal,curdir) elseif g:netrw_browse_split == 2 " vertically splitting the window first " call Decho("edit-a-file: vertically splitting window prior to edit",'~'.expand("<slnum>")) @@ -4634,10 +4623,15 @@ fun! s:NetrwBrowseChgDir(islocal,newdir,...) if !&ea keepalt wincmd | endif + call s:SetRexDir(a:islocal,curdir) elseif g:netrw_browse_split == 3 " open file in new tab " call Decho("edit-a-file: opening new tab prior to edit",'~'.expand("<slnum>")) keepalt tabnew + if !exists("b:netrw_curdir") + let b:netrw_curdir= getcwd() + endif + call s:SetRexDir(a:islocal,curdir) elseif g:netrw_browse_split == 4 " act like "P" (ie. open previous window) " call Decho("edit-a-file: use previous window for edit",'~'.expand("<slnum>")) @@ -4646,6 +4640,7 @@ fun! s:NetrwBrowseChgDir(islocal,newdir,...) " call Dret("s:NetrwBrowseChgDir") return endif + call s:SetRexDir(a:islocal,curdir) else " handling a file, didn't split, so remove menu " call Decho("edit-a-file: handling a file+didn't split, so remove menu",'~'.expand("<slnum>")) @@ -4663,6 +4658,7 @@ fun! s:NetrwBrowseChgDir(islocal,newdir,...) endif exe "NetrwKeepj keepalt ".g:netrw_chgwin."wincmd w" endif + call s:SetRexDir(a:islocal,curdir) endif endif @@ -4797,12 +4793,12 @@ fun! s:NetrwBrowseChgDir(islocal,newdir,...) endif let treedir = s:NetrwTreeDir(a:islocal) " call Decho("tree-list: treedir<".treedir.">",'~'.expand("<slnum>")) - let s:treecurpos = nbcd_curpos + let s:treecurpos = winsaveview() let haskey = 0 " call Decho("tree-list: w:netrw_treedict<".string(w:netrw_treedict).">",'~'.expand("<slnum>")) " search treedict for tree dir as-is -" call Decho("search treedict for tree dir as-is",'~'.expand("<slnum>")) +" call Decho("tree-list: search treedict for tree dir as-is",'~'.expand("<slnum>")) if has_key(w:netrw_treedict,treedir) " call Decho('tree-list: ....searched for treedir<'.treedir.'> : found it!','~'.expand("<slnum>")) let haskey= 1 @@ -4811,7 +4807,7 @@ fun! s:NetrwBrowseChgDir(islocal,newdir,...) endif " search treedict for treedir with a [/@] appended -" call Decho("search treedict for treedir with a [/@] appended",'~'.expand("<slnum>")) +" call Decho("tree-list: search treedict for treedir with a [/@] appended",'~'.expand("<slnum>")) if !haskey && treedir !~ '[/@]$' if has_key(w:netrw_treedict,treedir."/") let treedir= treedir."/" @@ -4823,7 +4819,7 @@ fun! s:NetrwBrowseChgDir(islocal,newdir,...) endif " search treedict for treedir with any trailing / elided -" call Decho("search treedict for treedir with any trailing / elided",'~'.expand("<slnum>")) +" call Decho("tree-list: search treedict for treedir with any trailing / elided",'~'.expand("<slnum>")) if !haskey && treedir =~ '/$' let treedir= substitute(treedir,'/$','','') if has_key(w:netrw_treedict,treedir) @@ -4873,6 +4869,7 @@ fun! s:NetrwBrowseChgDir(islocal,newdir,...) " else " Decho " call Decho("skipping option restore (dorestore==0): hidden=".&hidden." bufhidden=".&bufhidden." mod=".&mod,'~'.expand("<slnum>")) endif + call s:RestorePosn(s:netrw_nbcd) if dolockout && dorestore " call Decho("restore: filewritable(dirname<".dirname.">)=".filewritable(dirname),'~'.expand("<slnum>")) if filewritable(dirname) @@ -4908,6 +4905,10 @@ fun! s:NetrwBrowseUpDir(islocal) return endif + if !exists("w:netrw_liststyle") || w:netrw_liststyle != s:TREELIST + call s:SavePosn(s:netrw_nbcd) + endif + norm! 0 if exists("w:netrw_liststyle") && w:netrw_liststyle == s:TREELIST && exists("w:netrw_treedict") " call Decho("case: treestyle",'~'.expand("<slnum>")) @@ -4947,7 +4948,9 @@ fun! s:NetrwBrowseUpDir(islocal) else call s:NetrwBrowse(0,s:NetrwBrowseChgDir(0,'../')) endif - if exists("w:netrw_bannercnt") + if has_key(s:netrw_nbcd,bufnr("%")) + call s:RestorePosn(s:netrw_nbcd) + elseif exists("w:netrw_bannercnt") " call Decho("moving to line#".w:netrw_bannercnt,'~'.expand("<slnum>")) exe w:netrw_bannercnt else @@ -4967,14 +4970,15 @@ fun! netrw#BrowseX(fname,remote) " call Dfunc("netrw#BrowseX(fname<".a:fname."> remote=".a:remote.")") " if its really just a directory, then do a "gf" instead - if a:fname =~ '/$' + if (a:remote == 0 && isdirectory(a:fname)) || (a:remote == 1 && fname =~ '/$' && fname !~ '^https\=:') norm! gf " call Dret("netrw#BrowseX : did gf instead") endif let ykeep = @@ - let screenposn = netrw#SavePosn() + let screenposn = winsaveview() +" call Decho("saving posn to screenposn<".string(screenposn).">",'~'.expand("<slnum>")) " need to save and restore aw setting as gx can invoke this function from non-netrw buffers let awkeep = &aw @@ -4996,7 +5000,8 @@ fun! netrw#BrowseX(fname,remote) endif endfor endif - call netrw#RestorePosn(screenposn) +" call Decho("restoring posn to screenposn<".string(screenposn).">,'~'.expand("<slnum>"))" + call winrestview(screenposn) let @@= ykeep let &aw= awkeep " call Dret("netrw#BrowseX : coredump handler invoked") @@ -5041,17 +5046,20 @@ fun! netrw#BrowseX(fname,remote) " call Decho("fname<".fname.">",'~'.expand("<slnum>")) " call Decho("exten<".exten."> "."netrwFileHandlers#NFH_".exten."():exists=".exists("*netrwFileHandlers#NFH_".exten),'~'.expand("<slnum>")) - " set up redirection - if &srr =~ "%s" - if (has("win32") || has("win95") || has("win64") || has("win16")) - let redir= substitute(&srr,"%s","nul","") + " set up redirection (avoids browser messages) + " by default, g:netrw_suppress_gx_mesg is true + if g:netrw_suppress_gx_mesg + if &srr =~ "%s" + if (has("win32") || has("win95") || has("win64") || has("win16")) + let redir= substitute(&srr,"%s","nul","") + else + let redir= substitute(&srr,"%s","/dev/null","") + endif + elseif (has("win32") || has("win95") || has("win64") || has("win16")) + let redir= &srr . "nul" else - let redir= substitute(&srr,"%s","/dev/null","") + let redir= &srr . "/dev/null" endif - elseif (has("win32") || has("win95") || has("win64") || has("win16")) - let redir= &srr . "nul" - else - let redir= &srr . "/dev/null" endif " call Decho("set up redirection: redir{".redir."} srr{".&srr."}",'~'.expand("<slnum>")) @@ -5167,7 +5175,8 @@ fun! netrw#BrowseX(fname,remote) exe "sil! NetrwKeepj norm! \<c-o>" " redraw! endif - call netrw#RestorePosn(screenposn) +" call Decho("restoring posn to screenposn<".string(screenposn).">",'~'.expand("<slnum>")) + call winrestview(screenposn) let @@ = ykeep let &aw= awkeep @@ -5310,6 +5319,43 @@ fun! s:NetrwForceChgDir(islocal,newdir) endfun " --------------------------------------------------------------------- +" s:NetrwGlob: does glob() if local, remote listing otherwise {{{2 +" direntry: this is the name of the directory. Will be fnameescape'd to prevent wildcard handling by glob() +" expr : this is the expression to follow the directory. Will use s:ComposePath() +" pare =1: remove the current directory from the resulting glob() filelist +" =0: leave the current directory in the resulting glob() filelist +fun! s:NetrwGlob(direntry,expr,pare) +" call Dfunc("s:NetrwGlob(direntry<".a:direntry."> expr<".a:expr."> pare=".a:pare.")") + if netrw#CheckIfRemote() + keepalt 1sp + keepalt enew + let keep_liststyle = w:netrw_liststyle + let w:netrw_liststyle = s:THINLIST + if s:NetrwRemoteListing() == 0 + keepj keepalt %s@/@@ + let filelist= getline(1,$) + q! + else + " remote listing error -- leave treedict unchanged + let filelist= w:netrw_treedict[a:direntry] + endif + let w:netrw_liststyle= keep_liststyle + elseif v:version > 704 || (v:version == 704 && has("patch656")) + let filelist= glob(s:ComposePath(fnameescape(a:direntry),a:expr),0,1,1) + if a:pare + let filelist= map(filelist,'substitute(v:val, "^.*/", "", "")') + endif + else + let filelist= glob(s:ComposePath(fnameescape(a:direntry),a:expr),0,1) + if a:pare + let filelist= map(filelist,'substitute(v:val, "^.*/", "", "")') + endif + endif +" call Dret("s:NetrwGlob ".string(filelist)) + return filelist +endfun + +" --------------------------------------------------------------------- " s:NetrwForceFile: (gf support) Force treatment as a file {{{2 fun! s:NetrwForceFile(islocal,newfile) " call Dfunc("s:NetrwForceFile(islocal=".a:islocal." newdir<".a:newfile.">)") @@ -5336,7 +5382,8 @@ endfun fun! s:NetrwHide(islocal) " call Dfunc("NetrwHide(islocal=".a:islocal.") g:netrw_hide=".g:netrw_hide) let ykeep= @@ - let svpos= netrw#SavePosn() + let svpos= winsaveview() +" call Decho("saving posn to svpos<".string(svpos).">",'~'.expand("<slnum>")) if exists("s:netrwmarkfilelist_{bufnr('%')}") " call Decho("((g:netrw_hide == 1)? "unhide" : "hide")." files in markfilelist<".string(s:netrwmarkfilelist_{bufnr("%")}).">",'~'.expand("<slnum>")) @@ -5378,7 +5425,8 @@ fun! s:NetrwHide(islocal) endif NetrwKeepj call s:NetrwRefresh(a:islocal,s:NetrwBrowseChgDir(a:islocal,'./')) - NetrwKeepj call netrw#RestorePosn(svpos) +" call Decho("restoring posn to svpos<".string(svpos).">",'~'.expand("<slnum>")) + NetrwKeepj call winrestview(svpos) let @@= ykeep " call Dret("NetrwHide") endfun @@ -5390,7 +5438,8 @@ fun! s:NetrwHideEdit(islocal) let ykeep= @@ " save current cursor position - let svpos= netrw#SavePosn() + let svpos= winsaveview() +" call Decho("saving posn to svpos<".string(svpos).">",'~'.expand("<slnum>")) " get new hiding list from user call inputsave() @@ -5403,7 +5452,8 @@ fun! s:NetrwHideEdit(islocal) sil NetrwKeepj call s:NetrwRefresh(a:islocal,s:NetrwBrowseChgDir(a:islocal,"./")) " restore cursor position - call netrw#RestorePosn(svpos) +" call Decho("restoring posn to svpos<".string(svpos).">",'~'.expand("<slnum>")) + call winrestview(svpos) let @@= ykeep " call Dret("NetrwHideEdit") @@ -5415,7 +5465,8 @@ fun! s:NetrwHidden(islocal) " call Dfunc("s:NetrwHidden()") let ykeep= @@ " save current position - let svpos= netrw#SavePosn() + let svpos= winsaveview() +" call Decho("saving posn to svpos<".string(svpos).">",'~'.expand("<slnum>")) if g:netrw_list_hide =~ '\(^\|,\)\\(^\\|\\s\\s\\)\\zs\\.\\S\\+' " remove pattern from hiding list @@ -5428,7 +5479,8 @@ fun! s:NetrwHidden(islocal) " refresh screen and return to saved position NetrwKeepj call s:NetrwRefresh(a:islocal,s:NetrwBrowseChgDir(a:islocal,'./')) - NetrwKeepj call netrw#RestorePosn(svpos) +" call Decho("restoring posn to svpos<".string(svpos).">",'~'.expand("<slnum>")) + NetrwKeepj call winrestview(svpos) let @@= ykeep " call Dret("s:NetrwHidden") endfun @@ -5540,10 +5592,10 @@ fun! s:NetrwServerEdit(islocal,fname) if (islocal && isdirectory(s:NetrwFile(a:fname))) || (!islocal && a:fname =~ '/$') " handle directories in the local window -- not in the remote vim server - " user must have closed the NETRWSERVER window. Treat as a normal editing from netrw. + " user must have closed the NETRWSERVER window. Treat as normal editing from netrw. " call Decho("handling directory in client window",'~'.expand("<slnum>")) let g:netrw_browse_split= 0 - if exists("s:netrw_browse_split_".winnr()) + if exists("s:netrw_browse_split") && exists("s:netrw_browse_split_".winnr()) let g:netrw_browse_split= s:netrw_browse_split_{winnr()} unlet s:netrw_browse_split_{winnr()} endif @@ -5820,9 +5872,11 @@ fun! s:NetrwMakeDir(usrhost) if v:shell_error == 0 " refresh listing " call Decho("refresh listing",'~'.expand("<slnum>")) - let svpos= netrw#SavePosn() + let svpos= winsaveview() +" call Decho("saving posn to svpos<".string(svpos).">",'~'.expand("<slnum>")) call s:NetrwRefresh(1,s:NetrwBrowseChgDir(1,'./')) - call netrw#RestorePosn(svpos) +" call Decho("restoring posn to svpos<".string(svpos).">",'~'.expand("<slnum>")) + call winrestview(svpos) elseif !exists("g:netrw_quiet") call netrw#ErrorMsg(s:ERROR,"unable to make directory<".newdirname.">",26) endif @@ -5836,9 +5890,11 @@ fun! s:NetrwMakeDir(usrhost) call s:NetrwExe("sil! !".mkdircmd." ".s:ShellEscape(newdirname,1)) if v:shell_error == 0 " refresh listing - let svpos= netrw#SavePosn() + let svpos= winsaveview() +" call Decho("saving posn to svpos<".string(svpos).">",'~'.expand("<slnum>")) NetrwKeepj call s:NetrwRefresh(0,s:NetrwBrowseChgDir(0,'./')) - NetrwKeepj call netrw#RestorePosn(svpos) +" call Decho("restoring posn to svpos<".string(svpos).">",'~'.expand("<slnum>")) + NetrwKeepj call winrestview(svpos) elseif !exists("g:netrw_quiet") NetrwKeepj call netrw#ErrorMsg(s:ERROR,"unable to make directory<".newdirname.">",27) endif @@ -5846,7 +5902,8 @@ fun! s:NetrwMakeDir(usrhost) elseif b:netrw_method == 2 " Remote mkdir: using ftp+.netrc - let svpos= netrw#SavePosn() + let svpos= winsaveview() +" call Decho("saving posn to svpos<".string(svpos).">",'~'.expand("<slnum>")) " call Decho("b:netrw_curdir<".b:netrw_curdir.">",'~'.expand("<slnum>")) if exists("b:netrw_fname") " call Decho("b:netrw_fname<".b:netrw_fname.">",'~'.expand("<slnum>")) @@ -5856,11 +5913,13 @@ fun! s:NetrwMakeDir(usrhost) endif call s:NetrwRemoteFtpCmd(remotepath,g:netrw_remote_mkdir.' "'.newdirname.'"') NetrwKeepj call s:NetrwRefresh(0,s:NetrwBrowseChgDir(0,'./')) - NetrwKeepj call netrw#RestorePosn(svpos) +" call Decho("restoring posn to svpos<".string(svpos).">",'~'.expand("<slnum>")) + NetrwKeepj call winrestview(svpos) elseif b:netrw_method == 3 " Remote mkdir: using ftp + machine, id, passwd, and fname (ie. no .netrc) - let svpos= netrw#SavePosn() + let svpos= winsaveview() +" call Decho("saving posn to svpos<".string(svpos).">",'~'.expand("<slnum>")) " call Decho("b:netrw_curdir<".b:netrw_curdir.">",'~'.expand("<slnum>")) if exists("b:netrw_fname") " call Decho("b:netrw_fname<".b:netrw_fname.">",'~'.expand("<slnum>")) @@ -5870,7 +5929,8 @@ fun! s:NetrwMakeDir(usrhost) endif call s:NetrwRemoteFtpCmd(remotepath,g:netrw_remote_mkdir.' "'.newdirname.'"') NetrwKeepj call s:NetrwRefresh(0,s:NetrwBrowseChgDir(0,'./')) - NetrwKeepj call netrw#RestorePosn(svpos) +" call Decho("restoring posn to svpos<".string(svpos).">",'~'.expand("<slnum>")) + NetrwKeepj call winrestview(svpos) endif let @@= ykeep @@ -5884,22 +5944,30 @@ fun! s:TreeSqueezeDir(islocal) if exists("w:netrw_liststyle") && w:netrw_liststyle == s:TREELIST && exists("w:netrw_treedict") " its a tree-listing style let curdepth = substitute(getline('.'),'^\(\%('.s:treedepthstring.'\)*\)[^'.s:treedepthstring.'].\{-}$','\1','e') - let iline = line(".") - 1 let stopline = (exists("w:netrw_bannercnt")? (w:netrw_bannercnt + 1) : 1) -" call Decho("curdepth=".curdepth,'~'.expand("<slnum>")) + let depth = strchars(substitute(curdepth,' ','','g')) + let srch = -1 +" call Decho("curdepth<".curdepth.'>','~'.expand("<slnum>")) +" call Decho("depth =".depth,'~'.expand("<slnum>")) " call Decho("stopline#".stopline,'~'.expand("<slnum>")) -" call Decho("starting with line#".line(".").": ".getline('.'),'~'.expand("<slnum>")) - while iline > stopline - " find a line that has less depth - let depth = substitute(getline('.'),'^\(\%('.s:treedepthstring.'\)*\)[^'.s:treedepthstring.'].\{-}$','\1','e') -" call Decho("considering line#".line(".").": ".getline('.'),'~'.expand("<slnum>")) - if depth < curdepth - break - endif - norm! k - endwhile -" call Decho("squeezing at line#".line(".").": ".getline('.'),'~'.expand("<slnum>")) - call s:NetrwBrowse(a:islocal,s:NetrwBrowseChgDir(a:islocal,s:NetrwGetWord())) +" call Decho("curline#".line(".")."<".getline('.').'>','~'.expand("<slnum>")) + if depth >= 2 + NetrwKeepj norm! 0 + let curdepthm1= substitute(curdepth,'^'.s:treedepthstring,'','') + let srch = search('^'.curdepthm1.'\%('.s:treedepthstring.'\)\@!','bW',stopline) +" call Decho("curdepthm1<".curdepthm1.'>','~'.expand("<slnum>")) +" call Decho("case depth>=2: srch<".srch.'>','~'.expand("<slnum>")) + elseif depth == 1 + NetrwKeepj norm! 0 + let treedepthchr= substitute(s:treedepthstring,' ','','') + let srch = search('^[^'.treedepthchr.']','bW',stopline) +" call Decho("case depth==1: srch<".srch.'>','~'.expand("<slnum>")) + endif + if srch > 0 +" call Decho("squeezing at line#".line(".").": ".getline('.'),'~'.expand("<slnum>")) + call s:NetrwBrowse(a:islocal,s:NetrwBrowseChgDir(a:islocal,s:NetrwGetWord())) + exe srch + endif endif " call Dret("s:TreeSqueezeDir") endfun @@ -5927,23 +5995,24 @@ fun! s:NetrwMaps(islocal) if a:islocal " call Decho("make local maps",'~'.expand("<slnum>")) " local normal-mode maps - nnoremap <buffer> <silent> <nowait> a :call <SID>NetrwHide(1)<cr> - nnoremap <buffer> <silent> <nowait> % :call <SID>NetrwOpenFile(1)<cr> - nnoremap <buffer> <silent> <nowait> c :call <SID>NetrwLcd(b:netrw_curdir)<cr> + nnoremap <buffer> <silent> <nowait> a :<c-u>call <SID>NetrwHide(1)<cr> + nnoremap <buffer> <silent> <nowait> - :<c-u>call <SID>NetrwBrowseUpDir(1)<cr> + nnoremap <buffer> <silent> <nowait> % :<c-u>call <SID>NetrwOpenFile(1)<cr> + nnoremap <buffer> <silent> <nowait> c :<c-u>call <SID>NetrwLcd(b:netrw_curdir)<cr> nnoremap <buffer> <silent> <nowait> C :<c-u>call <SID>NetrwSetChgwin()<cr> - nnoremap <buffer> <silent> <nowait> <cr> :call netrw#LocalBrowseCheck(<SID>NetrwBrowseChgDir(1,<SID>NetrwGetWord()))<cr> - nnoremap <buffer> <silent> <nowait> <s-cr> :call <SID>TreeSqueezeDir(1)<cr> - nnoremap <buffer> <silent> <nowait> <c-r> :call <SID>NetrwServerEdit(3,<SID>NetrwGetWord())<cr> - nnoremap <buffer> <silent> <nowait> d :call <SID>NetrwMakeDir("")<cr> - nnoremap <buffer> <silent> <nowait> - :call <SID>NetrwBrowseUpDir(1)<cr> + nnoremap <buffer> <silent> <nowait> <cr> :<c-u>call netrw#LocalBrowseCheck(<SID>NetrwBrowseChgDir(1,<SID>NetrwGetWord()))<cr> + nnoremap <buffer> <silent> <nowait> <c-r> :<c-u>call <SID>NetrwServerEdit(3,<SID>NetrwGetWord())<cr> + nnoremap <buffer> <silent> <nowait> d :<c-u>call <SID>NetrwMakeDir("")<cr> nnoremap <buffer> <silent> <nowait> gb :<c-u>call <SID>NetrwBookHistHandler(1,b:netrw_curdir)<cr> nnoremap <buffer> <silent> <nowait> gd :<c-u>call <SID>NetrwForceChgDir(1,<SID>NetrwGetWord())<cr> nnoremap <buffer> <silent> <nowait> gf :<c-u>call <SID>NetrwForceFile(1,<SID>NetrwGetWord())<cr> nnoremap <buffer> <silent> <nowait> gh :<c-u>call <SID>NetrwHidden(1)<cr> nnoremap <buffer> <silent> <nowait> gn :<c-u>call netrw#SetTreetop(<SID>NetrwGetWord())<cr> nnoremap <buffer> <silent> <nowait> gp :<c-u>call <SID>NetrwChgPerm(1,b:netrw_curdir)<cr> - nnoremap <buffer> <silent> <nowait> I :call <SID>NetrwBannerCtrl(1)<cr> - nnoremap <buffer> <silent> <nowait> i :call <SID>NetrwListStyle(1)<cr> + nnoremap <buffer> <silent> <nowait> I :<c-u>call <SID>NetrwBannerCtrl(1)<cr> + nnoremap <buffer> <silent> <nowait> i :<c-u>call <SID>NetrwListStyle(1)<cr> + nnoremap <buffer> <silent> <nowait> ma :<c-u>call <SID>NetrwMarkFileArgList(1,0)<cr> + nnoremap <buffer> <silent> <nowait> mA :<c-u>call <SID>NetrwMarkFileArgList(1,1)<cr> nnoremap <buffer> <silent> <nowait> mb :<c-u>call <SID>NetrwBookHistHandler(0,b:netrw_curdir)<cr> nnoremap <buffer> <silent> <nowait> mB :<c-u>call <SID>NetrwBookHistHandler(6,b:netrw_curdir)<cr> nnoremap <buffer> <silent> <nowait> mc :<c-u>call <SID>NetrwMarkFileCopy(1)<cr> @@ -5957,104 +6026,110 @@ fun! s:NetrwMaps(islocal) nnoremap <buffer> <silent> <nowait> mp :<c-u>call <SID>NetrwMarkFilePrint(1)<cr> nnoremap <buffer> <silent> <nowait> mr :<c-u>call <SID>NetrwMarkFileRegexp(1)<cr> nnoremap <buffer> <silent> <nowait> ms :<c-u>call <SID>NetrwMarkFileSource(1)<cr> - nnoremap <buffer> <silent> <nowait> mt :<c-u>call <SID>NetrwMarkFileTgt(1)<cr> nnoremap <buffer> <silent> <nowait> mT :<c-u>call <SID>NetrwMarkFileTag(1)<cr> + nnoremap <buffer> <silent> <nowait> mt :<c-u>call <SID>NetrwMarkFileTgt(1)<cr> nnoremap <buffer> <silent> <nowait> mu :<c-u>call <SID>NetrwUnMarkFile(1)<cr> nnoremap <buffer> <silent> <nowait> mv :<c-u>call <SID>NetrwMarkFileVimCmd(1)<cr> nnoremap <buffer> <silent> <nowait> mx :<c-u>call <SID>NetrwMarkFileExe(1,0)<cr> nnoremap <buffer> <silent> <nowait> mX :<c-u>call <SID>NetrwMarkFileExe(1,1)<cr> nnoremap <buffer> <silent> <nowait> mz :<c-u>call <SID>NetrwMarkFileCompress(1)<cr> - nnoremap <buffer> <silent> <nowait> O :call <SID>NetrwObtain(1)<cr> + nnoremap <buffer> <silent> <nowait> O :<c-u>call <SID>NetrwObtain(1)<cr> nnoremap <buffer> <silent> <nowait> o :call <SID>NetrwSplit(3)<cr> - nnoremap <buffer> <silent> <nowait> p :call <SID>NetrwPreview(<SID>NetrwBrowseChgDir(1,<SID>NetrwGetWord(),1))<cr> - nnoremap <buffer> <silent> <nowait> P :call <SID>NetrwPrevWinOpen(1)<cr> + nnoremap <buffer> <silent> <nowait> p :<c-u>call <SID>NetrwPreview(<SID>NetrwBrowseChgDir(1,<SID>NetrwGetWord(),1))<cr> + nnoremap <buffer> <silent> <nowait> P :<c-u>call <SID>NetrwPrevWinOpen(1)<cr> nnoremap <buffer> <silent> <nowait> qb :<c-u>call <SID>NetrwBookHistHandler(2,b:netrw_curdir)<cr> nnoremap <buffer> <silent> <nowait> qf :<c-u>call <SID>NetrwFileInfo(1,<SID>NetrwGetWord())<cr> nnoremap <buffer> <silent> <nowait> qF :<c-u>call <SID>NetrwMarkFileQFEL(1,getqflist())<cr> - nnoremap <buffer> <silent> <nowait> r :let g:netrw_sort_direction= (g:netrw_sort_direction =~ 'n')? 'r' : 'n'<bar>exe "norm! 0"<bar>call <SID>NetrwRefresh(1,<SID>NetrwBrowseChgDir(1,'./'))<cr> + nnoremap <buffer> <silent> <nowait> qL :<c-u>call <SID>NetrwMarkFileQFEL(1,getloclist(v:count))<cr> + nnoremap <buffer> <silent> <nowait> r :<c-u>let g:netrw_sort_direction= (g:netrw_sort_direction =~# 'n')? 'r' : 'n'<bar>exe "norm! 0"<bar>call <SID>NetrwRefresh(1,<SID>NetrwBrowseChgDir(1,'./'))<cr> nnoremap <buffer> <silent> <nowait> s :call <SID>NetrwSortStyle(1)<cr> - nnoremap <buffer> <silent> <nowait> S :call <SID>NetSortSequence(1)<cr> + nnoremap <buffer> <silent> <nowait> S :<c-u>call <SID>NetSortSequence(1)<cr> + nnoremap <buffer> <silent> <nowait> Tb :<c-u>call <SID>NetrwSetTgt(1,'b',v:count1)<cr> nnoremap <buffer> <silent> <nowait> t :call <SID>NetrwSplit(4)<cr> - nnoremap <buffer> <silent> <nowait> Tb :<c-u>call <SID>NetrwSetTgt('b',v:count1)<cr> - nnoremap <buffer> <silent> <nowait> Th :<c-u>call <SID>NetrwSetTgt('h',v:count)<cr> + nnoremap <buffer> <silent> <nowait> Th :<c-u>call <SID>NetrwSetTgt(1,'h',v:count)<cr> nnoremap <buffer> <silent> <nowait> u :<c-u>call <SID>NetrwBookHistHandler(4,expand("%"))<cr> nnoremap <buffer> <silent> <nowait> U :<c-u>call <SID>NetrwBookHistHandler(5,expand("%"))<cr> nnoremap <buffer> <silent> <nowait> v :call <SID>NetrwSplit(5)<cr> - nnoremap <buffer> <silent> <nowait> x :call netrw#BrowseX(<SID>NetrwBrowseChgDir(1,<SID>NetrwGetWord(),0),0)"<cr> - nnoremap <buffer> <silent> <nowait> X :call <SID>NetrwLocalExecute(expand("<cword>"))"<cr> - " local insert-mode maps - inoremap <buffer> <silent> <nowait> a <c-o>:call <SID>NetrwHide(1)<cr> - inoremap <buffer> <silent> <nowait> c <c-o>:exe "NetrwKeepj lcd ".fnameescape(b:netrw_curdir)<cr> - inoremap <buffer> <silent> <nowait> c <c-o>:call <SID>NetrwLcd(b:netrw_curdir)<cr> - inoremap <buffer> <silent> <nowait> C <c-o>:call <SID>NetrwSetChgwin()<cr> - inoremap <buffer> <silent> <nowait> % <c-o>:call <SID>NetrwOpenFile(1)<cr> - inoremap <buffer> <silent> <nowait> - <c-o>:call <SID>NetrwBrowseUpDir(1)<cr> - inoremap <buffer> <silent> <nowait> <cr> <c-o>:call netrw#LocalBrowseCheck(<SID>NetrwBrowseChgDir(1,<SID>NetrwGetWord()))<cr> - inoremap <buffer> <silent> <nowait> <s-cr> <c-o>:call <SID>TreeSqueezeDir(1)<cr> - inoremap <buffer> <silent> <nowait> d <c-o>:call <SID>NetrwMakeDir("")<cr> - inoremap <buffer> <silent> <nowait> gb <c-o>:<c-u>call <SID>NetrwBookHistHandler(1,b:netrw_curdir)<cr> - inoremap <buffer> <silent> <nowait> gh <c-o>:<c-u>call <SID>NetrwHidden(1)<cr> - nnoremap <buffer> <silent> <nowait> gn :<c-u>call netrw#SetTreetop(<SID>NetrwGetWord())<cr> - inoremap <buffer> <silent> <nowait> gp <c-o>:<c-u>call <SID>NetrwChgPerm(1,b:netrw_curdir)<cr> - inoremap <buffer> <silent> <nowait> I <c-o>:call <SID>NetrwBannerCtrl(1)<cr> - inoremap <buffer> <silent> <nowait> i <c-o>:call <SID>NetrwListStyle(1)<cr> - inoremap <buffer> <silent> <nowait> mb <c-o>:<c-u>call <SID>NetrwBookHistHandler(0,b:netrw_curdir)<cr> - inoremap <buffer> <silent> <nowait> mB <c-o>:<c-u>call <SID>NetrwBookHistHandler(6,b:netrw_curdir)<cr> - inoremap <buffer> <silent> <nowait> mc <c-o>:<c-u>call <SID>NetrwMarkFileCopy(1)<cr> - inoremap <buffer> <silent> <nowait> md <c-o>:<c-u>call <SID>NetrwMarkFileDiff(1)<cr> - inoremap <buffer> <silent> <nowait> me <c-o>:<c-u>call <SID>NetrwMarkFileEdit(1)<cr> - inoremap <buffer> <silent> <nowait> mf <c-o>:<c-u>call <SID>NetrwMarkFile(1,<SID>NetrwGetWord())<cr> - inoremap <buffer> <silent> <nowait> mg <c-o>:<c-u>call <SID>NetrwMarkFileGrep(1)<cr> - inoremap <buffer> <silent> <nowait> mh <c-o>:<c-u>call <SID>NetrwMarkHideSfx(1)<cr> - inoremap <buffer> <silent> <nowait> mm <c-o>:<c-u>call <SID>NetrwMarkFileMove(1)<cr> - inoremap <buffer> <silent> <nowait> mp <c-o>:<c-u>call <SID>NetrwMarkFilePrint(1)<cr> - inoremap <buffer> <silent> <nowait> mr <c-o>:<c-u>call <SID>NetrwMarkFileRegexp(1)<cr> - inoremap <buffer> <silent> <nowait> ms <c-o>:<c-u>call <SID>NetrwMarkFileSource(1)<cr> - inoremap <buffer> <silent> <nowait> mT <c-o>:<c-u>call <SID>NetrwMarkFileTag(1)<cr> - inoremap <buffer> <silent> <nowait> mt <c-o>:<c-u>call <SID>NetrwMarkFileTgt(1)<cr> - inoremap <buffer> <silent> <nowait> mu <c-o>:<c-u>call <SID>NetrwUnMarkFile(1)<cr> - inoremap <buffer> <silent> <nowait> mv <c-o>:<c-u>call <SID>NetrwMarkFileVimCmd(1)<cr> - inoremap <buffer> <silent> <nowait> mx <c-o>:<c-u>call <SID>NetrwMarkFileExe(1,0)<cr> - inoremap <buffer> <silent> <nowait> mX <c-o>:<c-u>call <SID>NetrwMarkFileExe(1,1)<cr> - inoremap <buffer> <silent> <nowait> mz <c-o>:<c-u>call <SID>NetrwMarkFileCompress(1)<cr> - inoremap <buffer> <silent> <nowait> O <c-o>:call <SID>NetrwObtain(1)<cr> - inoremap <buffer> <silent> <nowait> o <c-o>:call <SID>NetrwSplit(3)<cr> - inoremap <buffer> <silent> <nowait> p <c-o>:call <SID>NetrwPreview(<SID>NetrwBrowseChgDir(1,<SID>NetrwGetWord(),1))<cr> - inoremap <buffer> <silent> <nowait> P <c-o>:call <SID>NetrwPrevWinOpen(1)<cr> - inoremap <buffer> <silent> <nowait> qb <c-o>:<c-u>call <SID>NetrwBookHistHandler(2,b:netrw_curdir)<cr> - inoremap <buffer> <silent> <nowait> qf <c-o>:<c-u>call <SID>NetrwFileInfo(1,<SID>NetrwGetWord())<cr> - inoremap <buffer> <silent> <nowait> qF :<c-u>call <SID>NetrwMarkFileQFEL(1,getqflist())<cr> - inoremap <buffer> <silent> <nowait> r <c-o>:let g:netrw_sort_direction= (g:netrw_sort_direction =~ 'n')? 'r' : 'n'<bar>exe "norm! 0"<bar>call <SID>NetrwRefresh(1,<SID>NetrwBrowseChgDir(1,'./'))<cr> - inoremap <buffer> <silent> <nowait> s <c-o>:call <SID>NetrwSortStyle(1)<cr> - inoremap <buffer> <silent> <nowait> S <c-o>:call <SID>NetSortSequence(1)<cr> - inoremap <buffer> <silent> <nowait> t <c-o>:call <SID>NetrwSplit(4)<cr> - inoremap <buffer> <silent> <nowait> Tb <c-o>:<c-u>call <SID>NetrwSetTgt('b',v:count1)<cr> - inoremap <buffer> <silent> <nowait> Th <c-o>:<c-u>call <SID>NetrwSetTgt('h',v:count)<cr> - inoremap <buffer> <silent> <nowait> u <c-o>:<c-u>call <SID>NetrwBookHistHandler(4,expand("%"))<cr> - inoremap <buffer> <silent> <nowait> U <c-o>:<c-u>call <SID>NetrwBookHistHandler(5,expand("%"))<cr> - inoremap <buffer> <silent> <nowait> v <c-o>:call <SID>NetrwSplit(5)<cr> - inoremap <buffer> <silent> <nowait> x <c-o>:call netrw#BrowseX(<SID>NetrwBrowseChgDir(1,<SID>NetrwGetWord(),0),0)"<cr> + nnoremap <buffer> <silent> <nowait> x :<c-u>call netrw#BrowseX(<SID>NetrwBrowseChgDir(1,<SID>NetrwGetWord(),0),0)"<cr> + nnoremap <buffer> <silent> <nowait> X :<c-u>call <SID>NetrwLocalExecute(expand("<cword>"))"<cr> +" " local insert-mode maps +" inoremap <buffer> <silent> <nowait> a <c-o>:call <SID>NetrwHide(1)<cr> +" inoremap <buffer> <silent> <nowait> c <c-o>:exe "NetrwKeepj lcd ".fnameescape(b:netrw_curdir)<cr> +" inoremap <buffer> <silent> <nowait> c <c-o>:call <SID>NetrwLcd(b:netrw_curdir)<cr> +" inoremap <buffer> <silent> <nowait> C <c-o>:call <SID>NetrwSetChgwin()<cr> +" inoremap <buffer> <silent> <nowait> % <c-o>:call <SID>NetrwOpenFile(1)<cr> +" inoremap <buffer> <silent> <nowait> - <c-o>:call <SID>NetrwBrowseUpDir(1)<cr> +" inoremap <buffer> <silent> <nowait> <cr> <c-o>:call netrw#LocalBrowseCheck(<SID>NetrwBrowseChgDir(1,<SID>NetrwGetWord()))<cr> +" inoremap <buffer> <silent> <nowait> d <c-o>:call <SID>NetrwMakeDir("")<cr> +" inoremap <buffer> <silent> <nowait> gb <c-o>:<c-u>call <SID>NetrwBookHistHandler(1,b:netrw_curdir)<cr> +" inoremap <buffer> <silent> <nowait> gh <c-o>:<c-u>call <SID>NetrwHidden(1)<cr> +" nnoremap <buffer> <silent> <nowait> gn :<c-u>call netrw#SetTreetop(<SID>NetrwGetWord())<cr> +" inoremap <buffer> <silent> <nowait> gp <c-o>:<c-u>call <SID>NetrwChgPerm(1,b:netrw_curdir)<cr> +" inoremap <buffer> <silent> <nowait> I <c-o>:call <SID>NetrwBannerCtrl(1)<cr> +" inoremap <buffer> <silent> <nowait> i <c-o>:call <SID>NetrwListStyle(1)<cr> +" inoremap <buffer> <silent> <nowait> mb <c-o>:<c-u>call <SID>NetrwBookHistHandler(0,b:netrw_curdir)<cr> +" inoremap <buffer> <silent> <nowait> mB <c-o>:<c-u>call <SID>NetrwBookHistHandler(6,b:netrw_curdir)<cr> +" inoremap <buffer> <silent> <nowait> mc <c-o>:<c-u>call <SID>NetrwMarkFileCopy(1)<cr> +" inoremap <buffer> <silent> <nowait> md <c-o>:<c-u>call <SID>NetrwMarkFileDiff(1)<cr> +" inoremap <buffer> <silent> <nowait> me <c-o>:<c-u>call <SID>NetrwMarkFileEdit(1)<cr> +" inoremap <buffer> <silent> <nowait> mf <c-o>:<c-u>call <SID>NetrwMarkFile(1,<SID>NetrwGetWord())<cr> +" inoremap <buffer> <silent> <nowait> mg <c-o>:<c-u>call <SID>NetrwMarkFileGrep(1)<cr> +" inoremap <buffer> <silent> <nowait> mh <c-o>:<c-u>call <SID>NetrwMarkHideSfx(1)<cr> +" inoremap <buffer> <silent> <nowait> mm <c-o>:<c-u>call <SID>NetrwMarkFileMove(1)<cr> +" inoremap <buffer> <silent> <nowait> mp <c-o>:<c-u>call <SID>NetrwMarkFilePrint(1)<cr> +" inoremap <buffer> <silent> <nowait> mr <c-o>:<c-u>call <SID>NetrwMarkFileRegexp(1)<cr> +" inoremap <buffer> <silent> <nowait> ms <c-o>:<c-u>call <SID>NetrwMarkFileSource(1)<cr> +" inoremap <buffer> <silent> <nowait> mT <c-o>:<c-u>call <SID>NetrwMarkFileTag(1)<cr> +" inoremap <buffer> <silent> <nowait> mt <c-o>:<c-u>call <SID>NetrwMarkFileTgt(1)<cr> +" inoremap <buffer> <silent> <nowait> mu <c-o>:<c-u>call <SID>NetrwUnMarkFile(1)<cr> +" inoremap <buffer> <silent> <nowait> mv <c-o>:<c-u>call <SID>NetrwMarkFileVimCmd(1)<cr> +" inoremap <buffer> <silent> <nowait> mx <c-o>:<c-u>call <SID>NetrwMarkFileExe(1,0)<cr> +" inoremap <buffer> <silent> <nowait> mX <c-o>:<c-u>call <SID>NetrwMarkFileExe(1,1)<cr> +" inoremap <buffer> <silent> <nowait> mz <c-o>:<c-u>call <SID>NetrwMarkFileCompress(1)<cr> +" inoremap <buffer> <silent> <nowait> O <c-o>:call <SID>NetrwObtain(1)<cr> +" inoremap <buffer> <silent> <nowait> o <c-o>:call <SID>NetrwSplit(3)<cr> +" inoremap <buffer> <silent> <nowait> p <c-o>:call <SID>NetrwPreview(<SID>NetrwBrowseChgDir(1,<SID>NetrwGetWord(),1))<cr> +" inoremap <buffer> <silent> <nowait> P <c-o>:call <SID>NetrwPrevWinOpen(1)<cr> +" inoremap <buffer> <silent> <nowait> qb <c-o>:<c-u>call <SID>NetrwBookHistHandler(2,b:netrw_curdir)<cr> +" inoremap <buffer> <silent> <nowait> qf <c-o>:<c-u>call <SID>NetrwFileInfo(1,<SID>NetrwGetWord())<cr> +" inoremap <buffer> <silent> <nowait> qF :<c-u>call <SID>NetrwMarkFileQFEL(1,getqflist())<cr> +" inoremap <buffer> <silent> <nowait> qL :<c-u>call <SID>NetrwMarkFileQFEL(1,getloclist(v:count))<cr> +" inoremap <buffer> <silent> <nowait> r <c-o>:let g:netrw_sort_direction= (g:netrw_sort_direction =~# 'n')? 'r' : 'n'<bar>exe "norm! 0"<bar>call <SID>NetrwRefresh(1,<SID>NetrwBrowseChgDir(1,'./'))<cr> +" inoremap <buffer> <silent> <nowait> s <c-o>:call <SID>NetrwSortStyle(1)<cr> +" inoremap <buffer> <silent> <nowait> S <c-o>:call <SID>NetSortSequence(1)<cr> +" inoremap <buffer> <silent> <nowait> t <c-o>:call <SID>NetrwSplit(4)<cr> +" inoremap <buffer> <silent> <nowait> Tb <c-o>:<c-u>call <SID>NetrwSetTgt(1,'b',v:count1)<cr> +" inoremap <buffer> <silent> <nowait> Th <c-o>:<c-u>call <SID>NetrwSetTgt(1,'h',v:count)<cr> +" inoremap <buffer> <silent> <nowait> u <c-o>:<c-u>call <SID>NetrwBookHistHandler(4,expand("%"))<cr> +" inoremap <buffer> <silent> <nowait> U <c-o>:<c-u>call <SID>NetrwBookHistHandler(5,expand("%"))<cr> +" inoremap <buffer> <silent> <nowait> v <c-o>:call <SID>NetrwSplit(5)<cr> +" inoremap <buffer> <silent> <nowait> x <c-o>:call netrw#BrowseX(<SID>NetrwBrowseChgDir(1,<SID>NetrwGetWord(),0),0)"<cr> if !hasmapto('<Plug>NetrwHideEdit') nmap <buffer> <unique> <c-h> <Plug>NetrwHideEdit - imap <buffer> <unique> <c-h> <Plug>NetrwHideEdit +" imap <buffer> <unique> <c-h> <c-o><Plug>NetrwHideEdit endif - nnoremap <buffer> <silent> <Plug>NetrwHideEdit :call <SID>NetrwHideEdit(1)<cr> + nnoremap <buffer> <silent> <Plug>NetrwHideEdit :call <SID>NetrwHideEdit(1)<cr> if !hasmapto('<Plug>NetrwRefresh') nmap <buffer> <unique> <c-l> <Plug>NetrwRefresh - imap <buffer> <unique> <c-l> <Plug>NetrwRefresh +" imap <buffer> <unique> <c-l> <c-o><Plug>NetrwRefresh endif - nnoremap <buffer> <silent> <Plug>NetrwRefresh :call <SID>NetrwRefresh(1,<SID>NetrwBrowseChgDir(1,(w:netrw_liststyle == 3)? w:netrw_treetop : './'))<cr> + nnoremap <buffer> <silent> <Plug>NetrwRefresh <c-l>:call <SID>NetrwRefresh(1,<SID>NetrwBrowseChgDir(1,(w:netrw_liststyle == 3)? w:netrw_treetop : './'))<cr> if s:didstarstar || !mapcheck("<s-down>","n") nnoremap <buffer> <silent> <s-down> :Nexplore<cr> - inoremap <buffer> <silent> <s-down> :Nexplore<cr> +" inoremap <buffer> <silent> <s-down> <c-o>:Nexplore<cr> endif if s:didstarstar || !mapcheck("<s-up>","n") nnoremap <buffer> <silent> <s-up> :Pexplore<cr> - inoremap <buffer> <silent> <s-up> :Pexplore<cr> +" inoremap <buffer> <silent> <s-up> <c-o>:Pexplore<cr> endif + if !hasmapto('<Plug>NetrwTreeSqueeze') + nmap <buffer> <silent> <nowait> <s-cr> <Plug>NetrwTreeSqueeze +" imap <buffer> <silent> <nowait> <s-cr> <c-o><Plug>NetrwTreeSqueeze + endif + nnoremap <buffer> <silent> <Plug>NetrwTreeSqueeze :call <SID>TreeSqueezeDir(1)<cr> let mapsafecurdir = escape(b:netrw_curdir, s:netrw_map_escape) if g:netrw_mousemaps == 1 - nmap <buffer> <leftmouse> <Plug>NetrwLeftmouse + nmap <buffer> <leftmouse> <Plug>NetrwLeftmouse nno <buffer> <silent> <Plug>NetrwLeftmouse <leftmouse>:call <SID>NetrwLeftmouse(1)<cr> nmap <buffer> <c-leftmouse> <Plug>NetrwCLeftmouse nno <buffer> <silent> <Plug>NetrwCLeftmouse <leftmouse>:call <SID>NetrwCLeftmouse(1)<cr> @@ -6067,14 +6142,14 @@ fun! s:NetrwMaps(islocal) nmap <buffer> <2-leftmouse> <Plug>Netrw2Leftmouse nmap <buffer> <silent> <Plug>Netrw2Leftmouse - imap <buffer> <leftmouse> <Plug>ILeftmouse - ino <buffer> <silent> <Plug>ILeftmouse <c-o><leftmouse><c-o>:call <SID>NetrwLeftmouse(1)<cr> +" ino <buffer> <silent> <Plug>ILeftmouse <c-o><leftmouse><c-o>:call <SID>NetrwLeftmouse(1)<cr> imap <buffer> <middlemouse> <Plug>IMiddlemouse - ino <buffer> <silent> <Plug>IMiddlemouse <c-o><leftmouse><c-o>:call <SID>NetrwPrevWinOpen(1)<cr> - imap <buffer> <s-leftmouse> <Plug>ISLeftmouse - ino <buffer> <silent> <Plug>ISLeftmouse <c-o><leftmouse><c-o>:call <SID>NetrwMarkFile(1,<SID>NetrwGetWord())<cr> +" ino <buffer> <silent> <Plug>IMiddlemouse <c-o><leftmouse><c-o>:call <SID>NetrwPrevWinOpen(1)<cr> +" imap <buffer> <s-leftmouse> <Plug>ISLeftmouse +" ino <buffer> <silent> <Plug>ISLeftmouse <c-o><leftmouse><c-o>:call <SID>NetrwMarkFile(1,<SID>NetrwGetWord())<cr> exe 'nnoremap <buffer> <silent> <rightmouse> <leftmouse>:call <SID>NetrwLocalRm("'.mapsafecurdir.'")<cr>' exe 'vnoremap <buffer> <silent> <rightmouse> <leftmouse>:call <SID>NetrwLocalRm("'.mapsafecurdir.'")<cr>' - exe 'inoremap <buffer> <silent> <rightmouse> <c-o><leftmouse><c-o>:call <SID>NetrwLocalRm("'.mapsafecurdir.'")<cr>' +" exe 'inoremap <buffer> <silent> <rightmouse> <c-o><leftmouse><c-o>:call <SID>NetrwLocalRm("'.mapsafecurdir.'")<cr>' endif exe 'nnoremap <buffer> <silent> <nowait> <del> :call <SID>NetrwLocalRm("'.mapsafecurdir.'")<cr>' exe 'nnoremap <buffer> <silent> <nowait> D :call <SID>NetrwLocalRm("'.mapsafecurdir.'")<cr>' @@ -6083,10 +6158,10 @@ fun! s:NetrwMaps(islocal) exe 'vnoremap <buffer> <silent> <nowait> <del> :call <SID>NetrwLocalRm("'.mapsafecurdir.'")<cr>' exe 'vnoremap <buffer> <silent> <nowait> D :call <SID>NetrwLocalRm("'.mapsafecurdir.'")<cr>' exe 'vnoremap <buffer> <silent> <nowait> R :call <SID>NetrwLocalRename("'.mapsafecurdir.'")<cr>' - exe 'inoremap <buffer> <silent> <nowait> <del> <c-o>:call <SID>NetrwLocalRm("'.mapsafecurdir.'")<cr>' - exe 'inoremap <buffer> <silent> <nowait> D <c-o>:call <SID>NetrwLocalRm("'.mapsafecurdir.'")<cr>' - exe 'inoremap <buffer> <silent> <nowait> R <c-o>:call <SID>NetrwLocalRename("'.mapsafecurdir.'")<cr>' - exe 'inoremap <buffer> <silent> <nowait> d <c-o>:call <SID>NetrwMakeDir("")<cr>' +" exe 'inoremap <buffer> <silent> <nowait> <del> <c-o>:call <SID>NetrwLocalRm("'.mapsafecurdir.'")<cr>' +" exe 'inoremap <buffer> <silent> <nowait> D <c-o>:call <SID>NetrwLocalRm("'.mapsafecurdir.'")<cr>' +" exe 'inoremap <buffer> <silent> <nowait> R <c-o>:call <SID>NetrwLocalRename("'.mapsafecurdir.'")<cr>' +" exe 'inoremap <buffer> <silent> <nowait> d <c-o>:call <SID>NetrwMakeDir("")<cr>' nnoremap <buffer> <F1> :he netrw-quickhelp<cr> " support user-specified maps @@ -6096,13 +6171,24 @@ fun! s:NetrwMaps(islocal) " call Decho("make remote maps",'~'.expand("<slnum>")) call s:RemotePathAnalysis(b:netrw_curdir) " remote normal-mode maps - nnoremap <buffer> <silent> <nowait> <cr> :call <SID>NetrwBrowse(0,<SID>NetrwBrowseChgDir(0,<SID>NetrwGetWord()))<cr> - nnoremap <buffer> <silent> <nowait> <s-cr> :call <SID>TreeSqueezeDir(0)<cr> - nnoremap <buffer> <silent> <nowait> <c-l> :call <SID>NetrwRefresh(0,<SID>NetrwBrowseChgDir(0,'./'))<cr> - nnoremap <buffer> <silent> <nowait> <c-r> :call <SID>NetrwServerEdit(2,<SID>NetrwGetWord())<cr> - nnoremap <buffer> <silent> <nowait> - :call <SID>NetrwBrowseUpDir(0)<cr> - nnoremap <buffer> <silent> <nowait> a :call <SID>NetrwHide(0)<cr> + nnoremap <buffer> <silent> <nowait> a :<c-u>call <SID>NetrwHide(0)<cr> + nnoremap <buffer> <silent> <nowait> - :<c-u>call <SID>NetrwBrowseUpDir(0)<cr> + nnoremap <buffer> <silent> <nowait> % :<c-u>call <SID>NetrwOpenFile(0)<cr> + nnoremap <buffer> <silent> <nowait> C :<c-u>call <SID>NetrwSetChgwin()<cr> + nnoremap <buffer> <silent> <nowait> <c-l> :<c-u>call <SID>NetrwRefresh(0,<SID>NetrwBrowseChgDir(0,'./'))<cr> + nnoremap <buffer> <silent> <nowait> <cr> :<c-u>call <SID>NetrwBrowse(0,<SID>NetrwBrowseChgDir(0,<SID>NetrwGetWord()))<cr> + nnoremap <buffer> <silent> <nowait> <c-r> :<c-u>call <SID>NetrwServerEdit(2,<SID>NetrwGetWord())<cr> + nnoremap <buffer> <silent> <nowait> gb :<c-u>call <SID>NetrwBookHistHandler(1,b:netrw_curdir)<cr> + nnoremap <buffer> <silent> <nowait> gd :<c-u>call <SID>NetrwForceChgDir(0,<SID>NetrwGetWord())<cr> + nnoremap <buffer> <silent> <nowait> gf :<c-u>call <SID>NetrwForceFile(0,<SID>NetrwGetWord())<cr> + nnoremap <buffer> <silent> <nowait> gh :<c-u>call <SID>NetrwHidden(0)<cr> + nnoremap <buffer> <silent> <nowait> gp :<c-u>call <SID>NetrwChgPerm(0,b:netrw_curdir)<cr> + nnoremap <buffer> <silent> <nowait> I :<c-u>call <SID>NetrwBannerCtrl(1)<cr> + nnoremap <buffer> <silent> <nowait> i :<c-u>call <SID>NetrwListStyle(0)<cr> + nnoremap <buffer> <silent> <nowait> ma :<c-u>call <SID>NetrwMarkFileArgList(0,0)<cr> + nnoremap <buffer> <silent> <nowait> mA :<c-u>call <SID>NetrwMarkFileArgList(0,1)<cr> nnoremap <buffer> <silent> <nowait> mb :<c-u>call <SID>NetrwBookHistHandler(0,b:netrw_curdir)<cr> + nnoremap <buffer> <silent> <nowait> mB :<c-u>call <SID>NetrwBookHistHandler(6,b:netrw_curdir)<cr> nnoremap <buffer> <silent> <nowait> mc :<c-u>call <SID>NetrwMarkFileCopy(0)<cr> nnoremap <buffer> <silent> <nowait> md :<c-u>call <SID>NetrwMarkFileDiff(0)<cr> nnoremap <buffer> <silent> <nowait> me :<c-u>call <SID>NetrwMarkFileEdit(0)<cr> @@ -6114,99 +6200,96 @@ fun! s:NetrwMaps(islocal) nnoremap <buffer> <silent> <nowait> mp :<c-u>call <SID>NetrwMarkFilePrint(0)<cr> nnoremap <buffer> <silent> <nowait> mr :<c-u>call <SID>NetrwMarkFileRegexp(0)<cr> nnoremap <buffer> <silent> <nowait> ms :<c-u>call <SID>NetrwMarkFileSource(0)<cr> - nnoremap <buffer> <silent> <nowait> mt :<c-u>call <SID>NetrwMarkFileTgt(0)<cr> nnoremap <buffer> <silent> <nowait> mT :<c-u>call <SID>NetrwMarkFileTag(0)<cr> + nnoremap <buffer> <silent> <nowait> mt :<c-u>call <SID>NetrwMarkFileTgt(0)<cr> nnoremap <buffer> <silent> <nowait> mu :<c-u>call <SID>NetrwUnMarkFile(0)<cr> nnoremap <buffer> <silent> <nowait> mv :<c-u>call <SID>NetrwMarkFileVimCmd(0)<cr> nnoremap <buffer> <silent> <nowait> mx :<c-u>call <SID>NetrwMarkFileExe(0,0)<cr> nnoremap <buffer> <silent> <nowait> mX :<c-u>call <SID>NetrwMarkFileExe(0,1)<cr> nnoremap <buffer> <silent> <nowait> mz :<c-u>call <SID>NetrwMarkFileCompress(0)<cr> - nnoremap <buffer> <silent> <nowait> gb :<c-u>call <SID>NetrwBookHistHandler(1,b:netrw_curdir)<cr> - nnoremap <buffer> <silent> <nowait> gd :<c-u>call <SID>NetrwForceChgDir(0,<SID>NetrwGetWord())<cr> - nnoremap <buffer> <silent> <nowait> gf :<c-u>call <SID>NetrwForceFile(0,<SID>NetrwGetWord())<cr> - nnoremap <buffer> <silent> <nowait> gh :<c-u>call <SID>NetrwHidden(0)<cr> - nnoremap <buffer> <silent> <nowait> gp :<c-u>call <SID>NetrwChgPerm(0,b:netrw_curdir)<cr> - nnoremap <buffer> <silent> <nowait> C :<c-u>call <SID>NetrwSetChgwin()<cr> - nnoremap <buffer> <silent> <nowait> i :call <SID>NetrwListStyle(0)<cr> - nnoremap <buffer> <silent> <nowait> I :call <SID>NetrwBannerCtrl(1)<cr> - nnoremap <buffer> <silent> <nowait> o :call <SID>NetrwSplit(0)<cr> - nnoremap <buffer> <silent> <nowait> O :call <SID>NetrwObtain(0)<cr> - nnoremap <buffer> <silent> <nowait> p :call <SID>NetrwPreview(<SID>NetrwBrowseChgDir(1,<SID>NetrwGetWord(),1))<cr> - nnoremap <buffer> <silent> <nowait> P :call <SID>NetrwPrevWinOpen(0)<cr> + nnoremap <buffer> <silent> <nowait> O :<c-u>call <SID>NetrwObtain(0)<cr> + nnoremap <buffer> <silent> <nowait> o :call <SID>NetrwSplit(0)<cr> + nnoremap <buffer> <silent> <nowait> p :<c-u>call <SID>NetrwPreview(<SID>NetrwBrowseChgDir(1,<SID>NetrwGetWord(),1))<cr> + nnoremap <buffer> <silent> <nowait> P :<c-u>call <SID>NetrwPrevWinOpen(0)<cr> nnoremap <buffer> <silent> <nowait> qb :<c-u>call <SID>NetrwBookHistHandler(2,b:netrw_curdir)<cr> - nnoremap <buffer> <silent> <nowait> mB :<c-u>call <SID>NetrwBookHistHandler(6,b:netrw_curdir)<cr> nnoremap <buffer> <silent> <nowait> qf :<c-u>call <SID>NetrwFileInfo(0,<SID>NetrwGetWord())<cr> nnoremap <buffer> <silent> <nowait> qF :<c-u>call <SID>NetrwMarkFileQFEL(0,getqflist())<cr> - nnoremap <buffer> <silent> <nowait> r :let g:netrw_sort_direction= (g:netrw_sort_direction =~ 'n')? 'r' : 'n'<bar>exe "norm! 0"<bar>call <SID>NetrwBrowse(0,<SID>NetrwBrowseChgDir(0,'./'))<cr> - nnoremap <buffer> <silent> <nowait> s :call <SID>NetrwSortStyle(0)<cr> - nnoremap <buffer> <silent> <nowait> S :call <SID>NetSortSequence(0)<cr> - nnoremap <buffer> <silent> <nowait> t :call <SID>NetrwSplit(1)<cr> - nnoremap <buffer> <silent> <nowait> Tb :<c-u>call <SID>NetrwSetTgt('b',v:count1)<cr> - nnoremap <buffer> <silent> <nowait> Th :<c-u>call <SID>NetrwSetTgt('h',v:count)<cr> - nnoremap <buffer> <silent> <nowait> u :<c-u>call <SID>NetrwBookHistHandler(4,b:netrw_curdir)<cr> - nnoremap <buffer> <silent> <nowait> U :<c-u>call <SID>NetrwBookHistHandler(5,b:netrw_curdir)<cr> - nnoremap <buffer> <silent> <nowait> v :call <SID>NetrwSplit(2)<cr> - nnoremap <buffer> <silent> <nowait> x :call netrw#BrowseX(<SID>NetrwBrowseChgDir(0,<SID>NetrwGetWord()),1)<cr> - nnoremap <buffer> <silent> <nowait> % :call <SID>NetrwOpenFile(0)<cr> - " remote insert-mode maps - inoremap <buffer> <silent> <nowait> <cr> <c-o>:call <SID>NetrwBrowse(0,<SID>NetrwBrowseChgDir(0,<SID>NetrwGetWord()))<cr> - inoremap <buffer> <silent> <nowait> <c-l> <c-o>:call <SID>NetrwRefresh(0,<SID>NetrwBrowseChgDir(0,'./'))<cr> - inoremap <buffer> <silent> <nowait> <s-cr> <c-o>:call <SID>TreeSqueezeDir(0)<cr> - inoremap <buffer> <silent> <nowait> - <c-o>:call <SID>NetrwBrowseUpDir(0)<cr> - inoremap <buffer> <silent> <nowait> a <c-o>:call <SID>NetrwHide(0)<cr> - inoremap <buffer> <silent> <nowait> mb <c-o>:<c-u>call <SID>NetrwBookHistHandler(0,b:netrw_curdir)<cr> - inoremap <buffer> <silent> <nowait> mc <c-o>:<c-u>call <SID>NetrwMarkFileCopy(0)<cr> - inoremap <buffer> <silent> <nowait> md <c-o>:<c-u>call <SID>NetrwMarkFileDiff(0)<cr> - inoremap <buffer> <silent> <nowait> me <c-o>:<c-u>call <SID>NetrwMarkFileEdit(0)<cr> - inoremap <buffer> <silent> <nowait> mf <c-o>:<c-u>call <SID>NetrwMarkFile(0,<SID>NetrwGetWord())<cr> - inoremap <buffer> <silent> <nowait> mg <c-o>:<c-u>call <SID>NetrwMarkFileGrep(0)<cr> - inoremap <buffer> <silent> <nowait> mh <c-o>:<c-u>call <SID>NetrwMarkHideSfx(0)<cr> - inoremap <buffer> <silent> <nowait> mm <c-o>:<c-u>call <SID>NetrwMarkFileMove(0)<cr> - inoremap <buffer> <silent> <nowait> mp <c-o>:<c-u>call <SID>NetrwMarkFilePrint(0)<cr> - inoremap <buffer> <silent> <nowait> mr <c-o>:<c-u>call <SID>NetrwMarkFileRegexp(0)<cr> - inoremap <buffer> <silent> <nowait> ms <c-o>:<c-u>call <SID>NetrwMarkFileSource(0)<cr> - inoremap <buffer> <silent> <nowait> mt <c-o>:<c-u>call <SID>NetrwMarkFileTgt(0)<cr> - inoremap <buffer> <silent> <nowait> mT <c-o>:<c-u>call <SID>NetrwMarkFileTag(0)<cr> - inoremap <buffer> <silent> <nowait> mu <c-o>:<c-u>call <SID>NetrwUnMarkFile(0)<cr> - nnoremap <buffer> <silent> <nowait> mv :<c-u>call <SID>NetrwMarkFileVimCmd(1)<cr> - inoremap <buffer> <silent> <nowait> mx <c-o>:<c-u>call <SID>NetrwMarkFileExe(0,0)<cr> - inoremap <buffer> <silent> <nowait> mX <c-o>:<c-u>call <SID>NetrwMarkFileExe(0,1)<cr> - inoremap <buffer> <silent> <nowait> mv <c-o>:<c-u>call <SID>NetrwMarkFileVimCmd(0)<cr> - inoremap <buffer> <silent> <nowait> mz <c-o>:<c-u>call <SID>NetrwMarkFileCompress(0)<cr> - inoremap <buffer> <silent> <nowait> gb <c-o>:<c-u>call <SID>NetrwBookHistHandler(1,b:netrw_curdir)<cr> - inoremap <buffer> <silent> <nowait> gh <c-o>:<c-u>call <SID>NetrwHidden(0)<cr> - inoremap <buffer> <silent> <nowait> gp <c-o>:<c-u>call <SID>NetrwChgPerm(0,b:netrw_curdir)<cr> - inoremap <buffer> <silent> <nowait> C <c-o>:call <SID>NetrwSetChgwin()<cr> - inoremap <buffer> <silent> <nowait> i <c-o>:call <SID>NetrwListStyle(0)<cr> - inoremap <buffer> <silent> <nowait> I <c-o>:call <SID>NetrwBannerCtrl(1)<cr> - inoremap <buffer> <silent> <nowait> o <c-o>:call <SID>NetrwSplit(0)<cr> - inoremap <buffer> <silent> <nowait> O <c-o>:call <SID>NetrwObtain(0)<cr> - inoremap <buffer> <silent> <nowait> p <c-o>:call <SID>NetrwPreview(<SID>NetrwBrowseChgDir(1,<SID>NetrwGetWord(),1))<cr> - inoremap <buffer> <silent> <nowait> P <c-o>:call <SID>NetrwPrevWinOpen(0)<cr> - inoremap <buffer> <silent> <nowait> qb <c-o>:<c-u>call <SID>NetrwBookHistHandler(2,b:netrw_curdir)<cr> - inoremap <buffer> <silent> <nowait> mB <c-o>:<c-u>call <SID>NetrwBookHistHandler(6,b:netrw_curdir)<cr> - inoremap <buffer> <silent> <nowait> qf <c-o>:<c-u>call <SID>NetrwFileInfo(0,<SID>NetrwGetWord())<cr> - inoremap <buffer> <silent> <nowait> qF :<c-u>call <SID>NetrwMarkFileQFEL(0,getqflist())<cr> - inoremap <buffer> <silent> <nowait> r <c-o>:let g:netrw_sort_direction= (g:netrw_sort_direction =~ 'n')? 'r' : 'n'<bar>exe "norm! 0"<bar>call <SID>NetrwBrowse(0,<SID>NetrwBrowseChgDir(0,'./'))<cr> - inoremap <buffer> <silent> <nowait> s <c-o>:call <SID>NetrwSortStyle(0)<cr> - inoremap <buffer> <silent> <nowait> S <c-o>:call <SID>NetSortSequence(0)<cr> - inoremap <buffer> <silent> <nowait> t <c-o>:call <SID>NetrwSplit(1)<cr> - inoremap <buffer> <silent> <nowait> Tb <c-o>:<c-u>call <SID>NetrwSetTgt('b',v:count1)<cr> - inoremap <buffer> <silent> <nowait> Th <c-o>:<c-u>call <SID>NetrwSetTgt('h',v:count)<cr> - inoremap <buffer> <silent> <nowait> u <c-o>:<c-u>call <SID>NetrwBookHistHandler(4,b:netrw_curdir)<cr> - inoremap <buffer> <silent> <nowait> U <c-o>:<c-u>call <SID>NetrwBookHistHandler(5,b:netrw_curdir)<cr> - inoremap <buffer> <silent> <nowait> v <c-o>:call <SID>NetrwSplit(2)<cr> - inoremap <buffer> <silent> <nowait> x <c-o>:call netrw#BrowseX(<SID>NetrwBrowseChgDir(0,<SID>NetrwGetWord()),1)<cr> - inoremap <buffer> <silent> <nowait> % <c-o>:call <SID>NetrwOpenFile(0)<cr> + nnoremap <buffer> <silent> <nowait> qL :<c-u>call <SID>NetrwMarkFileQFEL(0,getloclist(v:count))<cr> + nnoremap <buffer> <silent> <nowait> r :<c-u>let g:netrw_sort_direction= (g:netrw_sort_direction =~# 'n')? 'r' : 'n'<bar>exe "norm! 0"<bar>call <SID>NetrwBrowse(0,<SID>NetrwBrowseChgDir(0,'./'))<cr> + nnoremap <buffer> <silent> <nowait> s :call <SID>NetrwSortStyle(0)<cr> + nnoremap <buffer> <silent> <nowait> S :<c-u>call <SID>NetSortSequence(0)<cr> + nnoremap <buffer> <silent> <nowait> Tb :<c-u>call <SID>NetrwSetTgt(0,'b',v:count1)<cr> + nnoremap <buffer> <silent> <nowait> t :call <SID>NetrwSplit(1)<cr> + nnoremap <buffer> <silent> <nowait> Th :<c-u>call <SID>NetrwSetTgt(0,'h',v:count)<cr> + nnoremap <buffer> <silent> <nowait> u :<c-u>call <SID>NetrwBookHistHandler(4,b:netrw_curdir)<cr> + nnoremap <buffer> <silent> <nowait> U :<c-u>call <SID>NetrwBookHistHandler(5,b:netrw_curdir)<cr> + nnoremap <buffer> <silent> <nowait> v :call <SID>NetrwSplit(2)<cr> + nnoremap <buffer> <silent> <nowait> x :<c-u>call netrw#BrowseX(<SID>NetrwBrowseChgDir(0,<SID>NetrwGetWord()),1)<cr> +" " remote insert-mode maps +" inoremap <buffer> <silent> <nowait> <cr> <c-o>:call <SID>NetrwBrowse(0,<SID>NetrwBrowseChgDir(0,<SID>NetrwGetWord()))<cr> +" inoremap <buffer> <silent> <nowait> <c-l> <c-o>:call <SID>NetrwRefresh(0,<SID>NetrwBrowseChgDir(0,'./'))<cr> +" inoremap <buffer> <silent> <nowait> <s-cr> <c-o>:call <SID>TreeSqueezeDir(0)<cr> +" inoremap <buffer> <silent> <nowait> - <c-o>:call <SID>NetrwBrowseUpDir(0)<cr> +" inoremap <buffer> <silent> <nowait> a <c-o>:call <SID>NetrwHide(0)<cr> +" inoremap <buffer> <silent> <nowait> mb <c-o>:<c-u>call <SID>NetrwBookHistHandler(0,b:netrw_curdir)<cr> +" inoremap <buffer> <silent> <nowait> mc <c-o>:<c-u>call <SID>NetrwMarkFileCopy(0)<cr> +" inoremap <buffer> <silent> <nowait> md <c-o>:<c-u>call <SID>NetrwMarkFileDiff(0)<cr> +" inoremap <buffer> <silent> <nowait> me <c-o>:<c-u>call <SID>NetrwMarkFileEdit(0)<cr> +" inoremap <buffer> <silent> <nowait> mf <c-o>:<c-u>call <SID>NetrwMarkFile(0,<SID>NetrwGetWord())<cr> +" inoremap <buffer> <silent> <nowait> mg <c-o>:<c-u>call <SID>NetrwMarkFileGrep(0)<cr> +" inoremap <buffer> <silent> <nowait> mh <c-o>:<c-u>call <SID>NetrwMarkHideSfx(0)<cr> +" inoremap <buffer> <silent> <nowait> mm <c-o>:<c-u>call <SID>NetrwMarkFileMove(0)<cr> +" inoremap <buffer> <silent> <nowait> mp <c-o>:<c-u>call <SID>NetrwMarkFilePrint(0)<cr> +" inoremap <buffer> <silent> <nowait> mr <c-o>:<c-u>call <SID>NetrwMarkFileRegexp(0)<cr> +" inoremap <buffer> <silent> <nowait> ms <c-o>:<c-u>call <SID>NetrwMarkFileSource(0)<cr> +" inoremap <buffer> <silent> <nowait> mt <c-o>:<c-u>call <SID>NetrwMarkFileTgt(0)<cr> +" inoremap <buffer> <silent> <nowait> mT <c-o>:<c-u>call <SID>NetrwMarkFileTag(0)<cr> +" inoremap <buffer> <silent> <nowait> mu <c-o>:<c-u>call <SID>NetrwUnMarkFile(0)<cr> +" nnoremap <buffer> <silent> <nowait> mv :<c-u>call <SID>NetrwMarkFileVimCmd(1)<cr> +" inoremap <buffer> <silent> <nowait> mx <c-o>:<c-u>call <SID>NetrwMarkFileExe(0,0)<cr> +" inoremap <buffer> <silent> <nowait> mX <c-o>:<c-u>call <SID>NetrwMarkFileExe(0,1)<cr> +" inoremap <buffer> <silent> <nowait> mv <c-o>:<c-u>call <SID>NetrwMarkFileVimCmd(0)<cr> +" inoremap <buffer> <silent> <nowait> mz <c-o>:<c-u>call <SID>NetrwMarkFileCompress(0)<cr> +" inoremap <buffer> <silent> <nowait> gb <c-o>:<c-u>call <SID>NetrwBookHistHandler(1,b:netrw_curdir)<cr> +" inoremap <buffer> <silent> <nowait> gh <c-o>:<c-u>call <SID>NetrwHidden(0)<cr> +" inoremap <buffer> <silent> <nowait> gp <c-o>:<c-u>call <SID>NetrwChgPerm(0,b:netrw_curdir)<cr> +" inoremap <buffer> <silent> <nowait> C <c-o>:call <SID>NetrwSetChgwin()<cr> +" inoremap <buffer> <silent> <nowait> i <c-o>:call <SID>NetrwListStyle(0)<cr> +" inoremap <buffer> <silent> <nowait> I <c-o>:call <SID>NetrwBannerCtrl(1)<cr> +" inoremap <buffer> <silent> <nowait> o <c-o>:call <SID>NetrwSplit(0)<cr> +" inoremap <buffer> <silent> <nowait> O <c-o>:call <SID>NetrwObtain(0)<cr> +" inoremap <buffer> <silent> <nowait> p <c-o>:call <SID>NetrwPreview(<SID>NetrwBrowseChgDir(1,<SID>NetrwGetWord(),1))<cr> +" inoremap <buffer> <silent> <nowait> P <c-o>:call <SID>NetrwPrevWinOpen(0)<cr> +" inoremap <buffer> <silent> <nowait> qb <c-o>:<c-u>call <SID>NetrwBookHistHandler(2,b:netrw_curdir)<cr> +" inoremap <buffer> <silent> <nowait> mB <c-o>:<c-u>call <SID>NetrwBookHistHandler(6,b:netrw_curdir)<cr> +" inoremap <buffer> <silent> <nowait> qf <c-o>:<c-u>call <SID>NetrwFileInfo(0,<SID>NetrwGetWord())<cr> +" inoremap <buffer> <silent> <nowait> qF :<c-u>call <SID>NetrwMarkFileQFEL(0,getqflist())<cr> +" inoremap <buffer> <silent> <nowait> qL :<c-u>call <SID>NetrwMarkFileQFEL(0,getloclist(v:count))<cr> +" inoremap <buffer> <silent> <nowait> r <c-o>:let g:netrw_sort_direction= (g:netrw_sort_direction =~# 'n')? 'r' : 'n'<bar>exe "norm! 0"<bar>call <SID>NetrwBrowse(0,<SID>NetrwBrowseChgDir(0,'./'))<cr> +" inoremap <buffer> <silent> <nowait> s <c-o>:call <SID>NetrwSortStyle(0)<cr> +" inoremap <buffer> <silent> <nowait> S <c-o>:call <SID>NetSortSequence(0)<cr> +" inoremap <buffer> <silent> <nowait> t <c-o>:call <SID>NetrwSplit(1)<cr> +" inoremap <buffer> <silent> <nowait> Tb <c-o>:<c-u>call <SID>NetrwSetTgt('b',v:count1)<cr> +" inoremap <buffer> <silent> <nowait> Th <c-o>:<c-u>call <SID>NetrwSetTgt('h',v:count)<cr> +" inoremap <buffer> <silent> <nowait> u <c-o>:<c-u>call <SID>NetrwBookHistHandler(4,b:netrw_curdir)<cr> +" inoremap <buffer> <silent> <nowait> U <c-o>:<c-u>call <SID>NetrwBookHistHandler(5,b:netrw_curdir)<cr> +" inoremap <buffer> <silent> <nowait> v <c-o>:call <SID>NetrwSplit(2)<cr> +" inoremap <buffer> <silent> <nowait> x <c-o>:call netrw#BrowseX(<SID>NetrwBrowseChgDir(0,<SID>NetrwGetWord()),1)<cr> +" inoremap <buffer> <silent> <nowait> % <c-o>:call <SID>NetrwOpenFile(0)<cr> if !hasmapto('<Plug>NetrwHideEdit') nmap <buffer> <c-h> <Plug>NetrwHideEdit - imap <buffer> <c-h> <Plug>NetrwHideEdit +" imap <buffer> <c-h> <Plug>NetrwHideEdit endif nnoremap <buffer> <silent> <Plug>NetrwHideEdit :call <SID>NetrwHideEdit(0)<cr> if !hasmapto('<Plug>NetrwRefresh') nmap <buffer> <c-l> <Plug>NetrwRefresh - imap <buffer> <c-l> <Plug>NetrwRefresh +" imap <buffer> <c-l> <Plug>NetrwRefresh endif + if !hasmapto('<Plug>NetrwTreeSqueeze') + nmap <buffer> <silent> <nowait> <s-cr> <Plug>NetrwTreeSqueeze +" imap <buffer> <silent> <nowait> <s-cr> <c-o><Plug>NetrwTreeSqueeze + endif + nnoremap <buffer> <silent> <Plug>NetrwTreeSqueeze :call <SID>TreeSqueezeDir(0)<cr> let mapsafepath = escape(s:path, s:netrw_map_escape) let mapsafeusermach = escape(((s:user == "")? "" : s:user."@").s:machine, s:netrw_map_escape) @@ -6226,14 +6309,14 @@ fun! s:NetrwMaps(islocal) nmap <buffer> <2-leftmouse> <Plug>Netrw2Leftmouse nmap <buffer> <silent> <Plug>Netrw2Leftmouse - imap <buffer> <leftmouse> <Plug>ILeftmouse - ino <buffer> <silent> <Plug>ILeftmouse <c-o><leftmouse><c-o>:call <SID>NetrwLeftmouse(0)<cr> +" ino <buffer> <silent> <Plug>ILeftmouse <c-o><leftmouse><c-o>:call <SID>NetrwLeftmouse(0)<cr> imap <buffer> <middlemouse> <Plug>IMiddlemouse - ino <buffer> <silent> <Plug>IMiddlemouse <c-o><leftmouse><c-o>:call <SID>NetrwPrevWinOpen(0)<cr> +" ino <buffer> <silent> <Plug>IMiddlemouse <c-o><leftmouse><c-o>:call <SID>NetrwPrevWinOpen(0)<cr> imap <buffer> <s-leftmouse> <Plug>ISLeftmouse - ino <buffer> <silent> <Plug>ISLeftmouse <c-o><leftmouse><c-o>:call <SID>NetrwMarkFile(0,<SID>NetrwGetWord())<cr> +" ino <buffer> <silent> <Plug>ISLeftmouse <c-o><leftmouse><c-o>:call <SID>NetrwMarkFile(0,<SID>NetrwGetWord())<cr> exe 'nnoremap <buffer> <silent> <rightmouse> <leftmouse>:call <SID>NetrwRemoteRm("'.mapsafeusermach.'","'.mapsafepath.'")<cr>' exe 'vnoremap <buffer> <silent> <rightmouse> <leftmouse>:call <SID>NetrwRemoteRm("'.mapsafeusermach.'","'.mapsafepath.'")<cr>' - exe 'inoremap <buffer> <silent> <rightmouse> <c-o><leftmouse><c-o>:call <SID>NetrwRemoteRm("'.mapsafeusermach.'","'.mapsafepath.'")<cr>' +" exe 'inoremap <buffer> <silent> <rightmouse> <c-o><leftmouse><c-o>:call <SID>NetrwRemoteRm("'.mapsafeusermach.'","'.mapsafepath.'")<cr>' endif exe 'nnoremap <buffer> <silent> <nowait> <del> :call <SID>NetrwRemoteRm("'.mapsafeusermach.'","'.mapsafepath.'")<cr>' exe 'nnoremap <buffer> <silent> <nowait> d :call <SID>NetrwMakeDir("'.mapsafeusermach.'")<cr>' @@ -6242,12 +6325,12 @@ fun! s:NetrwMaps(islocal) exe 'vnoremap <buffer> <silent> <nowait> <del> :call <SID>NetrwRemoteRm("'.mapsafeusermach.'","'.mapsafepath.'")<cr>' exe 'vnoremap <buffer> <silent> <nowait> D :call <SID>NetrwRemoteRm("'.mapsafeusermach.'","'.mapsafepath.'")<cr>' exe 'vnoremap <buffer> <silent> <nowait> R :call <SID>NetrwRemoteRename("'.mapsafeusermach.'","'.mapsafepath.'")<cr>' - exe 'inoremap <buffer> <silent> <nowait> <del> <c-o>:call <SID>NetrwRemoteRm("'.mapsafeusermach.'","'.mapsafepath.'")<cr>' - exe 'inoremap <buffer> <silent> <nowait> d <c-o>:call <SID>NetrwMakeDir("'.mapsafeusermach.'")<cr>' - exe 'inoremap <buffer> <silent> <nowait> D <c-o>:call <SID>NetrwRemoteRm("'.mapsafeusermach.'","'.mapsafepath.'")<cr>' - exe 'inoremap <buffer> <silent> <nowait> R <c-o>:call <SID>NetrwRemoteRename("'.mapsafeusermach.'","'.mapsafepath.'")<cr>' +" exe 'inoremap <buffer> <silent> <nowait> <del> <c-o>:call <SID>NetrwRemoteRm("'.mapsafeusermach.'","'.mapsafepath.'")<cr>' +" exe 'inoremap <buffer> <silent> <nowait> d <c-o>:call <SID>NetrwMakeDir("'.mapsafeusermach.'")<cr>' +" exe 'inoremap <buffer> <silent> <nowait> D <c-o>:call <SID>NetrwRemoteRm("'.mapsafeusermach.'","'.mapsafepath.'")<cr>' +" exe 'inoremap <buffer> <silent> <nowait> R <c-o>:call <SID>NetrwRemoteRename("'.mapsafeusermach.'","'.mapsafepath.'")<cr>' nnoremap <buffer> <F1> :he netrw-quickhelp<cr> - inoremap <buffer> <F1> <c-o>:he netrw-quickhelp<cr> +" inoremap <buffer> <F1> <c-o>:he netrw-quickhelp<cr> " support user-specified maps call netrw#UserMaps(0) @@ -6257,7 +6340,7 @@ fun! s:NetrwMaps(islocal) endfun " --------------------------------------------------------------------- -" s:NetrwCommands: sets up commands {{{2 +" s:NetrwCommands: set up commands {{{2 " If -buffer, the command is only available from within netrw buffers " Otherwise, the command is available from any window, so long as netrw " has been used at least once in the session. @@ -6266,7 +6349,7 @@ fun! s:NetrwCommands(islocal) com! -nargs=* -complete=file -bang NetrwMB call s:NetrwBookmark(<bang>0,<f-args>) com! -nargs=* NetrwC call s:NetrwSetChgwin(<q-args>) - com! Rexplore if exists("w:netrw_rexlocal")|call s:NetrwRexplore(w:netrw_rexlocal,exists("w:netrw_rexdir")? w:netrw_rexdir : ".")|else|call netrw#ErrorMsg(s:WARNING,"not a former netrw window",79)|endif + com! Rexplore if exists("w:netrw_rexlocal")|call s:NetrwRexplore(w:netrw_rexlocal,exists("w:netrw_rexdir")? w:netrw_rexdir : ".")|else|call netrw#ErrorMsg(s:WARNING,"win#".winnr()." not a former netrw window",79)|endif if a:islocal com! -buffer -nargs=+ -complete=file MF call s:NetrwMarkFiles(1,<f-args>) else @@ -6286,10 +6369,10 @@ fun! s:NetrwMarkFiles(islocal,...) let i = 1 while i <= a:0 if a:islocal - if v:version == 704 && has("patch656") - let mffiles= glob(a:{i},0,1,1) + if v:version > 704 || (v:version == 704 && has("patch656")) + let mffiles= glob(fnameescape(a:{i}),0,1,1) else - let mffiles= glob(a:{i},0,1) + let mffiles= glob(fnameescape(a:{i}),0,1) endif else let mffiles= [a:{i}] @@ -6319,9 +6402,11 @@ fun! s:NetrwMarkTarget(...) let s:netrwmftgt = tgt let s:netrwmftgt_islocal = tgt !~ '^\a\{3,}://' let curislocal = b:netrw_curdir !~ '^\a\{3,}://' - let svpos = netrw#SavePosn() + let svpos = winsaveview() +" call Decho("saving posn to svpos<".string(svpos).">",'~'.expand("<slnum>")) call s:NetrwRefresh(curislocal,s:NetrwBrowseChgDir(curislocal,'./')) - call netrw#RestorePosn(svpos) +" call Decho("restoring posn to svpos<".string(svpos).">",'~'.expand("<slnum>")) + call winrestview(svpos) " call Dret("s:NetrwMarkTarget") endfun @@ -6460,6 +6545,48 @@ fun! s:NetrwMarkFile(islocal,fname) endfun " --------------------------------------------------------------------- +" s:NetrwMarkFileArgList: ma: move the marked file list to the argument list (tomflist=0) {{{2 +" mA: move the argument list to marked file list (tomflist=1) +" Uses the global marked file list +fun! s:NetrwMarkFileArgList(islocal,tomflist) +" call Dfunc("s:NetrwMarkFileArgList(islocal=".a:islocal.",tomflist=".a:tomflist.")") + + let svpos = winsaveview() +" call Decho("saving posn to svpos<".string(svpos).">",'~'.expand("<slnum>")) + let curdir = s:NetrwGetCurdir(a:islocal) + let curbufnr = bufnr("%") + + if a:tomflist + " mA: move argument list to marked file list + while argc() + let fname= argv(0) +" call Decho("exe argdel ".fname,'~'.expand("<slnum>")) + exe "argdel ".fnameescape(fname) + call s:NetrwMarkFile(a:islocal,fname) + endwhile + + else + " ma: move marked file list to argument list + if exists("s:netrwmarkfilelist") + + " for every filename in the marked list + for fname in s:netrwmarkfilelist +" call Decho("exe argadd ".fname,'~'.expand("<slnum>")) + exe "argadd ".fnameescape(fname) + endfor " for every file in the marked list + + " unmark list and refresh + call s:NetrwUnmarkList(curbufnr,curdir) + NetrwKeepj call s:NetrwRefresh(a:islocal,s:NetrwBrowseChgDir(a:islocal,'./')) +" call Decho("restoring posn to svpos<".string(svpos).">",'~'.expand("<slnum>")) + NetrwKeepj call winrestview(svpos) + endif + endif + +" call Dret("s:NetrwMarkFileArgList") +endfun + +" --------------------------------------------------------------------- " s:NetrwMarkFileCompress: (invoked by mz) This function is used to {{{2 " compress/decompress files using the programs " in g:netrw_compress and g:netrw_uncompress, @@ -6469,7 +6596,8 @@ endfun " g:netrw_decompress = { ".gz" : "gunzip" , ".bz2" : "bunzip2" , ".zip" : "unzip" , ".tar" : "tar -xf", ".xz" : "unxz"} fun! s:NetrwMarkFileCompress(islocal) " call Dfunc("s:NetrwMarkFileCompress(islocal=".a:islocal.")") - let svpos = netrw#SavePosn() + let svpos = winsaveview() +" call Decho("saving posn to svpos<".string(svpos).">",'~'.expand("<slnum>")) let curdir = s:NetrwGetCurdir(a:islocal) let curbufnr = bufnr("%") @@ -6524,7 +6652,8 @@ fun! s:NetrwMarkFileCompress(islocal) call s:NetrwUnmarkList(curbufnr,curdir) NetrwKeepj call s:NetrwRefresh(a:islocal,s:NetrwBrowseChgDir(a:islocal,'./')) - NetrwKeepj call netrw#RestorePosn(svpos) +" call Decho("restoring posn to svpos<".string(svpos).">",'~'.expand("<slnum>")) + NetrwKeepj call winrestview(svpos) endif " call Dret("s:NetrwMarkFileCompress") endfun @@ -6541,6 +6670,12 @@ fun! s:NetrwMarkFileCopy(islocal,...) let curdir = s:NetrwGetCurdir(a:islocal) let curbufnr = bufnr("%") + if b:netrw_curdir !~ '/$' + if !exists("b:netrw_curdir") + let b:netrw_curdir= curdir + endif + let b:netrw_curdir= b:netrw_curdir."/" + endif " sanity check if !exists("s:netrwmarkfilelist_{curbufnr}") || empty(s:netrwmarkfilelist_{curbufnr}) @@ -6557,7 +6692,7 @@ fun! s:NetrwMarkFileCopy(islocal,...) endif " call Decho("sanity chk passed: s:netrwmftgt<".s:netrwmftgt.">",'~'.expand("<slnum>")) - if a:islocal && s:netrwmftgt_islocal + if a:islocal && s:netrwmftgt_islocal " Copy marked files, local directory to local directory " call Decho("copy from local to local",'~'.expand("<slnum>")) if !executable(g:netrw_localcopycmd) && g:netrw_localcopycmd !~ '^'.expand("$COMSPEC").'\s' @@ -6571,12 +6706,12 @@ fun! s:NetrwMarkFileCopy(islocal,...) if len(s:netrwmarkfilelist_{bufnr('%')}) == 1 " only one marked file " call Decho("case: only one marked file",'~'.expand("<slnum>")) - let args = s:ShellEscape(b:netrw_curdir."/".s:netrwmarkfilelist_{bufnr('%')}[0]) + let args = s:ShellEscape(b:netrw_curdir.s:netrwmarkfilelist_{bufnr('%')}[0]) let oldname = s:netrwmarkfilelist_{bufnr('%')}[0] elseif a:0 == 1 " call Decho("case: handling one input argument",'~'.expand("<slnum>")) " this happens when the next case was used to recursively call s:NetrwMarkFileCopy() - let args = s:ShellEscape(b:netrw_curdir."/".a:1) + let args = s:ShellEscape(b:netrw_curdir.a:1) let oldname = a:1 else " copy multiple marked files inside the same directory @@ -6611,9 +6746,12 @@ fun! s:NetrwMarkFileCopy(islocal,...) let args= substitute(args,'/','\\','g') let tgt = substitute(tgt, '/','\\','g') endif - if args =~ "'"|let args= substitute(args,"'\\(.*\\)'",'\1','')|endif - if tgt =~ "'"|let tgt = substitute(tgt,"'\\(.*\\)'",'\1','') |endif - if args =~ '//$'|let args= substitute(args,'//$','/','')|endif + if args =~ "'" |let args= substitute(args,"'\\(.*\\)'",'\1','')|endif + if tgt =~ "'" |let tgt = substitute(tgt ,"'\\(.*\\)'",'\1','')|endif + if args =~ '//'|let args= substitute(args,'//','/','g')|endif + if tgt =~ '//'|let tgt = substitute(tgt ,'//','/','g')|endif +" call Decho("args <".args.">",'~'.expand("<slnum>")) +" call Decho("tgt <".tgt.">",'~'.expand("<slnum>")) if isdirectory(s:NetrwFile(args)) " call Decho("args<".args."> is a directory",'~'.expand("<slnum>")) let copycmd= g:netrw_localcopydircmd @@ -6688,11 +6826,17 @@ fun! s:NetrwMarkFileCopy(islocal,...) NetrwKeepj call s:NetrwDelete(fname) endfor call s:NetrwLcd(curdir) - call s:NetrwExe("sil !".g:netrw_localrmdir." ".s:ShellEscape(tmpdir,1)) - if v:shell_error != 0 - call netrw#ErrorMsg(s:WARNING,"consider setting g:netrw_localrmdir<".g:netrw_localrmdir."> to something that works",80) -" call Dret("s:NetrwMarkFileCopy : failed: sil !".g:netrw_localrmdir." ".s:ShellEscape(tmpdir,1) ) - return + if v:version < 704 || !has("patch1109") + call s:NetrwExe("sil !".g:netrw_localrmdir." ".s:ShellEscape(tmpdir,1)) + if v:shell_error != 0 + call netrw#ErrorMsg(s:WARNING,"consider setting g:netrw_localrmdir<".g:netrw_localrmdir."> to something that works",80) +" " call Dret("s:NetrwMarkFileCopy : failed: sil !".g:netrw_localrmdir." ".s:ShellEscape(tmpdir,1) ) + return + endif + else + if delete(tmpdir,"d") + call netrw#ErrorMsg(s:ERROR,"unable to delete directory <".tmpdir.">!",103) + endif endif else call s:NetrwLcd(curdir) @@ -6703,21 +6847,40 @@ fun! s:NetrwMarkFileCopy(islocal,...) " ------- " cleanup " ------- -" call Decho("cleanup",'~'.expand("<slnum>")) - if !exists("s:recursive") - " remove markings from local buffer - call s:NetrwUnmarkList(curbufnr,curdir) - endif - - " refresh buffers - if !s:netrwmftgt_islocal - call s:NetrwRefreshDir(s:netrwmftgt_islocal,s:netrwmftgt) - endif - if a:islocal - NetrwKeepj call s:NetrwRefreshDir(a:islocal,curdir) +" call Decho("cleanup",'~'.expand("<slnum>")) + " remove markings from local buffer + call s:NetrwUnmarkList(curbufnr,curdir) " remove markings from local buffer +" call Decho(" g:netrw_fastbrowse =".g:netrw_fastbrowse,'~'.expand("<slnum>")) +" call Decho(" s:netrwmftgt =".s:netrwmftgt,'~'.expand("<slnum>")) +" call Decho(" s:netrwmftgt_islocal=".s:netrwmftgt_islocal,'~'.expand("<slnum>")) +" call Decho(" curdir =".curdir,'~'.expand("<slnum>")) +" call Decho(" a:islocal =".a:islocal,'~'.expand("<slnum>")) +" call Decho(" curbufnr =".curbufnr,'~'.expand("<slnum>")) + if exists("s:recursive") +" call Decho(" s:recursive =".s:recursive,'~'.expand("<slnum>")) + else +" call Decho(" s:recursive =n/a",'~'.expand("<slnum>")) endif + " see s:LocalFastBrowser() for g:netrw_fastbrowse interpretation (refreshing done for both slow and medium) if g:netrw_fastbrowse <= 1 NetrwKeepj call s:LocalBrowseRefresh() + else + " refresh local and targets for fast browsing + if !exists("s:recursive") + " remove markings from local buffer +" call Decho(" remove markings from local buffer",'~'.expand("<slnum>")) + NetrwKeepj call s:NetrwUnmarkList(curbufnr,curdir) + endif + + " refresh buffers + if s:netrwmftgt_islocal +" call Decho(" refresh s:netrwmftgt=".s:netrwmftgt,'~'.expand("<slnum>")) + NetrwKeepj call s:NetrwRefreshDir(s:netrwmftgt_islocal,s:netrwmftgt) + endif + if a:islocal && s:netrwmftgt != curdir +" call Decho(" refresh curdir=".curdir,'~'.expand("<slnum>")) + NetrwKeepj call s:NetrwRefreshDir(a:islocal,curdir) + endif endif " call Dret("s:NetrwMarkFileCopy 1") @@ -6798,7 +6961,7 @@ fun! s:NetrwMarkFileEdit(islocal) endfun " --------------------------------------------------------------------- -" s:NetrwMarkFileQFEL: convert a quickfix-error list into a marked file list {{{2 +" s:NetrwMarkFileQFEL: convert a quickfix-error or location list into a marked file list {{{2 fun! s:NetrwMarkFileQFEL(islocal,qfel) " call Dfunc("s:NetrwMarkFileQFEL(islocal=".a:islocal.",qfel)") call s:NetrwUnmarkAll() @@ -6834,7 +6997,8 @@ endfun " mX enbloc=1: Uses the global marked-file list, applies command to entire list fun! s:NetrwMarkFileExe(islocal,enbloc) " call Dfunc("s:NetrwMarkFileExe(islocal=".a:islocal.",enbloc=".a:enbloc.")") - let svpos = netrw#SavePosn() + let svpos = winsaveview() +" call Decho("saving posn to svpos<".string(svpos).">",'~'.expand("<slnum>")) let curdir = s:NetrwGetCurdir(a:islocal) let curbufnr = bufnr("%") @@ -6894,7 +7058,8 @@ fun! s:NetrwMarkFileExe(islocal,enbloc) " refresh the listing NetrwKeepj call s:NetrwRefresh(a:islocal,s:NetrwBrowseChgDir(a:islocal,'./')) - NetrwKeepj call netrw#RestorePosn(svpos) +" call Decho("restoring posn to svpos<".string(svpos).">",'~'.expand("<slnum>")) + NetrwKeepj call winrestview(svpos) else NetrwKeepj call netrw#ErrorMsg(s:ERROR,"no files marked!",59) endif @@ -6926,7 +7091,8 @@ fun! s:NetrwMarkFileExe(islocal,enbloc) " refresh the listing NetrwKeepj call s:NetrwRefresh(a:islocal,s:NetrwBrowseChgDir(a:islocal,'./')) - NetrwKeepj call netrw#RestorePosn(svpos) +" call Decho("restoring posn to svpos<".string(svpos).">",'~'.expand("<slnum>")) + NetrwKeepj call winrestview(svpos) endif @@ -6939,7 +7105,8 @@ endfun " Uses the local marked file list. fun! s:NetrwMarkHideSfx(islocal) " call Dfunc("s:NetrwMarkHideSfx(islocal=".a:islocal.")") - let svpos = netrw#SavePosn() + let svpos = winsaveview() +" call Decho("saving posn to svpos<".string(svpos).">",'~'.expand("<slnum>")) let curbufnr = bufnr("%") " s:netrwmarkfilelist_{curbufnr}: the List of marked files @@ -6982,7 +7149,8 @@ fun! s:NetrwMarkHideSfx(islocal) " refresh the listing NetrwKeepj call s:NetrwRefresh(a:islocal,s:NetrwBrowseChgDir(a:islocal,'./')) - NetrwKeepj call netrw#RestorePosn(svpos) +" call Decho("restoring posn to svpos<".string(svpos).">",'~'.expand("<slnum>")) + NetrwKeepj call winrestview(svpos) else NetrwKeepj call netrw#ErrorMsg(s:ERROR,"no files marked!",59) endif @@ -6995,7 +7163,8 @@ endfun " Uses the local marked-file list. fun! s:NetrwMarkFileVimCmd(islocal) " call Dfunc("s:NetrwMarkFileVimCmd(islocal=".a:islocal.")") - let svpos = netrw#SavePosn() + let svpos = winsaveview() +" call Decho("saving posn to svpos<".string(svpos).">",'~'.expand("<slnum>")) let curdir = s:NetrwGetCurdir(a:islocal) let curbufnr = bufnr("%") @@ -7039,7 +7208,8 @@ fun! s:NetrwMarkFileVimCmd(islocal) " refresh the listing NetrwKeepj call s:NetrwRefresh(a:islocal,s:NetrwBrowseChgDir(a:islocal,'./')) - NetrwKeepj call netrw#RestorePosn(svpos) +" call Decho("restoring posn to svpos<".string(svpos).">",'~'.expand("<slnum>")) + NetrwKeepj call winrestview(svpos) else NetrwKeepj call netrw#ErrorMsg(s:ERROR,"no files marked!",59) endif @@ -7053,7 +7223,8 @@ endfun " Uses the local marked file list. fun! s:NetrwMarkHideSfx(islocal) " call Dfunc("s:NetrwMarkHideSfx(islocal=".a:islocal.")") - let svpos = netrw#SavePosn() + let svpos = winsaveview() +" call Decho("saving posn to svpos<".string(svpos).">",'~'.expand("<slnum>")) let curbufnr = bufnr("%") " s:netrwmarkfilelist_{curbufnr}: the List of marked files @@ -7096,7 +7267,8 @@ fun! s:NetrwMarkHideSfx(islocal) " refresh the listing NetrwKeepj call s:NetrwRefresh(a:islocal,s:NetrwBrowseChgDir(a:islocal,'./')) - NetrwKeepj call netrw#RestorePosn(svpos) +" call Decho("restoring posn to svpos<".string(svpos).">",'~'.expand("<slnum>")) + NetrwKeepj call winrestview(svpos) else NetrwKeepj call netrw#ErrorMsg(s:ERROR,"no files marked!",59) endif @@ -7109,7 +7281,8 @@ endfun " Uses the global markfilelist fun! s:NetrwMarkFileGrep(islocal) " call Dfunc("s:NetrwMarkFileGrep(islocal=".a:islocal.")") - let svpos = netrw#SavePosn() + let svpos = winsaveview() +" call Decho("saving posn to svpos<".string(svpos).">",'~'.expand("<slnum>")) let curbufnr = bufnr("%") let curdir = s:NetrwGetCurdir(a:islocal) @@ -7150,12 +7323,13 @@ fun! s:NetrwMarkFileGrep(islocal) echo "(use :cn, :cp to navigate, :Rex to return)" 2match none - NetrwKeepj call netrw#RestorePosn(svpos) +" call Decho("restoring posn to svpos<".string(svpos).">",'~'.expand("<slnum>")) + NetrwKeepj call winrestview(svpos) if exists("nonisi") " original, user-supplied pattern did not begin with a character from isident " call Decho("looking for trailing nonisi<".nonisi."> followed by a j, gj, or jg",'~'.expand("<slnum>")) - if pat =~ nonisi.'j$\|'.nonisi.'gj$\|'.nonisi.'jg$' + if pat =~# nonisi.'j$\|'.nonisi.'gj$\|'.nonisi.'jg$' call s:NetrwMarkFileQFEL(a:islocal,getqflist()) endif endif @@ -7353,7 +7527,7 @@ fun! s:NetrwMarkFileRegexp(islocal) " get the matching list of files using local glob() " call Decho("handle local regexp",'~'.expand("<slnum>")) let dirname = escape(b:netrw_curdir,g:netrw_glob_escape) - if v:version == 704 && has("patch656") + if v:version > 704 || (v:version == 704 && has("patch656")) let files = glob(s:ComposePath(dirname,regexp),0,0,1) else let files = glob(s:ComposePath(dirname,regexp),0,0) @@ -7456,7 +7630,8 @@ endfun " Uses the global markfilelist fun! s:NetrwMarkFileTag(islocal) " call Dfunc("s:NetrwMarkFileTag(islocal=".a:islocal.")") - let svpos = netrw#SavePosn() + let svpos = winsaveview() +" call Decho("saving posn to svpos<".string(svpos).">",'~'.expand("<slnum>")) let curdir = s:NetrwGetCurdir(a:islocal) let curbufnr = bufnr("%") @@ -7494,7 +7669,8 @@ fun! s:NetrwMarkFileTag(islocal) endif 2match none call s:NetrwRefresh(a:islocal,s:NetrwBrowseChgDir(a:islocal,'./')) - call netrw#RestorePosn(svpos) +" call Decho("restoring posn to svpos<".string(svpos).">",'~'.expand("<slnum>")) + call winrestview(svpos) endif " call Dret("s:NetrwMarkFileTag") @@ -7507,8 +7683,9 @@ endfun " s:netrwmftgt_islocal : 0=target directory is remote " 1=target directory is local fun! s:NetrwMarkFileTgt(islocal) -" call Dfunc("s:NetrwMarkFileTgt(islocal=".a:islocal.")") - let svpos = netrw#SavePosn() +" call Dfunc("s:NetrwMarkFileTgt(islocal=".a:islocal.")") + let svpos = winsaveview() +" call Decho("saving posn to svpos<".string(svpos).">",'~'.expand("<slnum>")) let curdir = s:NetrwGetCurdir(a:islocal) let hadtgt = exists("s:netrwmftgt") if !exists("w:netrw_bannercnt") @@ -7526,7 +7703,8 @@ fun! s:NetrwMarkFileTgt(islocal) call s:LocalBrowseRefresh() endif call s:NetrwRefresh(a:islocal,s:NetrwBrowseChgDir(a:islocal,'./')) - call netrw#RestorePosn(svpos) +" call Decho("restoring posn to svpos<".string(svpos).">",'~'.expand("<slnum>")) + call winrestview(svpos) " call Dret("s:NetrwMarkFileTgt : removed target") return else @@ -7566,16 +7744,17 @@ fun! s:NetrwMarkFileTgt(islocal) " need to do refresh so that the banner will be updated " s:LocalBrowseRefresh handles all local-browsing buffers when not fast browsing if g:netrw_fastbrowse <= 1 -" call Decho("g:netrw_fastbrowse=".g:netrw_fastbrowse.", so refreshing all local netrw buffers") +" call Decho("g:netrw_fastbrowse=".g:netrw_fastbrowse.", so refreshing all local netrw buffers",'~'.expand("<slnum>")) call s:LocalBrowseRefresh() endif " call s:NetrwRefresh(a:islocal,s:NetrwBrowseChgDir(a:islocal,'./')) - if w:netrw_liststyle == s:TREELIST + if exists("w:netrw_liststyle") && w:netrw_liststyle == s:TREELIST call s:NetrwRefresh(a:islocal,s:NetrwBrowseChgDir(a:islocal,w:netrw_treetop)) else call s:NetrwRefresh(a:islocal,s:NetrwBrowseChgDir(a:islocal,'./')) endif - call netrw#RestorePosn(svpos) +" call Decho("restoring posn to svpos<".string(svpos).">",'~'.expand("<slnum>")) + call winrestview(svpos) if !hadtgt sil! NetrwKeepj norm! j endif @@ -7590,7 +7769,7 @@ endfun fun! s:NetrwGetCurdir(islocal) " call Dfunc("s:NetrwGetCurdir(islocal=".a:islocal.")") - if w:netrw_liststyle == s:TREELIST + if exists("w:netrw_liststyle") && w:netrw_liststyle == s:TREELIST let b:netrw_curdir = s:NetrwTreePath(w:netrw_treetop) " call Decho("set b:netrw_curdir<".b:netrw_curdir."> (used s:NetrwTreeDir)",'~'.expand("<slnum>")) elseif !exists("b:netrw_curdir") @@ -7598,10 +7777,10 @@ fun! s:NetrwGetCurdir(islocal) " call Decho("set b:netrw_curdir<".b:netrw_curdir."> (used getcwd)",'~'.expand("<slnum>")) endif -" call Decho("b:netrw_curdir<".b:netrw_curdir."> ".((b:netrw_curdir !~ '\<\a\{3,}://')? "does not match" : "matches")." url pattern") +" call Decho("b:netrw_curdir<".b:netrw_curdir."> ".((b:netrw_curdir !~ '\<\a\{3,}://')? "does not match" : "matches")." url pattern",'~'.expand("<slnum>")) if b:netrw_curdir !~ '\<\a\{3,}://' let curdir= b:netrw_curdir -" call Decho("g:netrw_keepdir=".g:netrw_keepdir) +" call Decho("g:netrw_keepdir=".g:netrw_keepdir,'~'.expand("<slnum>")) if g:netrw_keepdir == 0 call s:NetrwLcd(curdir) endif @@ -7626,8 +7805,8 @@ fun! s:NetrwOpenFile(islocal) endif let g:netrw_quiet = 1 " save position for benefit of Rexplore - let s:rexposn_{bufnr("%")}= netrw#SavePosn() -" call Decho("setting s:rexposn_".bufnr("%")."<".bufname("%")."> to SavePosn",'~'.expand("<slnum>")) + let s:rexposn_{bufnr("%")}= winsaveview() +" call Decho("saving posn to s:rexposn_".bufnr("%")."<".string(s:rexposn_{bufnr("%")}).">",'~'.expand("<slnum>")) if b:netrw_curdir =~ '/$' exe "NetrwKeepj e ".fnameescape(b:netrw_curdir.fname) else @@ -7702,7 +7881,8 @@ fun! s:NetSortSequence(islocal) " call Dfunc("NetSortSequence(islocal=".a:islocal.")") let ykeep= @@ - let svpos= netrw#SavePosn() + let svpos= winsaveview() +" call Decho("saving posn to svpos<".string(svpos).">",'~'.expand("<slnum>")) call inputsave() let newsortseq= input("Edit Sorting Sequence: ",g:netrw_sort_sequence) call inputrestore() @@ -7710,7 +7890,8 @@ fun! s:NetSortSequence(islocal) " refresh the listing let g:netrw_sort_sequence= newsortseq NetrwKeepj call s:NetrwRefresh(a:islocal,s:NetrwBrowseChgDir(a:islocal,'./')) - NetrwKeepj call netrw#RestorePosn(svpos) +" call Decho("restoring posn to svpos<".string(svpos).">",'~'.expand("<slnum>")) + NetrwKeepj call winrestview(svpos) let @@= ykeep " call Dret("NetSortSequence") @@ -7785,7 +7966,8 @@ endfun " s:netrwmarkfilemtch_# -- used with 2match to display marked files fun! s:NetrwUnMarkFile(islocal) " call Dfunc("s:NetrwUnMarkFile(islocal=".a:islocal.")") - let svpos = netrw#SavePosn() + let svpos = winsaveview() +" call Decho("saving posn to svpos<".string(svpos).">",'~'.expand("<slnum>")) let curbufnr = bufnr("%") " unmark marked file list @@ -7806,7 +7988,8 @@ fun! s:NetrwUnMarkFile(islocal) 2match none " call s:NetrwRefresh(a:islocal,s:NetrwBrowseChgDir(a:islocal,'./')) - call netrw#RestorePosn(svpos) +"call Decho("restoring posn to svpos<".string(svpos).">",'~'.expand("<slnum>")) +call winrestview(svpos) " call Dret("s:NetrwUnMarkFile") endfun @@ -7898,7 +8081,7 @@ fun! s:NetrwMenu(domenu) elseif !a:domenu let s:netrwcnt = 0 let curwin = winnr() - windo if getline(2) =~ "Netrw" | let s:netrwcnt= s:netrwcnt + 1 | endif + windo if getline(2) =~# "Netrw" | let s:netrwcnt= s:netrwcnt + 1 | endif exe curwin."wincmd w" if s:netrwcnt <= 1 @@ -8276,7 +8459,8 @@ fun! s:NetrwRefresh(islocal,dirname) let ykeep = @@ " save the cursor position before refresh. - let screenposn = netrw#SavePosn() + let screenposn = winsaveview() +" call Decho("saving posn to screenposn<".string(screenposn).">",'~'.expand("<slnum>")) " call Decho("win#".winnr().": ".winheight(0)."x".winwidth(0)." curfile<".expand("%").">",'~'.expand("<slnum>")) " call Decho("clearing buffer prior to refresh",'~'.expand("<slnum>")) @@ -8288,7 +8472,8 @@ fun! s:NetrwRefresh(islocal,dirname) endif " restore position - NetrwKeepj call netrw#RestorePosn(screenposn) +" call Decho("restoring posn to screenposn<".string(screenposn).">",'~'.expand("<slnum>")) + NetrwKeepj call winrestview(screenposn) " restore file marks if exists("s:netrwmarkfilemtch_{bufnr('%')}") && s:netrwmarkfilemtch_{bufnr("%")} != "" @@ -8439,8 +8624,8 @@ endfun " Implements [count]Tb (bookhist<b>) " [count]Th (bookhist<h>) " See :help netrw-qb for how to make the choice. -fun! s:NetrwSetTgt(bookhist,choice) -" call Dfunc("s:NetrwSetTgt(bookhist<".a:bookhist."> choice#".a:choice.")") +fun! s:NetrwSetTgt(islocal,bookhist,choice) +" call Dfunc("s:NetrwSetTgt(islocal=".a:islocal." bookhist<".a:bookhist."> choice#".a:choice.")") if a:bookhist == 'b' " supports choosing a bookmark as a target using a qb-generated list @@ -8462,6 +8647,12 @@ fun! s:NetrwSetTgt(bookhist,choice) endif endif + " refresh the display + if !exists("b:netrw_curdir") + let b:netrw_curdir= getcwd() + endif + call s:NetrwRefresh(a:islocal,b:netrw_curdir) + " call Dret("s:NetrwSetTgt") endfun @@ -8470,12 +8661,14 @@ endfun fun! s:NetrwSortStyle(islocal) " call Dfunc("s:NetrwSortStyle(islocal=".a:islocal.") netrw_sort_by<".g:netrw_sort_by.">") NetrwKeepj call s:NetrwSaveWordPosn() - let svpos= netrw#SavePosn() + let svpos= winsaveview() +" call Decho("saving posn to svpos<".string(svpos).">",'~'.expand("<slnum>")) - let g:netrw_sort_by= (g:netrw_sort_by =~ '^n')? 'time' : (g:netrw_sort_by =~ '^t')? 'size' : (g:netrw_sort_by =~ '^siz')? 'exten' : 'name' + let g:netrw_sort_by= (g:netrw_sort_by =~# '^n')? 'time' : (g:netrw_sort_by =~# '^t')? 'size' : (g:netrw_sort_by =~# '^siz')? 'exten' : 'name' NetrwKeepj norm! 0 NetrwKeepj call s:NetrwRefresh(a:islocal,s:NetrwBrowseChgDir(a:islocal,'./')) - NetrwKeepj call netrw#RestorePosn(svpos) +" call Decho("restoring posn to svpos<".string(svpos).">",'~'.expand("<slnum>")) + NetrwKeepj call winrestview(svpos) " call Dret("s:NetrwSortStyle : netrw_sort_by<".g:netrw_sort_by.">") endfun @@ -8574,7 +8767,6 @@ fun! s:NetrwSplit(mode) let s:didsplit= 1 NetrwKeepj call s:RestoreWinVars() NetrwKeepj call netrw#LocalBrowseCheck(s:NetrwBrowseChgDir(1,s:NetrwGetWord())) - "call netrw#LocalBrowseCheck(s:NetrwBrowseChgDir(1,s:NetrwGetWord())) unlet s:didsplit else @@ -8653,6 +8845,9 @@ endfun " (full path directory with trailing slash returned) fun! s:NetrwTreeDir(islocal) " call Dfunc("s:NetrwTreeDir(islocal=".a:islocal.") getline(".line(".").")"."<".getline('.')."> b:netrw_curdir<".b:netrw_curdir."> tab#".tabpagenr()." win#".winnr()." buf#".bufnr("%")."<".bufname("%")."> ft=".&ft) +" call Decho("g:netrw_keepdir =".(exists("g:netrw_keepdir")? g:netrw_keepdir : 'n/a'),'~'.expand("<slnum>")) +" call Decho("w:netrw_liststyle=".(exists("w:netrw_liststyle")? w:netrw_liststyle : 'n/a'),'~'.expand("<slnum>")) +" call Decho("w:netrw_treetop =".(exists("w:netrw_treetop")? w:netrw_treetop : 'n/a'),'~'.expand("<slnum>")) if exists("s:treedir") " s:NetrwPrevWinOpen opens a "previous" window -- and thus needs to and does call s:NetrwTreeDir early @@ -8665,12 +8860,13 @@ fun! s:NetrwTreeDir(islocal) if !exists("b:netrw_curdir") || b:netrw_curdir == "" let b:netrw_curdir= getcwd() endif - let treedir = b:netrw_curdir " call Decho("set initial treedir<".treedir.">",'~'.expand("<slnum>")) - let s:treecurpos= netrw#SavePosn() - if w:netrw_liststyle == s:TREELIST + let s:treecurpos= winsaveview() +" call Decho("saving posn to s:treecurpos<".string(s:treecurpos).">",'~'.expand("<slnum>")) + + if exists("w:netrw_liststyle") && w:netrw_liststyle == s:TREELIST " call Decho("w:netrw_liststyle is TREELIST:",'~'.expand("<slnum>")) " call Decho("line#".line(".")." getline(.)<".getline('.')."> treecurpos<".string(s:treecurpos).">",'~'.expand("<slnum>")) @@ -8692,7 +8888,7 @@ fun! s:NetrwTreeDir(islocal) " detect user attempting to close treeroot " call Decho("check if user is attempting to close treeroot",'~'.expand("<slnum>")) " call Decho(".win#".winnr()." buf#".bufnr("%")."<".bufname("%").">",'~'.expand("<slnum>")) -" call Decho(".getline(".line(".").")<".getline('.').'> '.((getline('.') =~ '^'.s:treedepthstring)? '=~' : '!~').' ^'.s:treedepthstring,'~'.expand("<slnum>")) +" call Decho(".getline(".line(".").")<".getline('.').'> '.((getline('.') =~# '^'.s:treedepthstring)? '=~#' : '!~').' ^'.s:treedepthstring,'~'.expand("<slnum>")) if curline !~ '^'.s:treedepthstring && getline('.') != '..' " call Decho(".user may have attempted to close treeroot",'~'.expand("<slnum>")) " now force a refresh @@ -8701,13 +8897,12 @@ fun! s:NetrwTreeDir(islocal) " call Dret("s:NetrwTreeDir <".treedir."> : (side effect) s:treecurpos<".(exists("s:treecurpos")? string(s:treecurpos) : 'n/a').">") return b:netrw_curdir " else " Decho -" call Decho(".user did not attempt to close treeroot",'~'.expand("<slnum>")) +" call Decho(".user not attempting to close treeroot",'~'.expand("<slnum>")) endif " call Decho("islocal=".a:islocal." curline<".curline.">",'~'.expand("<slnum>")) -" call Decho("after subst<".substitute(curline,'^'.s:treedepthstring.'\+ \(.*\)$','\1','').">",'~'.expand("<slnum>")) - let potentialdir= substitute(curline,'^'.s:treedepthstring.'* \(.*\)@$','\1','') -" call Decho("potentialdir<".potentialdir."> isdir=".isdirectory(s:NetrwFile(potentialdir)),'~'.expand("<slnum>")) + let potentialdir= s:NetrwFile(substitute(curline,'^'.s:treedepthstring.'\+ \(.*\)@$','\1','')) +" call Decho("potentialdir<".potentialdir."> isdir=".isdirectory(potentialdir),'~'.expand("<slnum>")) " COMBAK: a symbolic link may point anywhere -- so it will be used to start a new treetop " if a:islocal && curline =~ '@$' && isdirectory(s:NetrwFile(potentialdir)) @@ -8763,9 +8958,13 @@ fun! s:NetrwTreeDisplay(dir,depth) let depth= s:treedepthstring.a:depth " call Decho("display subtrees with depth<".depth."> and current leaves",'~'.expand("<slnum>")) -" call Decho("w:netrw_treedict[".dir."]=".string(w:netrw_treedict[dir]),'~'.expand("<slnum>")) +" call Decho("for every entry in w:netrw_treedict[".dir."]=".string(w:netrw_treedict[dir]),'~'.expand("<slnum>")) for entry in w:netrw_treedict[dir] - let direntry= substitute(dir.'/'.entry,'[@/]$','','e') + if dir =~ '/$' + let direntry= substitute(dir.entry,'[@/]$','','e') + else + let direntry= substitute(dir.'/'.entry,'[@/]$','','e') + endif " call Decho("dir<".dir."> entry<".entry."> direntry<".direntry.">",'~'.expand("<slnum>")) if entry =~ '/$' && has_key(w:netrw_treedict,direntry) " call Decho("<".direntry."> is a key in treedict - display subtree for it",'~'.expand("<slnum>")) @@ -8786,10 +8985,48 @@ fun! s:NetrwTreeDisplay(dir,depth) endfun " --------------------------------------------------------------------- +" s:NetrwRefreshTreeDict: updates the contents information for a tree (w:netrw_treedict) {{{2 +fun! s:NetrwRefreshTreeDict(dir) +" call Dfunc("s:NetrwRefreshTreeDict(dir<".a:dir.">)") + for entry in w:netrw_treedict[a:dir] + let direntry= substitute(a:dir.'/'.entry,'[@/]$','','e') +" call Decho("a:dir<".a:dir."> entry<".entry."> direntry<".direntry.">",'~'.expand("<slnum>")) + + if entry =~ '/$' && has_key(w:netrw_treedict,direntry) +" call Decho("<".direntry."> is a key in treedict - display subtree for it",'~'.expand("<slnum>")) + NetrwKeepj call s:NetrwRefreshTreeDict(direntry) + let liststar = s:NetrwGlob(direntry,'*',1) + let listdotstar = s:NetrwGlob(direntry,'.*',1) + let w:netrw_treedict[direntry] = liststar + listdotstar +" call Decho("updating w:netrw_treedict[".direntry.']='.string(w:netrw_treedict[direntry]),'~'.expand("<slnum>")) + + elseif entry =~ '/$' && has_key(w:netrw_treedict,direntry.'/') +" call Decho("<".direntry."/> is a key in treedict - display subtree for it",'~'.expand("<slnum>")) + NetrwKeepj call s:NetrwRefreshTreeDict(direntry.'/') + let liststar = s:NetrwGlob(direntry.'/','*',1) + let listdotstar= s:NetrwGlob(direntry.'/','.*',1) + let w:netrw_treedict[direntry]= liststar + listdotstar +" call Decho("updating w:netrw_treedict[".direntry.']='.string(w:netrw_treedict[direntry]),'~'.expand("<slnum>")) + + elseif entry =~ '@$' && has_key(w:netrw_treedict,direntry.'@') +" call Decho("<".direntry."/> is a key in treedict - display subtree for it",'~'.expand("<slnum>")) + NetrwKeepj call s:NetrwRefreshTreeDict(direntry.'/') + let liststar = s:NetrwGlob(direntry.'/','*',1) + let listdotstar= s:NetrwGlob(direntry.'/','.*',1) +" call Decho("updating w:netrw_treedict[".direntry.']='.string(w:netrw_treedict[direntry]),'~'.expand("<slnum>")) + + else +" call Decho('not updating w:netrw_treedict['.direntry.'] with entry<'.entry.'> (no subtree)',,'~'.expand("<slnum>")) + endif + endfor +" call Dret("s:NetrwRefreshTreeDict") +endfun + +" --------------------------------------------------------------------- " s:NetrwTreeListing: displays tree listing from treetop on down, using NetrwTreeDisplay() {{{2 " Called by s:PerformListing() fun! s:NetrwTreeListing(dirname) - if w:netrw_liststyle == s:TREELIST + if exists("w:netrw_liststyle") && w:netrw_liststyle == s:TREELIST " call Dfunc("NetrwTreeListing() bufname<".expand("%").">") " call Decho("curdir<".a:dirname.">",'~'.expand("<slnum>")) " call Decho("win#".winnr().": w:netrw_treetop ".(exists("w:netrw_treetop")? "exists" : "doesn't exist")." w:netrw_treedict ".(exists("w:netrw_treedict")? "exists" : "doesn't exit"),'~'.expand("<slnum>")) @@ -8811,13 +9048,13 @@ fun! s:NetrwTreeListing(dirname) let w:netrw_treedict= {} endif - " update the directory listing for the current directory -" call Decho("updating dictionary with ".a:dirname.":[..directory listing..]",'~'.expand("<slnum>")) + " update the dictionary for the current directory +" call Decho("updating: w:netrw_treedict[".a:dirname.'] -> [directory listing]','~'.expand("<slnum>")) " call Decho("w:netrw_bannercnt=".w:netrw_bannercnt." line($)=".line("$"),'~'.expand("<slnum>")) - exe "sil! NetrwKeepj ".w:netrw_bannercnt.',$g@^\.\.\=/$@d' + exe "sil! NetrwKeepj ".w:netrw_bannercnt.',$g@^\.\.\=/$@d _' let w:netrw_treedict[a:dirname]= getline(w:netrw_bannercnt,line("$")) " call Decho("w:treedict[".a:dirname."]= ".string(w:netrw_treedict[a:dirname]),'~'.expand("<slnum>")) - exe "sil! NetrwKeepj ".w:netrw_bannercnt.",$d" + exe "sil! NetrwKeepj ".w:netrw_bannercnt.",$d _" " if past banner, record word if exists("w:netrw_bannercnt") && line(".") > w:netrw_bannercnt @@ -8852,6 +9089,8 @@ endfun " wipes that out prior to calling this function fun! s:NetrwTreePath(treetop) " call Dfunc("s:NetrwTreePath() line#".line(".")."<".getline(".").">") + let svpos = winsaveview() +" call Decho("saving posn to svpos<".string(svpos).">",'~'.expand("<slnum>")) let depth = substitute(getline('.'),'^\(\%('.s:treedepthstring.'\)*\)[^'.s:treedepthstring.'].\{-}$','\1','e') " call Decho("depth<".depth."> 1st subst",'~'.expand("<slnum>")) let depth = substitute(depth,'^'.s:treedepthstring,'','') @@ -8886,6 +9125,8 @@ fun! s:NetrwTreePath(treetop) let treedir= a:treetop.'/'.treedir endif let treedir= substitute(treedir,'//$','/','') +" call Decho("restoring posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))" + call winrestview(svpos) " call Dret("s:NetrwTreePath <".treedir.">") return treedir endfun @@ -8930,6 +9171,7 @@ fun! s:NetrwWideListing() " call Decho("bannercnt=".w:netrw_bannercnt." fpl=".w:netrw_fpl." fpc=".fpc." newcol[".newcolstart.",".newcolend."]",'~'.expand("<slnum>")) if has("clipboard") sil! let keepregstar = @* + sil! let keepregplus = @+ endif while line("$") >= newcolstart if newcolend > line("$") | let newcolend= line("$") | endif @@ -8940,11 +9182,12 @@ fun! s:NetrwWideListing() else exe "sil! NetrwKeepj norm! 0\<c-v>".newcolqty.'j$hx'.w:netrw_bannercnt.'G$p' endif - exe "sil! NetrwKeepj ".newcolstart.','.newcolend.'d' + exe "sil! NetrwKeepj ".newcolstart.','.newcolend.'d _' exe 'sil! NetrwKeepj '.w:netrw_bannercnt endwhile if has("clipboard") sil! let @*= keepregstar + sil! let @+= keepregplus endif exe "sil! NetrwKeepj ".w:netrw_bannercnt.',$s/\s\+$//e' NetrwKeepj call histdel("/",-1) @@ -9027,14 +9270,14 @@ fun! s:PerformListing(islocal) " call Decho("tab#".tabpagenr()." win#".winnr()." buf#".bufnr("%")."<".bufname("%")."> line#".line(".")." col#".col(".")." winline#".winline()." wincol#".wincol()." line($)=".line("$"),'~'.expand("<slnum>")) let sortby= g:netrw_sort_by - if g:netrw_sort_direction =~ "^r" + if g:netrw_sort_direction =~# "^r" let sortby= sortby." reversed" endif " Sorted by... {{{3 if g:netrw_banner " call Decho("--handle specified sorting: g:netrw_sort_by<".g:netrw_sort_by.">",'~'.expand("<slnum>")) - if g:netrw_sort_by =~ "^n" + if g:netrw_sort_by =~# "^n" " call Decho("directories will be sorted by name",'~'.expand("<slnum>")) " sorted by name NetrwKeepj put ='\" Sorted by '.sortby @@ -9131,13 +9374,13 @@ fun! s:PerformListing(islocal) if !g:netrw_banner || line("$") >= w:netrw_bannercnt " call Decho("manipulate directory listing (sort) : g:netrw_sort_by<".g:netrw_sort_by.">",'~'.expand("<slnum>")) - if g:netrw_sort_by =~ "^n" + if g:netrw_sort_by =~# "^n" " sort by name NetrwKeepj call s:NetrwSetSort() if !g:netrw_banner || w:netrw_bannercnt < line("$") " call Decho("g:netrw_sort_direction=".g:netrw_sort_direction." (bannercnt=".w:netrw_bannercnt.")",'~'.expand("<slnum>")) - if g:netrw_sort_direction =~ 'n' + if g:netrw_sort_direction =~# 'n' " normal direction sorting exe 'sil NetrwKeepj '.w:netrw_bannercnt.',$sort'.' '.g:netrw_sort_options else @@ -9150,7 +9393,7 @@ fun! s:PerformListing(islocal) exe 'sil! NetrwKeepj '.w:netrw_bannercnt.',$s/^\d\{3}'.g:netrw_sepchr.'//e' NetrwKeepj call histdel("/",-1) - elseif g:netrw_sort_by =~ "^ext" + elseif g:netrw_sort_by =~# "^ext" " sort by extension exe 'sil NetrwKeepj '.w:netrw_bannercnt.',$g+/+s/^/001'.g:netrw_sepchr.'/' NetrwKeepj call histdel("/",-1) @@ -9160,7 +9403,7 @@ fun! s:PerformListing(islocal) NetrwKeepj call histdel("/",-1) if !g:netrw_banner || w:netrw_bannercnt < line("$") " call Decho("g:netrw_sort_direction=".g:netrw_sort_direction." (bannercnt=".w:netrw_bannercnt.")",'~'.expand("<slnum>")) - if g:netrw_sort_direction =~ 'n' + if g:netrw_sort_direction =~# 'n' " normal direction sorting exe 'sil NetrwKeepj '.w:netrw_bannercnt.',$sort'.' '.g:netrw_sort_options else @@ -9174,7 +9417,7 @@ fun! s:PerformListing(islocal) elseif a:islocal if !g:netrw_banner || w:netrw_bannercnt < line("$") " call Decho("g:netrw_sort_direction=".g:netrw_sort_direction,'~'.expand("<slnum>")) - if g:netrw_sort_direction =~ 'n' + if g:netrw_sort_direction =~# 'n' " call Decho('exe sil NetrwKeepj '.w:netrw_bannercnt.',$sort','~'.expand("<slnum>")) exe 'sil! NetrwKeepj '.w:netrw_bannercnt.',$sort'.' '.g:netrw_sort_options else @@ -9186,7 +9429,7 @@ fun! s:PerformListing(islocal) endif endif - elseif g:netrw_sort_direction =~ 'r' + elseif g:netrw_sort_direction =~# 'r' " call Decho('(s:PerformListing) reverse the sorted listing','~'.expand("<slnum>")) if !g:netrw_banner || w:netrw_bannercnt < line('$') exe 'sil! NetrwKeepj '.w:netrw_bannercnt.',$g/^/m '.w:netrw_bannercnt @@ -9205,7 +9448,7 @@ fun! s:PerformListing(islocal) " call Decho("settings buf#".bufnr("%")."<".bufname("%").">: ".((&l:ma == 0)? "no" : "")."ma ".((&l:mod == 0)? "no" : "")."mod ".((&l:bl == 0)? "no" : "")."bl ".((&l:ro == 0)? "no" : "")."ro fo=".&l:fo. " (internal#3)",'~'.expand("<slnum>")) " resolve symbolic links if local and (thin or tree) - if a:islocal && (w:netrw_liststyle == s:THINLIST || w:netrw_liststyle == s:TREELIST) + if a:islocal && (w:netrw_liststyle == s:THINLIST || (exists("w:netrw_liststyle") && w:netrw_liststyle == s:TREELIST)) " call Decho("--resolve symbolic links if local and thin|tree",'~'.expand("<slnum>")) g/@$/call s:ShowLink() endif @@ -9247,7 +9490,8 @@ fun! s:PerformListing(islocal) if exists("s:treecurpos") " call Decho("s:treecurpos exists; restore posn",'~'.expand("<slnum>")) " call Decho("settings buf#".bufnr("%")."<".bufname("%").">: ".((&l:ma == 0)? "no" : "")."ma ".((&l:mod == 0)? "no" : "")."mod ".((&l:bl == 0)? "no" : "")."bl ".((&l:ro == 0)? "no" : "")."ro fo=".&l:fo. " (internal#8)",'~'.expand("<slnum>")) - NetrwKeepj call netrw#RestorePosn(s:treecurpos) +" call Decho("restoring posn to s:treecurpos<".string(s:treecurpos).">",'~'.expand("<slnum>")) + NetrwKeepj call winrestview(s:treecurpos) unlet s:treecurpos endif @@ -9310,7 +9554,7 @@ endfun " enforced here. fun! s:NetrwRemoteFtpCmd(path,listcmd) " call Dfunc("NetrwRemoteFtpCmd(path<".a:path."> listcmd<".a:listcmd.">) w:netrw_method=".(exists("w:netrw_method")? w:netrw_method : (exists("b:netrw_method")? b:netrw_method : "???"))) -" call Decho("line($)=".line("$")." w:netrw_bannercnt=".w:netrw_bannercnt,'~'.expand("<slnum>")) +" call Decho("line($)=".line("$")." win#".winnr()." w:netrw_bannercnt=".w:netrw_bannercnt,'~'.expand("<slnum>")) " sanity check: {{{3 if !exists("w:netrw_method") if exists("b:netrw_method") @@ -9329,8 +9573,8 @@ fun! s:NetrwRemoteFtpCmd(path,listcmd) " clear off any older non-banner lines " {{{3 " note that w:netrw_bannercnt indexes the line after the banner -" call Decho('exe sil! NetrwKeepj '.w:netrw_bannercnt.",$d (clear off old non-banner lines)",'~'.expand("<slnum>")) - exe "sil! NetrwKeepj ".w:netrw_bannercnt.",$d" +" call Decho('exe sil! NetrwKeepj '.w:netrw_bannercnt.",$d _ (clear off old non-banner lines)",'~'.expand("<slnum>")) + exe "sil! NetrwKeepj ".w:netrw_bannercnt.",$d _" "......................................... if w:netrw_method == 2 || w:netrw_method == 5 " {{{3 @@ -9427,7 +9671,7 @@ fun! s:NetrwRemoteFtpCmd(path,listcmd) sil! NetrwKeepj g/l\%([-r][-w][-x]\)\{3}/NetrwKeepj s/$/@/e NetrwKeepj call histdel("/",-1) NetrwKeepj call histdel("/",-1) - if w:netrw_liststyle == s:THINLIST || w:netrw_liststyle == s:WIDELIST || w:netrw_liststyle == s:TREELIST + if w:netrw_liststyle == s:THINLIST || w:netrw_liststyle == s:WIDELIST || (exists("w:netrw_liststyle") && w:netrw_liststyle == s:TREELIST) exe "sil! NetrwKeepj ".w:netrw_bannercnt.',$s/^\%(\S\+\s\+\)\{8}//e' NetrwKeepj call histdel("/",-1) endif @@ -9451,7 +9695,7 @@ endfun " --------------------------------------------------------------------- " s:NetrwRemoteListing: {{{2 fun! s:NetrwRemoteListing() -" call Dfunc("s:NetrwRemoteListing() b:netrw_curdir<".b:netrw_curdir.">)") +" call Dfunc("s:NetrwRemoteListing() b:netrw_curdir<".b:netrw_curdir.">) win#".winnr()) if !exists("w:netrw_bannercnt") && exists("s:bannercnt") let w:netrw_bannercnt= s:bannercnt @@ -9501,9 +9745,9 @@ fun! s:NetrwRemoteListing() " call Decho("use ftp to get remote file listing",'~'.expand("<slnum>")) let s:method = "ftp" let listcmd = g:netrw_ftp_list_cmd - if g:netrw_sort_by =~ '^t' + if g:netrw_sort_by =~# '^t' let listcmd= g:netrw_ftp_timelist_cmd - elseif g:netrw_sort_by =~ '^s' + elseif g:netrw_sort_by =~# '^s' let listcmd= g:netrw_ftp_sizelist_cmd endif " call Decho("listcmd<".listcmd."> (using g:netrw_ftp_list_cmd)",'~'.expand("<slnum>")) @@ -9515,7 +9759,7 @@ fun! s:NetrwRemoteListing() let mesg= getline(".") if exists("w:netrw_bannercnt") setl ma - exe w:netrw_bannercnt.",$d" + exe w:netrw_bannercnt.",$d _" setl noma endif NetrwKeepj call s:NetrwOptionRestore("w:") @@ -9524,7 +9768,7 @@ fun! s:NetrwRemoteListing() return -1 endif - if w:netrw_liststyle == s:THINLIST || w:netrw_liststyle == s:WIDELIST || w:netrw_liststyle == s:TREELIST + if w:netrw_liststyle == s:THINLIST || w:netrw_liststyle == s:WIDELIST || (exists("w:netrw_liststyle") && w:netrw_liststyle == s:TREELIST) " shorten the listing " call Decho("generate short listing",'~'.expand("<slnum>")) exe "sil! keepalt NetrwKeepj ".w:netrw_bannercnt @@ -9610,7 +9854,7 @@ fun! s:NetrwRemoteListing() if s:method == "ftp" " cleanup exe "sil! NetrwKeepj ".w:netrw_bannercnt - while getline('.') =~ g:netrw_ftp_browse_reject + while getline('.') =~# g:netrw_ftp_browse_reject sil! NetrwKeepj d endwhile " if there's no ../ listed, then put ../ in @@ -9654,7 +9898,8 @@ endfun fun! s:NetrwRemoteRm(usrhost,path) range " call Dfunc("s:NetrwRemoteRm(usrhost<".a:usrhost."> path<".a:path.">) virtcol=".virtcol(".")) " call Decho("firstline=".a:firstline." lastline=".a:lastline,'~'.expand("<slnum>")) - let svpos= netrw#SavePosn() + let svpos= winsaveview() +" call Decho("saving posn to svpos<".string(svpos).">",'~'.expand("<slnum>")) let all= 0 if exists("s:netrwmarkfilelist_{bufnr('%')}") @@ -9662,9 +9907,9 @@ fun! s:NetrwRemoteRm(usrhost,path) range " call Decho("remove all marked files with bufnr#".bufnr("%"),'~'.expand("<slnum>")) for fname in s:netrwmarkfilelist_{bufnr("%")} let ok= s:NetrwRemoteRmFile(a:path,fname,all) - if ok =~ 'q\%[uit]' + if ok =~# 'q\%[uit]' break - elseif ok =~ 'a\%[ll]' + elseif ok =~# 'a\%[ll]' let all= 1 endif endfor @@ -9683,9 +9928,9 @@ fun! s:NetrwRemoteRm(usrhost,path) range while ctr <= a:lastline exe "NetrwKeepj ".ctr let ok= s:NetrwRemoteRmFile(a:path,s:NetrwGetWord(),all) - if ok =~ 'q\%[uit]' + if ok =~# 'q\%[uit]' break - elseif ok =~ 'a\%[ll]' + elseif ok =~# 'a\%[ll]' let all= 1 endif let ctr= ctr + 1 @@ -9696,7 +9941,8 @@ fun! s:NetrwRemoteRm(usrhost,path) range " refresh the (remote) directory listing " call Decho("refresh remote directory listing",'~'.expand("<slnum>")) NetrwKeepj call s:NetrwRefresh(0,s:NetrwBrowseChgDir(0,'./')) - NetrwKeepj call netrw#RestorePosn(svpos) +" call Decho("restoring posn to svpos<".string(svpos).">",'~'.expand("<slnum>")) + NetrwKeepj call winrestview(svpos) " call Dret("s:NetrwRemoteRm") endfun @@ -9723,12 +9969,12 @@ fun! s:NetrwRemoteRmFile(path,rmfile,all) let ok="no" endif let ok= substitute(ok,'\[{y(es)},n(o),a(ll),q(uit)]\s*','','e') - if ok =~ 'a\%[ll]' + if ok =~# 'a\%[ll]' let all= 1 endif endif - if all || ok =~ 'y\%[es]' || ok == "" + if all || ok =~# 'y\%[es]' || ok == "" " call Decho("case all=".all." or ok<".ok.">".(exists("w:netrw_method")? ': netrw_method='.w:netrw_method : ""),'~'.expand("<slnum>")) if exists("w:netrw_method") && (w:netrw_method == 2 || w:netrw_method == 3) " call Decho("case ftp:",'~'.expand("<slnum>")) @@ -9736,7 +9982,7 @@ fun! s:NetrwRemoteRmFile(path,rmfile,all) if path =~ '^\a\{3,}://' let path= substitute(path,'^\a\{3,}://[^/]\+/','','') endif - sil! NetrwKeepj .,$d + sil! NetrwKeepj .,$d _ call s:NetrwRemoteFtpCmd(path,"delete ".'"'.a:rmfile.'"') else " call Decho("case ssh: g:netrw_rm_cmd<".g:netrw_rm_cmd.">",'~'.expand("<slnum>")) @@ -9763,13 +10009,13 @@ fun! s:NetrwRemoteRmFile(path,rmfile,all) else call netrw#ErrorMsg(s:WARNING,"cmd<".netrw_rm_cmd."> failed",60) endif - else if ret != 0 + elseif ret != 0 call netrw#ErrorMsg(s:WARNING,"cmd<".netrw_rm_cmd."> failed",60) endif " call Decho("returned=".ret." errcode=".v:shell_error,'~'.expand("<slnum>")) endif endif - elseif ok =~ 'q\%[uit]' + elseif ok =~# 'q\%[uit]' " call Decho("ok==".ok,'~'.expand("<slnum>")) endif @@ -9784,12 +10030,12 @@ fun! s:NetrwRemoteRmFile(path,rmfile,all) let ok="no" endif let ok= substitute(ok,'\[{y(es)},n(o),a(ll),q(uit)]\s*','','e') - if ok =~ 'a\%[ll]' + if ok =~# 'a\%[ll]' let all= 1 endif endif - if all || ok =~ 'y\%[es]' || ok == "" + if all || ok =~# 'y\%[es]' || ok == "" if exists("w:netrw_method") && (w:netrw_method == 2 || w:netrw_method == 3) NetrwKeepj call s:NetrwRemoteFtpCmd(a:path,"rmdir ".a:rmfile) else @@ -9812,7 +10058,7 @@ fun! s:NetrwRemoteRmFile(path,rmfile,all) endif endif - elseif ok =~ 'q\%[uit]' + elseif ok =~# 'q\%[uit]' " call Decho("ok==".ok,'~'.expand("<slnum>")) endif endif @@ -9827,7 +10073,8 @@ fun! s:NetrwRemoteRename(usrhost,path) range " call Dfunc("NetrwRemoteRename(usrhost<".a:usrhost."> path<".a:path.">)") " preparation for removing multiple files/directories - let svpos = netrw#SavePosn() + let svpos = winsaveview() +" call Decho("saving posn to svpos<".string(svpos).">",'~'.expand("<slnum>")) let ctr = a:firstline let rename_cmd = s:MakeSshCmd(g:netrw_rename_cmd) @@ -9893,7 +10140,8 @@ fun! s:NetrwRemoteRename(usrhost,path) range " refresh the directory NetrwKeepj call s:NetrwRefresh(0,s:NetrwBrowseChgDir(0,'./')) - NetrwKeepj call netrw#RestorePosn(svpos) +" call Decho("restoring posn to svpos<".string(svpos).">",'~'.expand("<slnum>")) + NetrwKeepj call winrestview(svpos) " call Dret("NetrwRemoteRename") endfun @@ -9955,7 +10203,7 @@ endfun " --------------------------------------------------------------------- " netrw#LocalBrowseCheck: {{{2 fun! netrw#LocalBrowseCheck(dirname) - " This function is called by netrwPlugin.vim's s:LocalBrowse() and by s:NetrwRexplore() + " This function is called by netrwPlugin.vim's s:LocalBrowse(), s:NetrwRexplore(), and by <cr> when atop listed file/directory " unfortunate interaction -- split window debugging can't be " used here, must use D-echoRemOn or D-echoTabOn -- the BufEnter " event triggers another call to LocalBrowseCheck() when attempts @@ -9964,7 +10212,7 @@ fun! netrw#LocalBrowseCheck(dirname) " would hit when re-entering netrw windows, creating unexpected " refreshes (and would do so in the middle of NetrwSaveOptions(), too) " call Dfunc("netrw#LocalBrowseCheck(dirname<".a:dirname.">") -" call Decho("isdir<".a:dirname.">=".isdirectory(s:NetrwFile(a:dirname)).((exists("s:treeforceredraw")? " treeforceredraw" : "")).expand("<slnum>")) +" call Decho("isdir<".a:dirname."> =".isdirectory(s:NetrwFile(a:dirname)).((exists("s:treeforceredraw")? " treeforceredraw" : "")).'~'.expand("<slnum>")) " call Decho("settings buf#".bufnr("%")."<".bufname("%").">: ".((&l:ma == 0)? "no" : "")."ma ".((&l:mod == 0)? "no" : "")."mod ".((&l:bl == 0)? "no" : "")."bl ".((&l:ro == 0)? "no" : "")."ro fo=".&l:fo,'~'.expand("<slnum>")) " call Dredir("ls!","ls!") " call Decho("tab#".tabpagenr()." win#".winnr()." buf#".bufnr("%")."<".bufname("%")."> line#".line(".")." col#".col(".")." winline#".winline()." wincol#".wincol(),'~'.expand("<slnum>")) @@ -9988,7 +10236,6 @@ fun! netrw#LocalBrowseCheck(dirname) unlet s:treeforceredraw sil! NetrwKeepj keepalt call s:NetrwBrowse(1,a:dirname) endif - " call Decho("tab#".tabpagenr()." win#".winnr()." buf#".bufnr("%")."<".bufname("%")."> line#".line(".")." col#".col(".")." winline#".winline()." wincol#".wincol(),'~'.expand("<slnum>")) " call Dret("netrw#LocalBrowseCheck") return @@ -10068,12 +10315,15 @@ fun! s:LocalBrowseRefresh() " refresh any netrw buffer " call Decho("refresh buf#".ibuf.'-> win#'.bufwinnr(ibuf),'~'.expand("<slnum>")) exe bufwinnr(ibuf)."wincmd w" - if getline(".") =~ 'Quick Help' + if getline(".") =~# 'Quick Help' " decrement g:netrw_quickhelp to prevent refresh from changing g:netrw_quickhelp " (counteracts s:NetrwBrowseChgDir()'s incrementing) let g:netrw_quickhelp= g:netrw_quickhelp - 1 endif " call Decho("#3: quickhelp=".g:netrw_quickhelp,'~'.expand("<slnum>")) + if exists("w:netrw_liststyle") && w:netrw_liststyle == s:TREELIST + NetrwKeepj call s:NetrwRefreshTreeDict(w:netrw_treetop) + endif NetrwKeepj call s:NetrwRefresh(1,s:NetrwBrowseChgDir(1,'./')) endif let ibl= ibl + 1 @@ -10171,15 +10421,8 @@ fun! s:LocalListing() " get the list of files contained in the current directory let dirname = b:netrw_curdir let dirnamelen = strlen(b:netrw_curdir) - if v:version == 704 && has("patch656") -" call Decho("using glob with patch656",'~'.expand("<slnum>")) - let filelist = glob(s:ComposePath(dirname,"*"),0,1,1) - let filelist = filelist + glob(s:ComposePath(dirname,".*"),0,1,1) - else -" call Decho("using glob without patch656",'~'.expand("<slnum>")) - let filelist = glob(s:ComposePath(dirname,"*"),0,1) - let filelist = filelist + glob(s:ComposePath(dirname,".*"),0,1) - endif + let filelist = s:NetrwGlob(dirname,"*",0) + let filelist = filelist + s:NetrwGlob(dirname,".*",0) " call Decho("filelist=".string(filelist),'~'.expand("<slnum>")) if g:netrw_cygwin == 0 && (has("win32") || has("win95") || has("win64") || has("win16")) @@ -10191,9 +10434,9 @@ fun! s:LocalListing() " call Decho("filelist=".string(filelist),'~'.expand("<slnum>")) endif -" call Decho("before while: dirname<".dirname.">",'~'.expand("<slnum>")) +" call Decho("before while: dirname <".dirname.">",'~'.expand("<slnum>")) " call Decho("before while: dirnamelen<".dirnamelen.">",'~'.expand("<slnum>")) -" call Decho("before while: filelist=".string(filelist),'~'.expand("<slnum>")) +" call Decho("before while: filelist =".string(filelist),'~'.expand("<slnum>")) if get(g:, 'netrw_dynamic_maxfilenamelen', 0) let filelistcopy = map(deepcopy(filelist),'fnamemodify(v:val, ":t")') @@ -10263,12 +10506,15 @@ fun! s:LocalListing() if w:netrw_liststyle == s:LONGLIST let sz = getfsize(filename) + if g:netrw_sizestyle =~# "[hH]" + let sz= s:NetrwHumanReadable(sz) + endif let fsz = strpart(" ",1,15-strlen(sz)).sz let pfile= pfile."\t".fsz." ".strftime(g:netrw_timefmt,getftime(filename)) -" call Decho("sz=".sz." fsz=".fsz,'~'.expand("<slnum>")) +" call Decho("longlist support: sz=".sz." fsz=".fsz,'~'.expand("<slnum>")) endif - if g:netrw_sort_by =~ "^t" + if g:netrw_sort_by =~# "^t" " sort by time (handles time up to 1 quintillion seconds, US) " call Decho("getftime(".filename.")=".getftime(filename),'~'.expand("<slnum>")) let t = getftime(filename) @@ -10281,6 +10527,9 @@ fun! s:LocalListing() " sort by size (handles file sizes up to 1 quintillion bytes, US) " call Decho("getfsize(".filename.")=".getfsize(filename),'~'.expand("<slnum>")) let sz = getfsize(filename) + if g:netrw_sizestyle =~# "[hH]" + let sz= s:NetrwHumanReadable(sz) + endif let fsz = strpart("000000000000000000",1,18-strlen(sz)).sz " call Decho("exe NetrwKeepj put ='".fsz.'/'.filename."'",'~'.expand("<slnum>")) let fszpfile= fsz.'/'.pfile @@ -10339,7 +10588,8 @@ fun! s:NetrwLocalRename(path) range " preparation for removing multiple files/directories let ykeep = @@ let ctr = a:firstline - let svpos = netrw#SavePosn() + let svpos = winsaveview() +" call Decho("saving posn to svpos<".string(svpos).">",'~'.expand("<slnum>")) " rename files given by the markfilelist if exists("s:netrwmarkfilelist_{bufnr('%')}") @@ -10405,7 +10655,8 @@ fun! s:NetrwLocalRename(path) range " refresh the directory " call Decho("refresh the directory listing",'~'.expand("<slnum>")) NetrwKeepj call s:NetrwRefresh(1,s:NetrwBrowseChgDir(1,'./')) - NetrwKeepj call netrw#RestorePosn(svpos) +" call Decho("restoring posn to svpos<".string(svpos).">",'~'.expand("<slnum>")) + NetrwKeepj call winrestview(svpos) let @@= ykeep " call Dret("NetrwLocalRename") @@ -10421,16 +10672,17 @@ fun! s:NetrwLocalRm(path) range let ykeep = @@ let ret = 0 let all = 0 - let svpos = netrw#SavePosn() + let svpos = winsaveview() +" call Decho("saving posn to svpos<".string(svpos).">",'~'.expand("<slnum>")) if exists("s:netrwmarkfilelist_{bufnr('%')}") " remove all marked files " call Decho("remove all marked files",'~'.expand("<slnum>")) for fname in s:netrwmarkfilelist_{bufnr("%")} let ok= s:NetrwLocalRmFile(a:path,fname,all) - if ok =~ 'q\%[uit]' || ok == "no" + if ok =~# 'q\%[uit]' || ok == "no" break - elseif ok =~ 'a\%[ll]' + elseif ok =~# 'a\%[ll]' let all= 1 endif endfor @@ -10457,9 +10709,9 @@ fun! s:NetrwLocalRm(path) range continue endif let ok= s:NetrwLocalRmFile(a:path,curword,all) - if ok =~ 'q\%[uit]' || ok == "no" + if ok =~# 'q\%[uit]' || ok == "no" break - elseif ok =~ 'a\%[ll]' + elseif ok =~# 'a\%[ll]' let all= 1 endif let ctr= ctr + 1 @@ -10471,7 +10723,8 @@ fun! s:NetrwLocalRm(path) range " call Decho("bufname<".bufname("%").">",'~'.expand("<slnum>")) if bufname("%") != "NetrwMessage" NetrwKeepj call s:NetrwRefresh(1,s:NetrwBrowseChgDir(1,'./')) - NetrwKeepj call netrw#RestorePosn(svpos) +" call Decho("restoring posn to svpos<".string(svpos).">",'~'.expand("<slnum>")) + NetrwKeepj call winrestview(svpos) endif let @@= ykeep @@ -10505,12 +10758,12 @@ fun! s:NetrwLocalRmFile(path,fname,all) " call Decho("response: ok<".ok.">",'~'.expand("<slnum>")) let ok= substitute(ok,'\[{y(es)},n(o),a(ll),q(uit)]\s*','','e') " call Decho("response: ok<".ok."> (after sub)",'~'.expand("<slnum>")) - if ok =~ 'a\%[ll]' + if ok =~# 'a\%[ll]' let all= 1 endif endif - if all || ok =~ 'y\%[es]' || ok == "" + if all || ok =~# 'y\%[es]' || ok == "" let ret= s:NetrwDelete(rmfile) " call Decho("errcode=".v:shell_error." ret=".ret,'~'.expand("<slnum>")) endif @@ -10526,35 +10779,41 @@ fun! s:NetrwLocalRmFile(path,fname,all) if ok == "" let ok="no" endif - if ok =~ 'a\%[ll]' + if ok =~# 'a\%[ll]' let all= 1 endif endif let rmfile= substitute(rmfile,'[\/]$','','e') - if all || ok =~ 'y\%[es]' || ok == "" -" call Decho("1st attempt: system(netrw#WinPath(".g:netrw_localrmdir.') '.s:ShellEscape(rmfile).')','~'.expand("<slnum>")) - call system(netrw#WinPath(g:netrw_localrmdir).' '.s:ShellEscape(rmfile)) -" call Decho("v:shell_error=".v:shell_error,'~'.expand("<slnum>")) + if all || ok =~# 'y\%[es]' || ok == "" + if v:version < 704 || !has("patch1109") +" " call Decho("1st attempt: system(netrw#WinPath(".g:netrw_localrmdir.') '.s:ShellEscape(rmfile).')','~'.expand("<slnum>")) + call system(netrw#WinPath(g:netrw_localrmdir).' '.s:ShellEscape(rmfile)) +" " call Decho("v:shell_error=".v:shell_error,'~'.expand("<slnum>")) - if v:shell_error != 0 -" call Decho("2nd attempt to remove directory<".rmfile.">",'~'.expand("<slnum>")) - let errcode= s:NetrwDelete(rmfile) -" call Decho("errcode=".errcode,'~'.expand("<slnum>")) - - if errcode != 0 - if has("unix") -" call Decho("3rd attempt to remove directory<".rmfile.">",'~'.expand("<slnum>")) - call system("rm ".s:ShellEscape(rmfile)) - if v:shell_error != 0 && !exists("g:netrw_quiet") - call netrw#ErrorMsg(s:ERROR,"unable to remove directory<".rmfile."> -- is it empty?",34) + if v:shell_error != 0 +" " call Decho("2nd attempt to remove directory<".rmfile.">",'~'.expand("<slnum>")) + let errcode= s:NetrwDelete(rmfile) +" " call Decho("errcode=".errcode,'~'.expand("<slnum>")) + + if errcode != 0 + if has("unix") +" " call Decho("3rd attempt to remove directory<".rmfile.">",'~'.expand("<slnum>")) + call system("rm ".s:ShellEscape(rmfile)) + if v:shell_error != 0 && !exists("g:netrw_quiet") + call netrw#ErrorMsg(s:ERROR,"unable to remove directory<".rmfile."> -- is it empty?",34) + let ok="no" + endif + elseif !exists("g:netrw_quiet") + call netrw#ErrorMsg(s:ERROR,"unable to remove directory<".rmfile."> -- is it empty?",35) let ok="no" endif - elseif !exists("g:netrw_quiet") - call netrw#ErrorMsg(s:ERROR,"unable to remove directory<".rmfile."> -- is it empty?",35) - let ok="no" endif endif + else + if delete(rmfile,"d") + call netrw#ErrorMsg(s:ERROR,"unable to delete directory <".rmfile.">!",103) + endif endif endif endif @@ -10567,6 +10826,17 @@ endfun " Support Functions: {{{1 " --------------------------------------------------------------------- +" s:WinNames: COMBAK {{{2 +fun! s:WinNames(id) + let curwin= winnr() + 1wincmd w +" call Decho("--- Windows By Name --- #".a:id) +" windo call Decho("win#".winnr()."<".expand("%").">") +" call Decho("--- --- --- --- --- ---") + exe curwin."wincmd w" +endfun + +" --------------------------------------------------------------------- " netrw#Access: intended to provide access to variable values for netrw's test suite {{{2 " 0: marked file list of current buffer " 1: marked file target @@ -10593,83 +10863,6 @@ fun! netrw#Call(funcname,...) " call Dret("netrw#Call") endfun -" ------------------------------------------------------------------------ -" netrw#RestorePosn: restores the cursor and file position as saved by netrw#SavePosn() {{{2 -fun! netrw#RestorePosn(...) -" call Dfunc("netrw#RestorePosn() a:0=".a:0." 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 - setl ei=all - if expand("%") == "NetrwMessage" - if exists("s:winBeforeErr") - exe s:winBeforeErr."wincmd w" - endif - endif - - if a:0 > 0 - exe "keepj ".a:1 - endif -" "call Decho("a:1 = ".((a:0 > 0)? a:1 : 'n/a'),'~'.expand("<slnum>")) -" "call Decho("liststyle = ".(exists("liststyle")? liststyle : 'n/a'). " w:netrw_liststyle=".(exists("w:netrw_liststyle")? w:netrw_liststyle : 'n/a'),'~'.expand("<slnum>")) - if exists("liststyle") && exists("w:netrw_liststyle") && liststyle != w:netrw_liststyle - let usesrch= 1 - else - let usesrch= 0 - endif - -" "call Decho("winh = ".(exists("w:netrw_winh")? w:netrw_winh : -1),'~'.expand("<slnum>")) -" "call Decho("winw = ".(exists("w:netrw_winw")? w:netrw_winw : -1),'~'.expand("<slnum>")) -" "call Decho("cur winheight=".winheight(0)." winwidth=".winwidth(0),'~'.expand("<slnum>")) -" "call Decho("w:netrw_winfile = ".(exists("w:netrw_winfile")? w:netrw_winfile : 'n/a'),'~'.expand("<slnum>")) - - " restore window - if exists("w:netrw_winnr") -" "call Decho("restore window: exe sil! ".w:netrw_winnr."wincmd w",'~'.expand("<slnum>")) - exe "sil! ".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 - if exists("w:netrw_hline") -" "call Decho("restore topofscreen: exe keepj norm! ".w:netrw_hline."G0z",'~'.expand("<slnum>")) - exe "keepj norm! ".w:netrw_hline."G0z\<CR>" - endif - - " restore position - " when the window's height x width has changed, the line,col is no longer useful - if w:netrw_winh == winheight(0) && w:netrw_winw == winwidth(0) && exists("w:netrw_line") && exists("w:netrw_col") && !usesrch -" "call Decho("using posn: exe keepj norm! ".w:netrw_line."G0".w:netrw_col."|",'~'.expand("<slnum>")) - exe "keepj norm! ".w:netrw_line."G0".w:netrw_col."\<bar>" - - elseif exists("w:netrw_winfile") - if !search('\<'.escape(w:netrw_winfile,g:netrw_fname_escape),'cw') - if exists("w:netrw_bannercnt") -" "call Decho("using bannercnt: win#".winnr()." ".winheight(0)."x".winwidth(0)." w:netrw_winfile<".w:netrw_winfile.">",'~'.expand("<slnum>")) - exe "keepj ".w:netrw_bannercnt - norm! 0 - else - " go to upper left corner -" "call Decho("goto ulc: win#".winnr()." ".winheight(0)."x".winwidth(0)." w:netrw_winfile<".w:netrw_winfile.">",'~'.expand("<slnum>")) - keepj 1 - norm! 0 - endif - else -" "call Decho("used search: w:netrw_winfile<".w:netrw_winfile.">",'~'.expand("<slnum>")) - endif - - else -" "call Decho("goto ulc: win#".winnr()." ".winheight(0)."x".winwidth(0),'~'.expand("<slnum>")) - keepj 1 - norm! 0 - endif - - let &ei= eikeep -" call Dret("netrw#RestorePosn : line#".line(".")." col#".col(".")." winline#".winline()." wincol#".wincol()) -endfun - " --------------------------------------------------------------------- " netrw#Expose: allows UserMaps and pchk to look at otherwise script-local variables {{{2 " I expect this function to be used in @@ -10677,18 +10870,22 @@ endfun " for example. fun! netrw#Expose(varname) " call Dfunc("netrw#Expose(varname<".a:varname.">)") - exe "let retval= s:".a:varname - if exists("g:netrw_pchk") - if type(retval) == 3 - let retval = copy(retval) - let i = 0 - while i < len(retval) - let retval[i]= substitute(retval[i],expand("$HOME"),'~','') - let i = i + 1 - endwhile + if exists("s:".a:varname) + exe "let retval= s:".a:varname + if exists("g:netrw_pchk") + if type(retval) == 3 + let retval = copy(retval) + let i = 0 + while i < len(retval) + let retval[i]= substitute(retval[i],expand("$HOME"),'~','') + let i = i + 1 + endwhile + endif +" call Dret("netrw#Expose ".string(retval)) + return string(retval) endif -" call Dret("netrw#Expose ".string(retval)) - return string(retval) + else + let retval= "n/a" endif " call Dret("netrw#Expose ".string(retval)) @@ -10713,48 +10910,6 @@ fun! netrw#RFC2396(fname) endfun " --------------------------------------------------------------------- -" netrw#SavePosn: saves position of cursor on screen {{{2 -fun! netrw#SavePosn() -" call Dfunc("netrw#SavePosn() win#".winnr()." line#".line(".")." col#".col(".")." winline#".winline()." wincol#".wincol()) - " Save current line and column - let w:netrw_winnr= winnr() - let w:netrw_line = line(".") - let w:netrw_col = virtcol(".") -" "call Decho("currently, win#".w:netrw_winnr." line#".w:netrw_line." col#".w:netrw_col,'~'.expand("<slnum>")) - - " save filename under cursor -" "call Decho("line#".line(".")." w:netrw_bannercnt=".(exists("w:netrw_bannercnt")? w:netrw_bannercnt : 'n/a'),'~'.expand("<slnum>")) - if exists("w:netrw_bannercnt") && line(".") >= w:netrw_bannercnt && &ft == "netrw" - let winfile = "|let w:netrw_winfile=\"".fnameescape(s:NetrwGetWord())."\"" - else - let winfile= "" - endif -" "call Decho("winfile<".winfile.">",'~'.expand("<slnum>")) - if exists("w:netrw_liststyle") - let liststyle = "|let liststyle=".w:netrw_liststyle - else - let liststyle= "" - endif -" "call Decho("liststyle=".liststyle,'~'.expand("<slnum>")) - - " Save top-of-screen line - keepj norm! H0 - let w:netrw_hline= line(".") - - " save up alternate position information - " use this when window height x width has changed - let w:netrw_winh = winheight(0) - let w:netrw_winw = winwidth(0) - - " set up string holding position parameters - let ret = "let w:netrw_winnr=".w:netrw_winnr."|let w:netrw_line=".w:netrw_line."|let w:netrw_col=".w:netrw_col."|let w:netrw_hline=".w:netrw_hline."|let w:netrw_winh=".w:netrw_winh."|let w:netrw_winw=".w:netrw_winw.liststyle.winfile - - keepj call netrw#RestorePosn() -" call Dret("netrw#SavePosn : win#=".(exists("w:netrw_winnr")? w:netrw_winnr : "n/a")." line=".(exists("w:netrw_line")? w:netrw_line : "n/a")." col=".(exists("w:netrw_col")? w:netrw_col : "n/a")." hline=".(exists("w:netrw_hline")? w:netrw_hline : "n/a")) - return ret -endfun - -" --------------------------------------------------------------------- " netrw#UserMaps: supports user-specified maps {{{2 " see :help function() " @@ -10823,9 +10978,9 @@ fun! s:ComposePath(base,subdir) " call Decho("amiga",'~'.expand("<slnum>")) let ec = a:base[s:Strlen(a:base)-1] if ec != '/' && ec != ':' - let ret = a:base . "/" . a:subdir + let ret = a:base."/" . a:subdir else - let ret = a:base . a:subdir + let ret = a:base.a:subdir endif elseif a:subdir =~ '^\a:[/\\][^/\\]' && (has("win32") || has("win95") || has("win64") || has("win16")) @@ -11053,10 +11208,10 @@ fun! s:NetrwBMShow() redir END let bmshowlist = split(bmshowraw,'\n') if bmshowlist != [] - let bmshowfuncs= filter(bmshowlist,'v:val =~ "<SNR>\\d\\+_BMShow()"') + let bmshowfuncs= filter(bmshowlist,'v:val =~# "<SNR>\\d\\+_BMShow()"') if bmshowfuncs != [] let bmshowfunc = substitute(bmshowfuncs[0],'^.*:\(call.*BMShow()\).*$','\1','') - if bmshowfunc =~ '^call.*BMShow()' + if bmshowfunc =~# '^call.*BMShow()' exe "sil! NetrwKeepj ".bmshowfunc endif endif @@ -11198,10 +11353,14 @@ fun! s:NetrwEnew(...) NetrwKeepj call s:NetrwOptionRestore("w:") " call Decho("generate a buffer with NetrwKeepj keepalt enew!",'~'.expand("<slnum>")) + " when tree listing uses file TreeListing... a new buffer is made. + " Want the old buffer to be unlisted. + " COMBAK: this causes a problem, see P43 +" setl nobl let netrw_keepdiff= &l:diff noswapfile NetrwKeepj keepalt enew! let &l:diff= netrw_keepdiff -" call Decho("bufnr($)=".bufnr("$")." winnr($)=".winnr("$"),'~'.expand("<slnum>")) +" call Decho("bufnr($)=".bufnr("$")."<".bufname(bufnr("$"))."> winnr($)=".winnr("$"),'~'.expand("<slnum>")) NetrwKeepj call s:NetrwOptionSave("w:") " copy function-local-variables to buffer variable equivalents @@ -11227,8 +11386,9 @@ fun! s:NetrwEnew(...) let b:netrw_curdir= a:1 if b:netrw_curdir =~ '/$' if exists("w:netrw_liststyle") && w:netrw_liststyle == s:TREELIST + setl nobl file NetrwTreeListing - setl bt=nowrite noswf bh=hide + setl nobl bt=nowrite bh=hide nno <silent> <buffer> [ :sil call <SID>TreeListMove('[')<cr> nno <silent> <buffer> ] :sil call <SID>TreeListMove(']')<cr> else @@ -11259,8 +11419,8 @@ endfun " --------------------------------------------------------------------- " s:NetrwInsureWinVars: insure that a netrw buffer has its w: variables in spite of a wincmd v or s {{{2 fun! s:NetrwInsureWinVars() -" call Dfunc("s:NetrwInsureWinVars() win#".winnr()) if !exists("w:netrw_liststyle") +" call Dfunc("s:NetrwInsureWinVars() win#".winnr()) let curbuf = bufnr("%") let curwin = winnr() let iwin = 1 @@ -11280,8 +11440,8 @@ fun! s:NetrwInsureWinVars() let w:{k}= winvars[k] endfor endif +" call Dret("s:NetrwInsureWinVars win#".winnr()) endif -" call Dret("s:NetrwInsureWinVars win#".winnr()) endfun " --------------------------------------------------------------------- @@ -11331,6 +11491,50 @@ fun! s:NetrwSaveWordPosn() endfun " --------------------------------------------------------------------- +" s:NetrwHumanReadable: takes a number and makes it "human readable" {{{2 +" 1000 -> 1K, 1000000 -> 1M, 1000000000 -> 1G +fun! s:NetrwHumanReadable(sz) +" call Dfunc("s:NetrwHumanReadable(sz=".a:sz.") type=".type(a:sz)." style=".g:netrw_sizestyle ) + + if g:netrw_sizestyle == 'h' + if a:sz >= 1000000000 + let sz = printf("%.1f",a:sz/1000000000.0)."g" + elseif a:sz >= 10000000 + let sz = printf("%d",a:sz/1000000)."m" + elseif a:sz >= 1000000 + let sz = printf("%.1f",a:sz/1000000.0)."m" + elseif a:sz >= 10000 + let sz = printf("%d",a:sz/1000)."k" + elseif a:sz >= 1000 + let sz = printf("%.1f",a:sz/1000.0)."k" + else + let sz= a:sz + endif + + elseif g:netrw_sizestyle == 'H' + if a:sz >= 1073741824 + let sz = printf("%.1f",a:sz/1073741824.0)."G" + elseif a:sz >= 10485760 + let sz = printf("%d",a:sz/1048576)."M" + elseif a:sz >= 1048576 + let sz = printf("%.1f",a:sz/1048576.0)."M" + elseif a:sz >= 10240 + let sz = printf("%d",a:sz/1024)."K" + elseif a:sz >= 1024 + let sz = printf("%.1f",a:sz/1024.0)."K" + else + let sz= a:sz + endif + + else + let sz= a:sz + endif + +" call Dret("s:NetrwHumanReadable ".sz) + return sz +endfun + +" --------------------------------------------------------------------- " s:NetrwRestoreWordPosn: used to keep cursor on same word after refresh, {{{2 " changed sorting, etc. Also see s:NetrwSaveWordPosn(). fun! s:NetrwRestoreWordPosn() @@ -11442,14 +11646,14 @@ endfun " s:SetRexDir() sets up <2-leftmouse> maps (if g:netrw_retmap " is true) and a command, :Rexplore, which call this function. " -" s:nbcd_curpos_{bufnr('%')} is set up by s:NetrwBrowseChgDir() +" s:netrw_nbcd is set up by s:NetrwBrowseChgDir() " " s:rexposn_BUFNR used to save/restore cursor position fun! s:NetrwRexplore(islocal,dirname) if exists("s:netrwdrag") return endif -" call Dfunc("s:NetrwRexplore() w:netrw_rexlocal=".w:netrw_rexlocal." w:netrw_rexdir<".w:netrw_rexdir.">") +" call Dfunc("s:NetrwRexplore() w:netrw_rexlocal=".w:netrw_rexlocal." w:netrw_rexdir<".w:netrw_rexdir."> win#".winnr()) " call Decho("currently in bufname<".bufname("%").">",'~'.expand("<slnum>")) " call Decho("ft=".&ft." win#".winnr()." w:netrw_rexfile<".(exists("w:netrw_rexfile")? w:netrw_rexfile : 'n/a').">",'~'.expand("<slnum>")) @@ -11474,7 +11678,7 @@ fun! s:NetrwRexplore(islocal,dirname) " call Decho("set w:netrw_rexfile<".w:netrw_rexfile."> (win#".winnr().")",'~'.expand("<slnum>")) if !exists("w:netrw_rexlocal") -" call Dret("s:NetrwRexplore w:netrw_rexlocal doesn't exist (".&ft.")") +" call Dret("s:NetrwRexplore w:netrw_rexlocal doesn't exist (".&ft." win#".winnr().")") return endif " call Decho("settings buf#".bufnr("%")."<".bufname("%").">: ".((&l:ma == 0)? "no" : "")."ma ".((&l:mod == 0)? "no" : "")."mod ".((&l:bl == 0)? "no" : "")."bl ".((&l:ro == 0)? "no" : "")."ro fo=".&l:fo,'~'.expand("<slnum>")) @@ -11489,7 +11693,8 @@ fun! s:NetrwRexplore(islocal,dirname) if exists("s:rexposn_".bufnr("%")) " call Decho("restore posn, then unlet s:rexposn_".bufnr('%')."<".bufname("%").">",'~'.expand("<slnum>")) " restore position in directory listing - NetrwKeepj call netrw#RestorePosn(s:rexposn_{bufnr('%')}) +" call Decho("restoring posn to s:rexposn_".bufnr('%')."<".string(s:rexposn_{bufnr('%')}).">",'~'.expand("<slnum>")) + NetrwKeepj call winrestview(s:rexposn_{bufnr('%')}) if exists("s:rexposn_".bufnr('%')) unlet s:rexposn_{bufnr('%')} endif @@ -11522,6 +11727,29 @@ fun! s:SaveBufVars() endfun " --------------------------------------------------------------------- +" s:SavePosn: saves position associated with current buffer into a dictionary {{{2 +fun! s:SavePosn(posndict) +" call Dfunc("s:SavePosn(posndict) curbuf#".bufnr("%")."<".bufname("%").">") + + let a:posndict[bufnr("%")]= winsaveview() +" call Decho("saving posn: posndict[".bufnr("%")."]=".string(winsaveview()),'~'.expand("<slnum>")) + +" call Dret("s:SavePosn posndict") + return a:posndict +endfun + +" --------------------------------------------------------------------- +" s:RestorePosn: restores position associated with current buffer using dictionary {{{2 +fun! s:RestorePosn(posndict) +" call Dfunc("s:RestorePosn(posndict) curbuf#".bufnr("%")."<".bufname("%").">") + if has_key(a:posndict,bufnr("%")) + call winrestview(a:posndict[bufnr("%")]) +" call Decho("restoring posn: posndict[".bufnr("%")."]=".string(a:posndict[bufnr("%")]),'~'.expand("<slnum>")) + endif +" call Dret("s:RestorePosn") +endfun + +" --------------------------------------------------------------------- " s:SaveWinVars: (used by Explore() and NetrwSplit()) {{{2 fun! s:SaveWinVars() " call Dfunc("s:SaveWinVars() win#".winnr()) @@ -11571,11 +11799,14 @@ endfun " --------------------------------------------------------------------- " s:SetRexDir: set directory for :Rexplore {{{2 fun! s:SetRexDir(islocal,dirname) -" call Dfunc("s:SetRexDir(islocal=".a:islocal." dirname<".a:dirname.">)") +" call Dfunc("s:SetRexDir(islocal=".a:islocal." dirname<".a:dirname.">) win#".winnr()) let w:netrw_rexdir = a:dirname let w:netrw_rexlocal = a:islocal - let s:rexposn_{bufnr("%")} = netrw#SavePosn() -" call Decho("setting s:rexposn_".bufnr("%")."<".bufname("%")."> to SavePosn",'~'.expand("<slnum>")) + let s:rexposn_{bufnr("%")} = winsaveview() +" call Decho("setting w:netrw_rexdir =".w:netrw_rexdir,'~'.expand("<slnum>")) +" call Decho("setting w:netrw_rexlocal=".w:netrw_rexlocal,'~'.expand("<slnum>")) +" call Decho("saving posn to s:rexposn_".bufnr("%")."<".string(s:rexposn_{bufnr("%")}).">",'~'.expand("<slnum>")) +" call Decho("setting s:rexposn_".bufnr("%")."<".bufname("%")."> to ".string(winsaveview()),'~'.expand("<slnum>")) " call Dret("s:SetRexDir : win#".winnr()." ".(a:islocal? "local" : "remote")." dir: ".a:dirname) endfun @@ -11685,56 +11916,39 @@ fun! s:ShellEscape(s, ...) endfun " --------------------------------------------------------------------- -" s:TreeListMove: {{{2 +" s:TreeListMove: supports [[, ]], [], and ][ in tree mode {{{2 fun! s:TreeListMove(dir) " call Dfunc("s:TreeListMove(dir<".a:dir.">)") - let curline = getline('.') - let prvline = (line(".") > 1)? getline(line(".")-1) : '' - let nxtline = (line(".") < line("$"))? getline(line(".")+1) : '' - let curindent= substitute(curline,'^\([| ]*\).\{-}$','\1','') - let indentm1 = substitute(curindent,'^'.s:treedepthstring.' ','','') -" call Decho("prvline <".prvline."> #".line(".")-1,'~'.expand("<slnum>")) -" call Decho("curline <".curline."> #".line("."),'~'.expand("<slnum>")) -" call Decho("nxtline <".nxtline."> #".line(".")+1,'~'.expand("<slnum>")) -" call Decho("curindent<".curindent.">",'~'.expand("<slnum>")) -" call Decho("indentm1 <".indentm1.">",'~'.expand("<slnum>")) - + let curline = getline('.') + let prvline = (line(".") > 1)? getline(line(".")-1) : '' + let nxtline = (line(".") < line("$"))? getline(line(".")+1) : '' + let curindent = substitute(getline('.'),'^\(\%('.s:treedepthstring.'\)*\)[^'.s:treedepthstring.'].\{-}$','\1','e') + let indentm1 = substitute(curindent,'^'.s:treedepthstring,'','') + let treedepthchr = substitute(s:treedepthstring,' ','','g') + let stopline = exists("w:netrw_bannercnt")? w:netrw_bannercnt : 1 +" call Decho("prvline <".prvline."> #".(line(".")-1), '~'.expand("<slnum>")) +" call Decho("curline <".curline."> #".line(".") , '~'.expand("<slnum>")) +" call Decho("nxtline <".nxtline."> #".(line(".")+1), '~'.expand("<slnum>")) +" call Decho("curindent<".curindent.">" , '~'.expand("<slnum>")) +" call Decho("indentm1 <".indentm1.">" , '~'.expand("<slnum>")) + " COMBAK : need to handle when on a directory + " COMBAK : need to handle ]] and ][. In general, needs work!!! if curline !~ '/$' -" call Decho('regfile','~'.expand("<slnum>")) - if a:dir == '[' && prvline != '' + if a:dir == '[[' && prvline != '' NetrwKeepj norm! 0 - let nl = search('^'.indentm1.'[^'.s:treedepthstring.']','bWe') " search backwards from regular file + let nl = search('^'.indentm1.'\%('.s:treedepthstring.'\)\@!','bWe',stopline) " search backwards " call Decho("regfile srch back: ".nl,'~'.expand("<slnum>")) - elseif a:dir == ']' && nxtline != '' - NetrwKeepj norm! $ - let nl = search('^'.indentm1.'[^'.s:treedepthstring.']','We') " search forwards from regular file -" call Decho("regfile srch fwd: ".nl,'~'.expand("<slnum>")) - endif - - elseif a:dir == '[' && prvline != '' - NetrwKeepj norm! 0 - let curline= line(".") - let nl = search('^'.curindent.'[^'.s:treedepthstring.']','bWe') " search backwards From directory, same indentation -" call Decho("dir srch back ind: ".nl,'~'.expand("<slnum>")) - if nl != 0 - if line(".") == curline-1 - let nl= search('^'.indentm1.'[^'.s:treedepthstring.']','bWe') " search backwards from directory, indentation - 1 -" call Decho("dir srch back ind-1: ".nl,'~'.expand("<slnum>")) - endif - endif - - elseif a:dir == ']' && nxtline != '' - NetrwKeepj norm! $ - let curline = line(".") - let nl = search('^'.curindent.'[^'.s:treedepthstring.']','We') " search forwards from directory, same indentation -" call Decho("dir srch fwd ind: ".nl,'~'.expand("<slnum>")) - if nl != 0 - if line(".") == curline+1 - let nl= search('^'.indentm1.'[^'.s:treedepthstring.']','We') " search forwards from directory, indentation - 1 -" call Decho("dir srch fwd ind-1: ".nl,'~'.expand("<slnum>")) + elseif a:dir == '[]' && nxtline != '' + NetrwKeepj norm! 0 +" call Decho('srchpat<'.'^\%('.curindent.'\)\@!'.'>','~'.expand("<slnum>")) + let nl = search('^\%('.curindent.'\)\@!','We') " search forwards + if nl != 0 + NetrwKeepj norm! k + else + NetrwKeepj norm! G endif +" call Decho("regfile srch fwd: ".nl,'~'.expand("<slnum>")) endif - endif " call Dret("s:TreeListMove") diff --git a/runtime/autoload/provider/clipboard.vim b/runtime/autoload/provider/clipboard.vim index c7cb14ded7..1bcc1dea74 100644 --- a/runtime/autoload/provider/clipboard.vim +++ b/runtime/autoload/provider/clipboard.vim @@ -22,54 +22,85 @@ function! s:try_cmd(cmd, ...) let argv = split(a:cmd, " ") let out = a:0 ? systemlist(argv, a:1, 1) : systemlist(argv, [''], 1) if v:shell_error - echohl WarningMsg - echo "clipboard: error: ".(len(out) ? out[0] : '') - echohl None + if !exists('s:did_error_try_cmd') + echohl WarningMsg + echomsg "clipboard: error: ".(len(out) ? out[0] : '') + echohl None + let s:did_error_try_cmd = 1 + endif return 0 endif return out endfunction +" Returns TRUE if `cmd` exits with success, else FALSE. +function! s:cmd_ok(cmd) + call system(a:cmd) + return v:shell_error == 0 +endfunction + let s:cache_enabled = 1 -if executable('pbcopy') - let s:copy['+'] = 'pbcopy' - let s:paste['+'] = 'pbpaste' - let s:copy['*'] = s:copy['+'] - let s:paste['*'] = s:paste['+'] - let s:cache_enabled = 0 -elseif exists('$DISPLAY') && executable('xsel') - let s:copy['+'] = 'xsel --nodetach -i -b' - let s:paste['+'] = 'xsel -o -b' - let s:copy['*'] = 'xsel --nodetach -i -p' - let s:paste['*'] = 'xsel -o -p' -elseif exists('$DISPLAY') && executable('xclip') - let s:copy['+'] = 'xclip -quiet -i -selection clipboard' - let s:paste['+'] = 'xclip -o -selection clipboard' - let s:copy['*'] = 'xclip -quiet -i -selection primary' - let s:paste['*'] = 'xclip -o -selection primary' -elseif executable('lemonade') - let s:copy['+'] = 'lemonade copy' - let s:paste['+'] = 'lemonade paste' - let s:copy['*'] = 'lemonade copy' - let s:paste['*'] = 'lemonade paste' -elseif executable('doitclient') - let s:copy['+'] = 'doitclient wclip' - let s:paste['+'] = 'doitclient wclip -r' - let s:copy['*'] = s:copy['+'] - let s:paste['*'] = s:paste['+'] -else - echom 'clipboard: No clipboard tool available. See :help nvim-clipboard' +let s:err = '' + +function! provider#clipboard#Error() abort + return s:err +endfunction + +function! provider#clipboard#Executable() abort + if has('mac') && executable('pbcopy') + let s:copy['+'] = 'pbcopy' + let s:paste['+'] = 'pbpaste' + let s:copy['*'] = s:copy['+'] + let s:paste['*'] = s:paste['+'] + let s:cache_enabled = 0 + return 'pbcopy' + elseif exists('$DISPLAY') && executable('xsel') && s:cmd_ok('xsel -o -b') + let s:copy['+'] = 'xsel --nodetach -i -b' + let s:paste['+'] = 'xsel -o -b' + let s:copy['*'] = 'xsel --nodetach -i -p' + let s:paste['*'] = 'xsel -o -p' + return 'xsel' + elseif exists('$DISPLAY') && executable('xclip') + let s:copy['+'] = 'xclip -quiet -i -selection clipboard' + let s:paste['+'] = 'xclip -o -selection clipboard' + let s:copy['*'] = 'xclip -quiet -i -selection primary' + let s:paste['*'] = 'xclip -o -selection primary' + return 'xclip' + elseif executable('lemonade') + let s:copy['+'] = 'lemonade copy' + let s:paste['+'] = 'lemonade paste' + let s:copy['*'] = 'lemonade copy' + let s:paste['*'] = 'lemonade paste' + return 'lemonade' + elseif executable('doitclient') + let s:copy['+'] = 'doitclient wclip' + let s:paste['+'] = 'doitclient wclip -r' + let s:copy['*'] = s:copy['+'] + let s:paste['*'] = s:paste['+'] + return 'doitclient' + elseif executable('win32yank') + let s:copy['+'] = 'win32yank -i --crlf' + let s:paste['+'] = 'win32yank -o --lf' + let s:copy['*'] = s:copy['+'] + let s:paste['*'] = s:paste['+'] + return 'win32yank' + endif + + let s:err = 'clipboard: No clipboard tool available. See :help clipboard' + return '' +endfunction + +if empty(provider#clipboard#Executable()) finish endif let s:clipboard = {} function! s:clipboard.get(reg) - let reg = a:reg == '"' ? '+' : a:reg - if s:selections[reg].owner > 0 - return s:selections[reg].data + if s:selections[a:reg].owner > 0 + return s:selections[a:reg].data end - return s:try_cmd(s:paste[reg]) + return s:try_cmd(s:paste[a:reg]) endfunction function! s:clipboard.set(lines, regtype, reg) @@ -94,6 +125,7 @@ function! s:clipboard.set(lines, regtype, reg) let selection.data = [a:lines, a:regtype] let argv = split(s:copy[a:reg], " ") let selection.detach = s:cache_enabled + let selection.cwd = "/" let jobid = jobstart(argv, selection) if jobid <= 0 echohl WarningMsg diff --git a/runtime/autoload/provider/python.vim b/runtime/autoload/provider/python.vim index cb9d5c5296..b99a046375 100644 --- a/runtime/autoload/provider/python.vim +++ b/runtime/autoload/provider/python.vim @@ -1,5 +1,5 @@ " The Python provider uses a Python host to emulate an environment for running -" python-vim plugins. See ":help nvim-provider" for more information. +" python-vim plugins. See ":help provider". " " Associating the plugin with the Python host is the first step because plugins " will be passed as command-line arguments diff --git a/runtime/autoload/provider/python3.vim b/runtime/autoload/provider/python3.vim index f4a751e7a2..4f47a03a9b 100644 --- a/runtime/autoload/provider/python3.vim +++ b/runtime/autoload/provider/python3.vim @@ -1,5 +1,5 @@ " The Python3 provider uses a Python3 host to emulate an environment for running -" python3 plugins. See ":help nvim-provider" for more information. +" python3 plugins. See ":help provider". " " Associating the plugin with the Python3 host is the first step because " plugins will be passed as command-line arguments diff --git a/runtime/autoload/provider/pythonx.vim b/runtime/autoload/provider/pythonx.vim index 05815a4896..08a0f39b01 100644 --- a/runtime/autoload/provider/pythonx.vim +++ b/runtime/autoload/provider/pythonx.vim @@ -5,11 +5,24 @@ endif let s:loaded_pythonx_provider = 1 +let s:stderr = {} +let s:job_opts = {'rpc': v:true} + +" TODO(bfredl): this logic is common and should be builtin +function! s:job_opts.on_stderr(chan_id, data, event) + let stderr = get(s:stderr, a:chan_id, ['']) + let last = remove(stderr, -1) + let a:data[0] = last.a:data[0] + call extend(stderr, a:data) + let s:stderr[a:chan_id] = stderr +endfunction + function! provider#pythonx#Require(host) abort let ver = (a:host.orig_name ==# 'python') ? 2 : 3 " Python host arguments - let args = ['-c', 'import sys; sys.path.remove(""); import neovim; neovim.start_host()'] + let prog = (ver == '2' ? provider#python#Prog() : provider#python3#Prog()) + let args = [prog, '-c', 'import sys; sys.path.remove(""); import neovim; neovim.start_host()'] " Collect registered Python plugins into args let python_plugins = remote#host#PluginsForHost(a:host.name) @@ -18,46 +31,44 @@ function! provider#pythonx#Require(host) abort endfor try - let channel_id = rpcstart((ver == '2' ? - \ provider#python#Prog() : provider#python3#Prog()), args) - if rpcrequest(channel_id, 'poll') == 'ok' + let channel_id = jobstart(args, s:job_opts) + if rpcrequest(channel_id, 'poll') ==# 'ok' return channel_id endif catch echomsg v:throwpoint echomsg v:exception + for row in get(s:stderr, channel_id, []) + echomsg row + endfor endtry throw remote#host#LoadErrorForHost(a:host.orig_name, \ '$NVIM_PYTHON_LOG_FILE') endfunction function! provider#pythonx#Detect(major_ver) abort - let host_var = (a:major_ver == 2) ? - \ 'g:python_host_prog' : 'g:python3_host_prog' - let skip_var = (a:major_ver == 2) ? - \ 'g:python_host_skip_check' : 'g:python3_host_skip_check' - let skip = exists(skip_var) ? {skip_var} : 0 - if exists(host_var) - " Disable auto detection. - let [result, err] = s:check_interpreter({host_var}, a:major_ver, skip) - if result - return [{host_var}, err] + if a:major_ver == 2 + if exists('g:python_host_prog') + return [g:python_host_prog, ''] + else + let progs = ['python2', 'python2.7', 'python2.6', 'python'] + endif + else + if exists('g:python3_host_prog') + return [g:python3_host_prog, ''] + else + let progs = ['python3', 'python3.7', 'python3.6', 'python3.5', + \ 'python3.4', 'python3.3', 'python'] endif - return ['', 'provider/pythonx: Could not load Python ' . a:major_ver - \ . ' from ' . host_var . ': ' . err] endif - let prog_suffixes = (a:major_ver == 2) ? - \ ['2', '2.7', '2.6', ''] - \ : ['3', '3.5', '3.4', '3.3', ''] - let errors = [] - for prog in map(prog_suffixes, "'python' . v:val") - let [result, err] = s:check_interpreter(prog, a:major_ver, skip) + + for prog in progs + let [result, err] = s:check_interpreter(prog, a:major_ver) if result return [prog, err] endif - " Accumulate errors in case we don't find " any suitable Python interpreter. call add(errors, err) @@ -68,23 +79,19 @@ function! provider#pythonx#Detect(major_ver) abort \ . ":\n" . join(errors, "\n")] endfunction -function! s:check_interpreter(prog, major_ver, skip) abort +function! s:check_interpreter(prog, major_ver) abort let prog_path = exepath(a:prog) - if prog_path == '' + if prog_path ==# '' return [0, a:prog . ' not found in search path or not executable.'] endif - if a:skip - return [1, ''] - endif - let min_version = (a:major_ver == 2) ? '2.6' : '3.3' " Try to load neovim module, and output Python version. " Return codes: " 0 Neovim module can be loaded. - " 1 Something else went wrong. " 2 Neovim module cannot be loaded. + " Otherwise something else went wrong (e.g. 1 or 127). let prog_ver = system([ a:prog , '-c' , \ 'import sys; ' . \ 'sys.path.remove(""); ' . @@ -93,7 +100,8 @@ function! s:check_interpreter(prog, major_ver, skip) abort \ 'exit(2*int(pkgutil.get_loader("neovim") is None))' \ ]) - if prog_ver + if v:shell_error == 2 || v:shell_error == 0 + " Check version only for expected return codes. if prog_ver !~ '^' . a:major_ver return [0, prog_path . ' is Python ' . prog_ver . ' and cannot provide Python ' \ . a:major_ver . '.'] @@ -103,12 +111,16 @@ function! s:check_interpreter(prog, major_ver, skip) abort endif endif - if v:shell_error == 1 + if v:shell_error == 2 + return [0, prog_path . ' does not have the neovim module installed. ' + \ . 'See ":help provider-python".'] + elseif v:shell_error == 127 + " This can happen with pyenv's shims. + return [0, prog_path . ' does not exist: ' . prog_ver] + elseif v:shell_error return [0, 'Checking ' . prog_path . ' caused an unknown error. ' - \ . 'Please report this at github.com/neovim/neovim.'] - elseif v:shell_error == 2 - return [0, prog_path . ' does have not have the neovim module installed. ' - \ . 'See ":help nvim-python".'] + \ . '(' . v:shell_error . ', output: ' . prog_ver . ')' + \ . ' Please report this at github.com/neovim/neovim.'] endif return [1, ''] diff --git a/runtime/autoload/provider/ruby.vim b/runtime/autoload/provider/ruby.vim index aad8c09d28..c8ede20a75 100644 --- a/runtime/autoload/provider/ruby.vim +++ b/runtime/autoload/provider/ruby.vim @@ -1,13 +1,30 @@ " The Ruby provider helper -if exists('s:loaded_ruby_provider') +if exists('g:loaded_ruby_provider') finish endif +let g:loaded_ruby_provider = 1 -let s:loaded_ruby_provider = 1 +let s:stderr = {} +let s:job_opts = {'rpc': v:true} + +function! s:job_opts.on_stderr(chan_id, data, event) + let stderr = get(s:stderr, a:chan_id, ['']) + let last = remove(stderr, -1) + let a:data[0] = last.a:data[0] + call extend(stderr, a:data) + let s:stderr[a:chan_id] = stderr +endfunction + +function! provider#ruby#Detect() abort + return exepath('neovim-ruby-host') +endfunction + +function! provider#ruby#Prog() + return s:prog +endfunction function! provider#ruby#Require(host) abort - " Collect registered Ruby plugins into args - let args = [] + let args = [provider#ruby#Prog()] let ruby_plugins = remote#host#PluginsForHost(a:host.name) for plugin in ruby_plugins @@ -15,20 +32,47 @@ function! provider#ruby#Require(host) abort endfor try - let channel_id = rpcstart(provider#ruby#Prog(), args) - - if rpcrequest(channel_id, 'poll') == 'ok' + let channel_id = jobstart(args, s:job_opts) + if rpcrequest(channel_id, 'poll') ==# 'ok' return channel_id endif catch echomsg v:throwpoint echomsg v:exception + for row in get(s:stderr, channel_id, []) + echomsg row + endfor endtry - - throw remote#host#LoadErrorForHost(a:host.orig_name, - \ '$NVIM_RUBY_LOG_FILE') + throw remote#host#LoadErrorForHost(a:host.orig_name, '$NVIM_RUBY_LOG_FILE') endfunction -function! provider#ruby#Prog() abort - return 'neovim-ruby-host' +function! provider#ruby#Call(method, args) + if s:err != '' + echoerr s:err + return + endif + + if !exists('s:host') + try + let s:host = remote#host#Require('legacy-ruby-provider') + catch + let s:err = v:exception + echohl WarningMsg + echomsg v:exception + echohl None + return + endtry + endif + return call('rpcrequest', insert(insert(a:args, 'ruby_'.a:method), s:host)) endfunction + +let s:err = '' +let s:prog = provider#ruby#Detect() +let s:plugin_path = expand('<sfile>:p:h') . '/script_host.rb' + +if empty(s:prog) + let s:err = 'Cannot find the neovim RubyGem. Try :CheckHealth' +endif + +call remote#host#RegisterClone('legacy-ruby-provider', 'ruby') +call remote#host#RegisterPlugin('legacy-ruby-provider', s:plugin_path, []) diff --git a/runtime/autoload/provider/script_host.rb b/runtime/autoload/provider/script_host.rb new file mode 100644 index 0000000000..1dade766c7 --- /dev/null +++ b/runtime/autoload/provider/script_host.rb @@ -0,0 +1,8 @@ +begin + require "neovim/ruby_provider" +rescue LoadError + warn( + "Your neovim RubyGem is missing or out of date. " + + "Install the latest version using `gem install neovim`." + ) +end diff --git a/runtime/autoload/remote/host.vim b/runtime/autoload/remote/host.vim index a63c6a923b..51f7e5886f 100644 --- a/runtime/autoload/remote/host.vim +++ b/runtime/autoload/remote/host.vim @@ -1,7 +1,5 @@ let s:hosts = {} let s:plugin_patterns = {} -let s:remote_plugins_manifest = fnamemodify(expand($MYVIMRC, 1), ':h') - \.'/.'.fnamemodify($MYVIMRC, ':t').'-rplugin~' let s:plugins_for_host = {} @@ -120,9 +118,59 @@ function! remote#host#RegisterPlugin(host, path, specs) abort endfunction +" Get the path to the rplugin manifest file. +function! s:GetManifestPath() abort + let manifest_base = '' + + if exists('$NVIM_RPLUGIN_MANIFEST') + return fnamemodify($NVIM_RPLUGIN_MANIFEST, ':p') + endif + + let dest = has('win32') ? '$LOCALAPPDATA' : '$XDG_DATA_HOME' + if !exists(dest) + let dest = has('win32') ? '~/AppData/Local' : '~/.local/share' + endif + + let dest = fnamemodify(expand(dest), ':p') + if !empty(dest) && !filereadable(dest) + let dest .= ('/' ==# dest[-1:] ? '' : '/') . 'nvim' + call mkdir(dest, 'p', 0700) + let manifest_base = dest + endif + + return manifest_base.'/rplugin.vim' +endfunction + + +" Old manifest file based on known script locations. +function! s:GetOldManifestPath() abort + let prefix = exists('$MYVIMRC') + \ ? $MYVIMRC + \ : matchstr(get(split(execute('scriptnames'), '\n'), 0, ''), '\f\+$') + return fnamemodify(expand(prefix, 1), ':h') + \.'/.'.fnamemodify(prefix, ':t').'-rplugin~' +endfunction + + +function! s:GetManifest() abort + let manifest = s:GetManifestPath() + + if !filereadable(manifest) + " Check if an old manifest file exists and move it to the new location. + let old_manifest = s:GetOldManifestPath() + if filereadable(old_manifest) + call rename(old_manifest, manifest) + endif + endif + + return manifest +endfunction + + function! remote#host#LoadRemotePlugins() abort - if filereadable(s:remote_plugins_manifest) - exe 'source '.s:remote_plugins_manifest + let manifest = s:GetManifest() + if filereadable(manifest) + execute 'source' fnameescape(manifest) endif endfunction @@ -130,7 +178,9 @@ endfunction function! remote#host#LoadRemotePluginsEvent(event, pattern) abort autocmd! nvim-rplugin call remote#host#LoadRemotePlugins() - execute 'silent doautocmd <nomodeline>' a:event a:pattern + if exists('#'.a:event.'#'.a:pattern) " Avoid 'No matching autocommands'. + execute 'silent doautocmd <nomodeline>' a:event a:pattern + endif endfunction @@ -140,7 +190,8 @@ function! s:RegistrationCommands(host) abort call remote#host#RegisterClone(host_id, a:host) let pattern = s:plugin_patterns[a:host] let paths = globpath(&rtp, 'rplugin/'.a:host.'/'.pattern, 0, 1) - let paths = map(paths, 'tr(v:val,"\\","/")') " Normalize slashes #4795 + let paths = map(paths, 'tr(resolve(v:val),"\\","/")') " Normalize slashes #4795 + let paths = uniq(sort(paths)) if empty(paths) return [] endif @@ -194,9 +245,9 @@ function! remote#host#UpdateRemotePlugins() abort endtry endif endfor - call writefile(commands, s:remote_plugins_manifest) - echomsg printf('remote/host: generated the manifest file in "%s"', - \ s:remote_plugins_manifest) + call writefile(commands, s:GetManifest()) + echomsg printf('remote/host: generated rplugin manifest: %s', + \ s:GetManifest()) endfunction @@ -210,12 +261,9 @@ endfunction function! remote#host#LoadErrorForHost(host, log) abort return 'Failed to load '. a:host . ' host. '. - \ 'You can try to see what happened '. - \ 'by starting Neovim with the environment variable '. - \ a:log . ' set to a file and opening the generated '. - \ 'log file. Also, the host stderr will be available '. - \ 'in Neovim log, so it may contain useful information. '. - \ 'See also ~/.nvimlog.' + \ 'You can try to see what happened by starting nvim with '. + \ a:log . ' set and opening the generated log file.'. + \ ' Also, the host stderr is available in messages.' endfunction diff --git a/runtime/autoload/shada.vim b/runtime/autoload/shada.vim index 9be85b6f2e..cf27ee608a 100644 --- a/runtime/autoload/shada.vim +++ b/runtime/autoload/shada.vim @@ -241,8 +241,6 @@ function s:shada_check_type(type, val) abort if msg isnot# 0 return msg endif - if a:val > 0 || a:val < 1 - endif return 0 elseif a:type is# 'binarray' if type isnot# 'array' @@ -359,9 +357,14 @@ function s:shada_string(type, v) abort if (has_key(s:SHADA_ENUMS, a:type) && type(a:v) == type(0) \&& has_key(s:SHADA_REV_ENUMS[a:type], a:v)) return s:SHADA_REV_ENUMS[a:type][a:v] - elseif (a:type is# 'intchar' && type(a:v) == type(0) - \&& strtrans(nr2char(a:v)) is# nr2char(a:v)) - return "'" . nr2char(a:v) . "'" + " Restricting a:v to be <= 127 is not necessary, but intchar constants are + " normally expected to be either ASCII printable characters or NUL. + elseif a:type is# 'intchar' && type(a:v) == type(0) && a:v >= 0 && a:v <= 127 + if a:v > 0 && strtrans(nr2char(a:v)) is# nr2char(a:v) + return "'" . nr2char(a:v) . "'" + else + return "'\\" . a:v . "'" + endif else return msgpack#string(a:v) endif diff --git a/runtime/autoload/sqlcomplete.vim b/runtime/autoload/sqlcomplete.vim index 4a8863e15f..e80729add4 100644 --- a/runtime/autoload/sqlcomplete.vim +++ b/runtime/autoload/sqlcomplete.vim @@ -1,8 +1,8 @@ " Vim OMNI completion script for SQL " Language: SQL " Maintainer: David Fishburn <dfishburn dot vim at gmail dot com> -" Version: 15.0 -" Last Change: 2013 May 13 +" Version: 16.0 +" Last Change: 2015 Dec 29 " Homepage: http://www.vim.org/scripts/script.php?script_id=1572 " Usage: For detailed help " ":help sql.txt" @@ -16,6 +16,12 @@ " look backwards to a FROM clause and find the first table " and complete it. " +" Version 16.0 (Dec 2015) +" - NF: If reseting the cache and table, procedure or view completion +" had been used via dbext, have dbext delete or recreate the +" dictionary so that new objects are picked up for the +" next completion. +" " Version 15.0 (May 2013) " - NF: Changed the SQL precached syntax items, omni_sql_precache_syntax_groups, " to use regular expressions to pick up extended syntax group names. @@ -103,7 +109,7 @@ endif if exists('g:loaded_sql_completion') finish endif -let g:loaded_sql_completion = 150 +let g:loaded_sql_completion = 160 let s:keepcpo= &cpo set cpo&vim @@ -459,6 +465,29 @@ function! sqlcomplete#Complete(findstart, base) let s:tbl_cols = [] let s:syn_list = [] let s:syn_value = [] + + if s:sql_file_table != "" + if g:loaded_dbext >= 2300 + call DB_DictionaryDelete("table") + else + DBCompleteTables! + endif + endif + if s:sql_file_procedure != "" + if g:loaded_dbext >= 2300 + call DB_DictionaryDelete("procedure") + else + DBCompleteProcedures! + endif + endif + if s:sql_file_view != "" + if g:loaded_dbext >= 2300 + call DB_DictionaryDelete("view") + else + DBCompleteViews! + endif + endif + let s:sql_file_table = "" let s:sql_file_procedure = "" let s:sql_file_view = "" diff --git a/runtime/autoload/vimball.vim b/runtime/autoload/vimball.vim deleted file mode 100644 index 9a5a73c3c1..0000000000 --- a/runtime/autoload/vimball.vim +++ /dev/null @@ -1,775 +0,0 @@ -" vimball.vim : construct a file containing both paths and files -" Author: Charles E. Campbell, Jr. -" Date: Jan 17, 2012 -" Version: 35 -" GetLatestVimScripts: 1502 1 :AutoInstall: vimball.vim -" Copyright: (c) 2004-2011 by Charles E. Campbell, Jr. -" The VIM LICENSE applies to Vimball.vim, and Vimball.txt -" (see |copyright|) except use "Vimball" instead of "Vim". -" No warranty, express or implied. -" *** *** Use At-Your-Own-Risk! *** *** - -" --------------------------------------------------------------------- -" Load Once: {{{1 -if &cp || exists("g:loaded_vimball") - finish -endif -let g:loaded_vimball = "v35" -if v:version < 702 - echohl WarningMsg - echo "***warning*** this version of vimball needs vim 7.2" - echohl Normal - finish -endif -let s:keepcpo= &cpo -set cpo&vim -"DechoTabOn - -" ===================================================================== -" Constants: {{{1 -if !exists("s:USAGE") - let s:USAGE = 0 - let s:WARNING = 1 - let s:ERROR = 2 - - " determine if cygwin is in use or not - if !exists("g:netrw_cygwin") - if has("win32") || has("win95") || has("win64") || has("win16") - if &shell =~ '\%(\<bash\>\|\<zsh\>\)\%(\.exe\)\=$' - let g:netrw_cygwin= 1 - else - let g:netrw_cygwin= 0 - endif - else - let g:netrw_cygwin= 0 - endif - endif - - " set up g:vimball_mkdir if the mkdir() call isn't defined - if !exists("*mkdir") - if exists("g:netrw_local_mkdir") - let g:vimball_mkdir= g:netrw_local_mkdir - elseif executable("mkdir") - let g:vimball_mkdir= "mkdir" - elseif executable("makedir") - let g:vimball_mkdir= "makedir" - endif - if !exists(g:vimball_mkdir) - call vimball#ShowMesg(s:WARNING,"(vimball) g:vimball_mkdir undefined") - endif - endif -endif - -" ===================================================================== -" Functions: {{{1 - -" --------------------------------------------------------------------- -" vimball#MkVimball: creates a vimball given a list of paths to files {{{2 -" Input: -" line1,line2: a range of lines containing paths to files to be included in the vimball -" writelevel : if true, force a write to filename.vmb, even if it exists -" (usually accomplished with :MkVimball! ... -" filename : base name of file to be created (ie. filename.vmb) -" Output: a filename.vmb using vimball format: -" path -" filesize -" [file] -" path -" filesize -" [file] -fun! vimball#MkVimball(line1,line2,writelevel,...) range -" call Dfunc("MkVimball(line1=".a:line1." line2=".a:line2." writelevel=".a:writelevel." vimballname<".a:1.">) a:0=".a:0) - if a:1 =~ '\.vim$' || a:1 =~ '\.txt$' - let vbname= substitute(a:1,'\.\a\{3}$','.vmb','') - else - let vbname= a:1 - endif - if vbname !~ '\.vmb$' - let vbname= vbname.'.vmb' - endif -" call Decho("vbname<".vbname.">") - if !a:writelevel && a:1 =~ '[\/]' - call vimball#ShowMesg(s:ERROR,"(MkVimball) vimball name<".a:1."> should not include slashes; use ! to insist") -" call Dret("MkVimball : vimball name<".a:1."> should not include slashes") - return - endif - if !a:writelevel && filereadable(vbname) - call vimball#ShowMesg(s:ERROR,"(MkVimball) file<".vbname."> exists; use ! to insist") -" call Dret("MkVimball : file<".vbname."> already exists; use ! to insist") - return - endif - - " user option bypass - call vimball#SaveSettings() - - if a:0 >= 2 - " allow user to specify where to get the files - let home= expand(a:2) - else - " use first existing directory from rtp - let home= vimball#VimballHome() - endif - - " save current directory - let curdir = getcwd() - call s:ChgDir(home) - - " record current tab, initialize while loop index - let curtabnr = tabpagenr() - let linenr = a:line1 -" call Decho("curtabnr=".curtabnr) - - while linenr <= a:line2 - let svfile = getline(linenr) -" call Decho("svfile<".svfile.">") - - if !filereadable(svfile) - call vimball#ShowMesg(s:ERROR,"unable to read file<".svfile.">") - call s:ChgDir(curdir) - call vimball#RestoreSettings() -" call Dret("MkVimball") - return - endif - - " create/switch to mkvimball tab - if !exists("vbtabnr") - tabnew - sil! file Vimball - let vbtabnr= tabpagenr() - else - exe "tabn ".vbtabnr - endif - - let lastline= line("$") + 1 - if lastline == 2 && getline("$") == "" - call setline(1,'" Vimball Archiver by Charles E. Campbell, Jr., Ph.D.') - call setline(2,'UseVimball') - call setline(3,'finish') - let lastline= line("$") + 1 - endif - call setline(lastline ,substitute(svfile,'$',' [[[1','')) - call setline(lastline+1,0) - - " write the file from the tab -" call Decho("exe $r ".fnameescape(svfile)) - exe "$r ".fnameescape(svfile) - - call setline(lastline+1,line("$") - lastline - 1) -" call Decho("lastline=".lastline." line$=".line("$")) - - " restore to normal tab - exe "tabn ".curtabnr - let linenr= linenr + 1 - endwhile - - " write the vimball - exe "tabn ".vbtabnr - call s:ChgDir(curdir) - setlocal ff=unix - if a:writelevel -" call Decho("exe w! ".fnameescape(vbname)) - exe "w! ".fnameescape(vbname) - else -" call Decho("exe w ".fnameescape(vbname)) - exe "w ".fnameescape(vbname) - endif -" call Decho("Vimball<".vbname."> created") - echo "Vimball<".vbname."> created" - - " remove the evidence - setlocal nomod bh=wipe - exe "tabn ".curtabnr - exe "tabc ".vbtabnr - - " restore options - call vimball#RestoreSettings() - -" call Dret("MkVimball") -endfun - -" --------------------------------------------------------------------- -" vimball#Vimball: extract and distribute contents from a vimball {{{2 -" (invoked the the UseVimball command embedded in -" vimballs' prologue) -fun! vimball#Vimball(really,...) -" call Dfunc("vimball#Vimball(really=".a:really.") a:0=".a:0) - - if v:version < 701 || (v:version == 701 && !exists('*fnameescape')) - echoerr "your vim is missing the fnameescape() function (pls upgrade to vim 7.2 or later)" -" call Dret("vimball#Vimball : needs 7.1 with patch 299 or later") - return - endif - - if getline(1) !~ '^" Vimball Archiver' - echoerr "(Vimball) The current file does not appear to be a Vimball!" -" call Dret("vimball#Vimball") - return - endif - - " set up standard settings - call vimball#SaveSettings() - let curtabnr = tabpagenr() - let vimballfile = expand("%:tr") - - " set up vimball tab -" call Decho("setting up vimball tab") - tabnew - sil! file Vimball - let vbtabnr= tabpagenr() - let didhelp= "" - - " go to vim plugin home - if a:0 > 0 - " let user specify the directory where the vimball is to be unpacked. - " If, however, the user did not specify a full path, set the home to be below the current directory - let home= expand(a:1) - if has("win32") || has("win95") || has("win64") || has("win16") - if home !~ '^\a:[/\\]' - let home= getcwd().'/'.a:1 - endif - elseif home !~ '^/' - let home= getcwd().'/'.a:1 - endif - else - let home= vimball#VimballHome() - endif -" call Decho("home<".home.">") - - " save current directory and remove older same-named vimball, if any - let curdir = getcwd() -" call Decho("home<".home.">") -" call Decho("curdir<".curdir.">") - - call s:ChgDir(home) - let s:ok_unablefind= 1 - call vimball#RmVimball(vimballfile) - unlet s:ok_unablefind - - let linenr = 4 - let filecnt = 0 - - " give title to listing of (extracted) files from Vimball Archive - if a:really - echohl Title | echomsg "Vimball Archive" | echohl None - else - echohl Title | echomsg "Vimball Archive Listing" | echohl None - echohl Statement | echomsg "files would be placed under: ".home | echohl None - endif - - " apportion vimball contents to various files -" call Decho("exe tabn ".curtabnr) - exe "tabn ".curtabnr -" call Decho("linenr=".linenr." line$=".line("$")) - while 1 < linenr && linenr < line("$") - let fname = substitute(getline(linenr),'\t\[\[\[1$','','') - let fname = substitute(fname,'\\','/','g') - let fsize = substitute(getline(linenr+1),'^\(\d\+\).\{-}$','\1','')+0 - let fenc = substitute(getline(linenr+1),'^\d\+\s*\(\S\{-}\)$','\1','') - let filecnt = filecnt + 1 -" call Decho("fname<".fname."> fsize=".fsize." filecnt=".filecnt. " fenc=".fenc) - - if a:really - echomsg "extracted <".fname.">: ".fsize." lines" - else - echomsg "would extract <".fname.">: ".fsize." lines" - endif -" call Decho("using L#".linenr.": will extract file<".fname.">") -" call Decho("using L#".(linenr+1).": fsize=".fsize) - - " Allow AsNeeded/ directory to take place of plugin/ directory - " when AsNeeded/filename is filereadable or was present in VimballRecord - if fname =~ '\<plugin/' - let anfname= substitute(fname,'\<plugin/','AsNeeded/','') - if filereadable(anfname) || (exists("s:VBRstring") && s:VBRstring =~ anfname) -" call Decho("using anfname<".anfname."> instead of <".fname.">") - let fname= anfname - endif - endif - - " make directories if they don't exist yet - if a:really -" call Decho("making directories if they don't exist yet (fname<".fname.">)") - let fnamebuf= substitute(fname,'\\','/','g') - let dirpath = substitute(home,'\\','/','g') -" call Decho("init: fnamebuf<".fnamebuf.">") -" call Decho("init: dirpath <".dirpath.">") - while fnamebuf =~ '/' - let dirname = dirpath."/".substitute(fnamebuf,'/.*$','','') - let dirpath = dirname - let fnamebuf = substitute(fnamebuf,'^.\{-}/\(.*\)$','\1','') -" call Decho("dirname<".dirname.">") -" call Decho("dirpath<".dirpath.">") - if !isdirectory(dirname) -" call Decho("making <".dirname.">") - if exists("g:vimball_mkdir") - call system(g:vimball_mkdir." ".shellescape(dirname)) - else - call mkdir(dirname) - endif - call s:RecordInVar(home,"rmdir('".dirname."')") - endif - endwhile - endif - call s:ChgDir(home) - - " grab specified qty of lines and place into "a" buffer - " (skip over path/filename and qty-lines) - let linenr = linenr + 2 - let lastline = linenr + fsize - 1 -" call Decho("exe ".linenr.",".lastline."yank a") - " no point in handling a zero-length file - if lastline >= linenr - exe "silent ".linenr.",".lastline."yank a" - - " copy "a" buffer into tab -" call Decho('copy "a buffer into tab#'.vbtabnr) - exe "tabn ".vbtabnr - setlocal ma - sil! %d - silent put a - 1 - sil! d - - " write tab to file - if a:really - let fnamepath= home."/".fname -" call Decho("exe w! ".fnameescape(fnamepath)) - if fenc != "" - exe "silent w! ++enc=".fnameescape(fenc)." ".fnameescape(fnamepath) - else - exe "silent w! ".fnameescape(fnamepath) - endif - echo "wrote ".fnameescape(fnamepath) - call s:RecordInVar(home,"call delete('".fnamepath."')") - endif - - " return to tab with vimball -" call Decho("exe tabn ".curtabnr) - exe "tabn ".curtabnr - - " set up help if its a doc/*.txt file -" call Decho("didhelp<".didhelp."> fname<".fname.">") - if a:really && didhelp == "" && fname =~ 'doc/[^/]\+\.\(txt\|..x\)$' - let didhelp= substitute(fname,'^\(.*\<doc\)[/\\][^.]*\.\(txt\|..x\)$','\1','') -" call Decho("didhelp<".didhelp.">") - endif - endif - - " update for next file -" call Decho("update linenr= [linenr=".linenr."] + [fsize=".fsize."] = ".(linenr+fsize)) - let linenr= linenr + fsize - endwhile - - " set up help -" call Decho("about to set up help: didhelp<".didhelp.">") - if didhelp != "" - let htpath= home."/".didhelp -" call Decho("exe helptags ".htpath) - exe "helptags ".fnameescape(htpath) - echo "did helptags" - endif - - " make sure a "Press ENTER..." prompt appears to keep the messages showing! - while filecnt <= &ch - echomsg " " - let filecnt= filecnt + 1 - endwhile - - " record actions in <.VimballRecord> - call s:RecordInFile(home) - - " restore events, delete tab and buffer - exe "tabn ".vbtabnr - setlocal nomod bh=wipe - exe "tabn ".curtabnr - exe "tabc ".vbtabnr - call vimball#RestoreSettings() - call s:ChgDir(curdir) - -" call Dret("vimball#Vimball") -endfun - -" --------------------------------------------------------------------- -" vimball#RmVimball: remove any files, remove any directories made by any {{{2 -" previous vimball extraction based on a file of the current -" name. -" Usage: RmVimball (assume current file is a vimball; remove) -" RmVimball vimballname -fun! vimball#RmVimball(...) -" call Dfunc("vimball#RmVimball() a:0=".a:0) - if exists("g:vimball_norecord") -" call Dret("vimball#RmVimball : (g:vimball_norecord)") - return - endif - - if a:0 == 0 - let curfile= expand("%:tr") -" call Decho("case a:0=0: curfile<".curfile."> (used expand(%:tr))") - else - if a:1 =~ '[\/]' - call vimball#ShowMesg(s:USAGE,"RmVimball vimballname [path]") -" call Dret("vimball#RmVimball : suspect a:1<".a:1.">") - return - endif - let curfile= a:1 -" call Decho("case a:0=".a:0.": curfile<".curfile.">") - endif - if curfile =~ '\.vmb$' - let curfile= substitute(curfile,'\.vmb','','') - elseif curfile =~ '\.vba$' - let curfile= substitute(curfile,'\.vba','','') - endif - if a:0 >= 2 - let home= expand(a:2) - else - let home= vimball#VimballHome() - endif - let curdir = getcwd() -" call Decho("home <".home.">") -" call Decho("curfile<".curfile.">") -" call Decho("curdir <".curdir.">") - - call s:ChgDir(home) - if filereadable(".VimballRecord") -" call Decho(".VimballRecord is readable") -" call Decho("curfile<".curfile.">") - keepalt keepjumps 1split - sil! keepalt keepjumps e .VimballRecord - let keepsrch= @/ -" call Decho('search for ^\M'.curfile.'.\m: ') -" call Decho('search for ^\M'.curfile.'.\m{vba|vmb}: ') -" call Decho('search for ^\M'.curfile.'\m[-0-9.]*\.{vba|vmb}: ') - if search('^\M'.curfile."\m: ".'cw') - let foundit= 1 - elseif search('^\M'.curfile.".\mvmb: ",'cw') - let foundit= 2 - elseif search('^\M'.curfile.'\m[-0-9.]*\.vmb: ','cw') - let foundit= 2 - elseif search('^\M'.curfile.".\mvba: ",'cw') - let foundit= 1 - elseif search('^\M'.curfile.'\m[-0-9.]*\.vba: ','cw') - let foundit= 1 - else - let foundit = 0 - endif - if foundit - if foundit == 1 - let exestring = substitute(getline("."),'^\M'.curfile.'\m\S\{-}\.vba: ','','') - else - let exestring = substitute(getline("."),'^\M'.curfile.'\m\S\{-}\.vmb: ','','') - endif - let s:VBRstring= substitute(exestring,'call delete(','','g') - let s:VBRstring= substitute(s:VBRstring,"[')]",'','g') -" call Decho("exe ".exestring) - sil! keepalt keepjumps exe exestring - sil! keepalt keepjumps d - let exestring= strlen(substitute(exestring,'call delete(.\{-})|\=',"D","g")) -" call Decho("exestring<".exestring.">") - echomsg "removed ".exestring." files" - else - let s:VBRstring= '' - let curfile = substitute(curfile,'\.vmb','','') -" call Decho("unable to find <".curfile."> in .VimballRecord") - if !exists("s:ok_unablefind") - call vimball#ShowMesg(s:WARNING,"(RmVimball) unable to find <".curfile."> in .VimballRecord") - endif - endif - sil! keepalt keepjumps g/^\s*$/d - sil! keepalt keepjumps wq! - let @/= keepsrch - endif - call s:ChgDir(curdir) - -" call Dret("vimball#RmVimball") -endfun - -" --------------------------------------------------------------------- -" vimball#Decompress: attempts to automatically decompress vimballs {{{2 -fun! vimball#Decompress(fname,...) -" call Dfunc("Decompress(fname<".a:fname.">) a:0=".a:0) - - " decompression: - if expand("%") =~ '.*\.gz' && executable("gunzip") - " handle *.gz with gunzip - silent exe "!gunzip ".shellescape(a:fname) - if v:shell_error != 0 - call vimball#ShowMesg(s:WARNING,"(vimball#Decompress) gunzip may have failed with <".a:fname.">") - endif - let fname= substitute(a:fname,'\.gz$','','') - exe "e ".escape(fname,' \') - if a:0 == 0| call vimball#ShowMesg(s:USAGE,"Source this file to extract it! (:so %)") | endif - - elseif expand("%") =~ '.*\.gz' && executable("gzip") - " handle *.gz with gzip -d - silent exe "!gzip -d ".shellescape(a:fname) - if v:shell_error != 0 - call vimball#ShowMesg(s:WARNING,'(vimball#Decompress) "gzip -d" may have failed with <'.a:fname.">") - endif - let fname= substitute(a:fname,'\.gz$','','') - exe "e ".escape(fname,' \') - if a:0 == 0| call vimball#ShowMesg(s:USAGE,"Source this file to extract it! (:so %)") | endif - - elseif expand("%") =~ '.*\.bz2' && executable("bunzip2") - " handle *.bz2 with bunzip2 - silent exe "!bunzip2 ".shellescape(a:fname) - if v:shell_error != 0 - call vimball#ShowMesg(s:WARNING,"(vimball#Decompress) bunzip2 may have failed with <".a:fname.">") - endif - let fname= substitute(a:fname,'\.bz2$','','') - exe "e ".escape(fname,' \') - if a:0 == 0| call vimball#ShowMesg(s:USAGE,"Source this file to extract it! (:so %)") | endif - - elseif expand("%") =~ '.*\.bz2' && executable("bzip2") - " handle *.bz2 with bzip2 -d - silent exe "!bzip2 -d ".shellescape(a:fname) - if v:shell_error != 0 - call vimball#ShowMesg(s:WARNING,'(vimball#Decompress) "bzip2 -d" may have failed with <'.a:fname.">") - endif - let fname= substitute(a:fname,'\.bz2$','','') - exe "e ".escape(fname,' \') - if a:0 == 0| call vimball#ShowMesg(s:USAGE,"Source this file to extract it! (:so %)") | endif - - elseif expand("%") =~ '.*\.zip' && executable("unzip") - " handle *.zip with unzip - silent exe "!unzip ".shellescape(a:fname) - if v:shell_error != 0 - call vimball#ShowMesg(s:WARNING,"(vimball#Decompress) unzip may have failed with <".a:fname.">") - endif - let fname= substitute(a:fname,'\.zip$','','') - exe "e ".escape(fname,' \') - if a:0 == 0| call vimball#ShowMesg(s:USAGE,"Source this file to extract it! (:so %)") | endif - endif - - if a:0 == 0| setlocal noma bt=nofile fmr=[[[,]]] fdm=marker | endif - -" call Dret("Decompress") -endfun - -" --------------------------------------------------------------------- -" vimball#ShowMesg: {{{2 -fun! vimball#ShowMesg(level,msg) -" call Dfunc("vimball#ShowMesg(level=".a:level." msg<".a:msg.">)") - - let rulerkeep = &ruler - let showcmdkeep = &showcmd - set noruler noshowcmd - redraw! - - if &fo =~ '[ta]' - echomsg "***vimball*** ".a:msg - else - if a:level == s:WARNING || a:level == s:USAGE - echohl WarningMsg - elseif a:level == s:ERROR - echohl Error - endif - echomsg "***vimball*** ".a:msg - echohl None - endif - - if a:level != s:USAGE - call inputsave()|let ok= input("Press <cr> to continue")|call inputrestore() - endif - - let &ruler = rulerkeep - let &showcmd = showcmdkeep - -" call Dret("vimball#ShowMesg") -endfun -" ===================================================================== -" s:ChgDir: change directory (in spite of Windoze) {{{2 -fun! s:ChgDir(newdir) -" call Dfunc("ChgDir(newdir<".a:newdir.">)") - if (has("win32") || has("win95") || has("win64") || has("win16")) - try - exe 'silent cd '.fnameescape(substitute(a:newdir,'/','\\','g')) - catch /^Vim\%((\a\+)\)\=:E/ - call mkdir(fnameescape(substitute(a:newdir,'/','\\','g'))) - exe 'silent cd '.fnameescape(substitute(a:newdir,'/','\\','g')) - endtry - else - try - exe 'silent cd '.fnameescape(a:newdir) - catch /^Vim\%((\a\+)\)\=:E/ - call mkdir(fnameescape(a:newdir)) - exe 'silent cd '.fnameescape(a:newdir) - endtry - endif -" call Dret("ChgDir : curdir<".getcwd().">") -endfun - -" --------------------------------------------------------------------- -" s:RecordInVar: record a un-vimball command in the .VimballRecord file {{{2 -fun! s:RecordInVar(home,cmd) -" call Dfunc("RecordInVar(home<".a:home."> cmd<".a:cmd.">)") - if a:cmd =~ '^rmdir' -" if !exists("s:recorddir") -" let s:recorddir= substitute(a:cmd,'^rmdir',"call s:Rmdir",'') -" else -" let s:recorddir= s:recorddir."|".substitute(a:cmd,'^rmdir',"call s:Rmdir",'') -" endif - elseif !exists("s:recordfile") - let s:recordfile= a:cmd - else - let s:recordfile= s:recordfile."|".a:cmd - endif -" call Dret("RecordInVar : s:recordfile<".(exists("s:recordfile")? s:recordfile : "")."> s:recorddir<".(exists("s:recorddir")? s:recorddir : "").">") -endfun - -" --------------------------------------------------------------------- -" s:RecordInFile: {{{2 -fun! s:RecordInFile(home) -" call Dfunc("s:RecordInFile()") - if exists("g:vimball_norecord") -" call Dret("s:RecordInFile : g:vimball_norecord") - return - endif - - if exists("s:recordfile") || exists("s:recorddir") - let curdir= getcwd() - call s:ChgDir(a:home) - keepalt keepjumps 1split - - let cmd= expand("%:tr").": " -" call Decho("cmd<".cmd.">") - - sil! keepalt keepjumps e .VimballRecord - setlocal ma - $ - if exists("s:recordfile") && exists("s:recorddir") - let cmd= cmd.s:recordfile."|".s:recorddir - elseif exists("s:recorddir") - let cmd= cmd.s:recorddir - elseif exists("s:recordfile") - let cmd= cmd.s:recordfile - else -" call Dret("s:RecordInFile : neither recordfile nor recorddir exist") - return - endif -" call Decho("cmd<".cmd.">") - - " put command into buffer, write .VimballRecord `file - keepalt keepjumps put=cmd - sil! keepalt keepjumps g/^\s*$/d - sil! keepalt keepjumps wq! - call s:ChgDir(curdir) - - if exists("s:recorddir") -" call Decho("unlet s:recorddir<".s:recorddir.">") - unlet s:recorddir - endif - if exists("s:recordfile") -" call Decho("unlet s:recordfile<".s:recordfile.">") - unlet s:recordfile - endif - else -" call Decho("s:record[file|dir] doesn't exist") - endif - -" call Dret("s:RecordInFile") -endfun - -" --------------------------------------------------------------------- -" vimball#VimballHome: determine/get home directory path (usually from rtp) {{{2 -fun! vimball#VimballHome() -" call Dfunc("vimball#VimballHome()") - if exists("g:vimball_home") - let home= g:vimball_home - else - " go to vim plugin home - for home in split(&rtp,',') + [''] - if isdirectory(home) && filewritable(home) | break | endif - let basehome= substitute(home,'[/\\]\.vim$','','') - if isdirectory(basehome) && filewritable(basehome) - let home= basehome."/.vim" - break - endif - endfor - if home == "" - " just pick the first directory - let home= substitute(&rtp,',.*$','','') - endif - if (has("win32") || has("win95") || has("win64") || has("win16")) - let home= substitute(home,'/','\\','g') - endif - endif - " insure that the home directory exists -" call Decho("picked home<".home.">") - if !isdirectory(home) - if exists("g:vimball_mkdir") -" call Decho("home<".home."> isn't a directory -- making it now with g:vimball_mkdir<".g:vimball_mkdir.">") -" call Decho("system(".g:vimball_mkdir." ".shellescape(home).")") - call system(g:vimball_mkdir." ".shellescape(home)) - else -" call Decho("home<".home."> isn't a directory -- making it now with mkdir()") - call mkdir(home) - endif - endif -" call Dret("vimball#VimballHome <".home.">") - return home -endfun - -" --------------------------------------------------------------------- -" vimball#SaveSettings: {{{2 -fun! vimball#SaveSettings() -" call Dfunc("SaveSettings()") - let s:makeep = getpos("'a") - let s:regakeep= @a - if exists("&acd") - let s:acdkeep = &acd - endif - let s:eikeep = &ei - let s:fenkeep = &l:fen - let s:hidkeep = &hidden - let s:ickeep = &ic - let s:lzkeep = &lz - let s:pmkeep = &pm - let s:repkeep = &report - let s:vekeep = &ve - let s:ffkeep = &l:ff - let s:swfkeep = &l:swf - if exists("&acd") - setlocal ei=all ve=all noacd nofen noic report=999 nohid bt= ma lz pm= ff=unix noswf - else - setlocal ei=all ve=all nofen noic report=999 nohid bt= ma lz pm= ff=unix noswf - endif - " vimballs should be in unix format - setlocal ff=unix -" call Dret("SaveSettings") -endfun - -" --------------------------------------------------------------------- -" vimball#RestoreSettings: {{{2 -fun! vimball#RestoreSettings() -" call Dfunc("RestoreSettings()") - let @a = s:regakeep - if exists("&acd") - let &acd = s:acdkeep - endif - let &l:fen = s:fenkeep - let &hidden = s:hidkeep - let &ic = s:ickeep - let &lz = s:lzkeep - let &pm = s:pmkeep - let &report = s:repkeep - let &ve = s:vekeep - let &ei = s:eikeep - let &l:ff = s:ffkeep - if s:makeep[0] != 0 - " restore mark a -" call Decho("restore mark-a: makeep=".string(makeep)) - call setpos("'a",s:makeep) - endif - if exists("&acd") - unlet s:acdkeep - endif - unlet s:regakeep s:eikeep s:fenkeep s:hidkeep s:ickeep s:repkeep s:vekeep s:makeep s:lzkeep s:pmkeep s:ffkeep -" call Dret("RestoreSettings") -endfun - -let &cpo = s:keepcpo -unlet s:keepcpo - -" --------------------------------------------------------------------- -" Modelines: {{{1 -" vim: fdm=marker diff --git a/runtime/autoload/vimexpect.vim b/runtime/autoload/vimexpect.vim index 16e7d30d6c..0ed888d2a4 100644 --- a/runtime/autoload/vimexpect.vim +++ b/runtime/autoload/vimexpect.vim @@ -140,7 +140,7 @@ endfunction " Job handler that simply forwards lines to the parser. -function! s:JobOutput(id, lines) +function! s:JobOutput(_id, lines, _event) dict call self._parser.feed(a:lines) endfunction |