aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--runtime/autoload/clojurecomplete.vim16
-rw-r--r--runtime/autoload/man.vim5
-rw-r--r--runtime/autoload/msgpack.vim8
-rw-r--r--runtime/autoload/provider/clipboard.vim17
-rw-r--r--runtime/autoload/provider/pythonx.vim3
-rw-r--r--runtime/autoload/shada.vim13
-rw-r--r--runtime/doc/api-funcs.txt716
-rw-r--r--runtime/doc/autocmd.txt9
-rw-r--r--runtime/doc/mbyte.txt3
-rw-r--r--runtime/doc/pi_msgpack.txt5
-rw-r--r--runtime/doc/repeat.txt6
-rw-r--r--runtime/doc/syntax.txt15
-rw-r--r--runtime/doc/usr_41.txt4
-rw-r--r--runtime/doc/vim_diff.txt26
-rw-r--r--runtime/filetype.vim6
-rw-r--r--runtime/ftplugin/clojure.vim20
-rw-r--r--runtime/indent/clojure.vim206
-rw-r--r--runtime/keymap/armenian-eastern_utf-8.vim108
-rw-r--r--runtime/keymap/armenian-western_utf-8.vim108
-rw-r--r--runtime/syntax/clojure.vim217
-rw-r--r--runtime/syntax/help.vim2
-rw-r--r--runtime/syntax/python.vim4
-rw-r--r--runtime/syntax/sqloracle.vim20
-rw-r--r--runtime/syntax/vim.vim4
-rw-r--r--scripts/gen_api_vimdoc.py514
-rw-r--r--src/nvim/eval.c64
-rw-r--r--src/nvim/eval.lua1
-rw-r--r--src/nvim/ex_cmds.c8
-rw-r--r--src/nvim/ex_docmd.c4
-rw-r--r--src/nvim/fileio.c123
-rw-r--r--src/nvim/os/time.c39
-rw-r--r--src/nvim/path.c47
-rw-r--r--src/nvim/testdir/Makefile2
-rw-r--r--src/nvim/testdir/test_autocmd.vim31
-rw-r--r--src/nvim/testdir/test_expr.vim11
-rw-r--r--src/nvim/testdir/test_usercommands.vim64
-rw-r--r--src/nvim/version.c15
-rw-r--r--test/functional/ex_cmds/ctrl_c_spec.lua62
-rw-r--r--test/functional/ex_cmds/global_spec.lua74
-rw-r--r--test/functional/helpers.lua73
-rw-r--r--test/functional/legacy/autochdir_spec.lua26
-rw-r--r--test/functional/plugin/msgpack_spec.lua2
-rw-r--r--test/functional/plugin/shada_spec.lua37
-rw-r--r--test/functional/ui/mouse_spec.lua14
-rw-r--r--test/helpers.lua40
-rw-r--r--test/unit/formatc.lua8
-rw-r--r--test/unit/helpers.lua15
-rw-r--r--test/unit/path_spec.lua11
-rw-r--r--test/unit/preprocess.lua155
49 files changed, 2440 insertions, 541 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/man.vim b/runtime/autoload/man.vim
index 6fed4a54e3..251e6eee41 100644
--- a/runtime/autoload/man.vim
+++ b/runtime/autoload/man.vim
@@ -113,10 +113,11 @@ function! s:system(cmd, ...) abort
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
- " Respect $MANWIDTH, or default to window width.
- return s:system(['env', 'MANPAGER=cat', (empty($MANWIDTH) ? 'MANWIDTH='.winwidth(0) : ''), 'man', a:path])
+ return s:system(['env', 'MANPAGER=cat', 'MANWIDTH='.manwidth, 'man', a:path])
endfunction
function! s:put_page(page) abort
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/provider/clipboard.vim b/runtime/autoload/provider/clipboard.vim
index f63ad5730b..b8baaa8c64 100644
--- a/runtime/autoload/provider/clipboard.vim
+++ b/runtime/autoload/provider/clipboard.vim
@@ -22,14 +22,23 @@ 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
let s:err = ''
@@ -45,7 +54,7 @@ function! provider#clipboard#Executable() abort
let s:paste['*'] = s:paste['+']
let s:cache_enabled = 0
return 'pbcopy'
- elseif exists('$DISPLAY') && executable('xsel')
+ 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'
diff --git a/runtime/autoload/provider/pythonx.vim b/runtime/autoload/provider/pythonx.vim
index f46c260fa3..08a0f39b01 100644
--- a/runtime/autoload/provider/pythonx.vim
+++ b/runtime/autoload/provider/pythonx.vim
@@ -57,7 +57,8 @@ function! provider#pythonx#Detect(major_ver) abort
if exists('g:python3_host_prog')
return [g:python3_host_prog, '']
else
- let progs = ['python3', 'python3.5', 'python3.4', 'python3.3', 'python']
+ let progs = ['python3', 'python3.7', 'python3.6', 'python3.5',
+ \ 'python3.4', 'python3.3', 'python']
endif
endif
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/doc/api-funcs.txt b/runtime/doc/api-funcs.txt
new file mode 100644
index 0000000000..706941fd12
--- /dev/null
+++ b/runtime/doc/api-funcs.txt
@@ -0,0 +1,716 @@
+*api-funcs.txt* Neovim API Function Reference {Nvim}
+
+Note: This documentation is generated from Neovim's API source code.
+
+Contents:
+
+1. Global Functions |api-global|
+2. Buffer Functions |api-buffer|
+3. Window Functions |api-window|
+4. Tabpage Functions |api-tabpage|
+5. UI Functions |api-ui|
+
+==============================================================================
+1. Global Functions *api-global*
+
+nvim_command({command}) *nvim_command()*
+ Executes an ex-command. On VimL error: Returns the VimL error;
+ v:errmsg is not updated.
+
+ Parameters:~
+ {command} Ex-command string
+
+nvim_feedkeys({keys}, {mode}, {escape_csi}) *nvim_feedkeys()*
+ Passes input keys to Nvim. On VimL error: Does not fail, but
+ updates v:errmsg.
+
+ Parameters:~
+ {keys} to be typed
+ {mode} mapping options
+ {escape_csi} If true, escape K_SPECIAL/CSI bytes in
+ `keys`
+
+nvim_input({keys}) *nvim_input()*
+ Passes keys to Nvim as raw user-input. On VimL error: Does not
+ fail, but updates v:errmsg.
+
+ Unlike `nvim_feedkeys`, this uses a lower-level input buffer
+ and the call is not deferred. This is the most reliable way to
+ emulate real user input.
+
+ Parameters:~
+ {keys} to be typed
+
+ Return:~
+ Number of bytes actually written (can be fewer than
+ requested if the buffer becomes full).
+
+ *nvim_replace_termcodes()*
+nvim_replace_termcodes({str}, {from_part}, {do_lt}, {special})
+ Replaces any terminal codes with the internal representation
+
+nvim_command_output({str}) *nvim_command_output()*
+ TODO: Documentation
+
+nvim_eval({expr}) *nvim_eval()*
+ Evaluates a VimL expression (:help expression). Dictionaries
+ and Lists are recursively expanded. On VimL error: Returns a
+ generic error; v:errmsg is not updated.
+
+ Parameters:~
+ {expr} VimL expression string
+
+ Return:~
+ Evaluation result or expanded object
+
+nvim_call_function({fname}, {args}) *nvim_call_function()*
+ Calls a VimL function with the given arguments. On VimL error:
+ Returns a generic error; v:errmsg is not updated.
+
+ Parameters:~
+ {fname} Function to call
+ {args} Function arguments packed in an Array
+
+ Return:~
+ Result of the function call
+
+nvim_strwidth({str}) *nvim_strwidth()*
+ Calculates the number of display cells occupied by `text`.
+ <Tab> counts as one cell.
+
+ Parameters:~
+ {text} Some text
+
+ Return:~
+ Number of cells
+
+nvim_list_runtime_paths() *nvim_list_runtime_paths()*
+ Gets the paths contained in 'runtimepath'.
+
+ Return:~
+ List of paths
+
+nvim_set_current_dir({dir}) *nvim_set_current_dir()*
+ Changes the global working directory.
+
+ Parameters:~
+ {dir} Directory path
+
+nvim_get_current_line() *nvim_get_current_line()*
+ Gets the current line
+
+ Parameters:~
+
+ Return:~
+ Current line string
+
+nvim_set_current_line({line}) *nvim_set_current_line()*
+ Sets the current line
+
+ Parameters:~
+ {line} Line contents
+
+nvim_del_current_line() *nvim_del_current_line()*
+ Deletes the current line
+
+ Parameters:~
+
+nvim_get_var({name}) *nvim_get_var()*
+ Gets a global (g:) variable
+
+ Parameters:~
+ {name} Variable name
+
+ Return:~
+ Variable value
+
+nvim_set_var({name}, {value}) *nvim_set_var()*
+ Sets a global (g:) variable
+
+ Parameters:~
+ {name} Variable name
+ {value} Variable value
+
+nvim_del_var({name}) *nvim_del_var()*
+ Removes a global (g:) variable
+
+ Parameters:~
+ {name} Variable name
+
+nvim_get_vvar({name}) *nvim_get_vvar()*
+ Gets a v: variable
+
+ Parameters:~
+ {name} Variable name
+
+ Return:~
+ Variable value
+
+nvim_get_option({name}) *nvim_get_option()*
+ Gets an option value string
+
+ Parameters:~
+ {name} Option name
+
+ Return:~
+ Option value
+
+nvim_set_option({name}, {value}) *nvim_set_option()*
+ Sets an option value
+
+ Parameters:~
+ {name} Option name
+ {value} New option value
+
+nvim_out_write({str}) *nvim_out_write()*
+ Writes a message to vim output buffer
+
+ Parameters:~
+ {str} Message
+
+nvim_err_write({str}) *nvim_err_write()*
+ Writes a message to vim error buffer
+
+ Parameters:~
+ {str} Message
+
+nvim_err_writeln({str}) *nvim_err_writeln()*
+ Writes a message to vim error buffer. Appends a linefeed to
+ ensure all contents are written.
+
+ Parameters:~
+ {str} Message
+
+nvim_list_bufs() *nvim_list_bufs()*
+ Gets the current list of buffer handles
+
+ Return:~
+ List of buffer handles
+
+nvim_get_current_buf() *nvim_get_current_buf()*
+ Gets the current buffer
+
+ Return:~
+ Buffer handle
+
+nvim_set_current_buf({buffer}) *nvim_set_current_buf()*
+ Sets the current buffer
+
+ Parameters:~
+ {id} Buffer handle
+
+nvim_list_wins() *nvim_list_wins()*
+ Gets the current list of window handles
+
+ Return:~
+ List of window handles
+
+nvim_get_current_win() *nvim_get_current_win()*
+ Gets the current window
+
+ Return:~
+ Window handle
+
+nvim_set_current_win({window}) *nvim_set_current_win()*
+ Sets the current window
+
+ Parameters:~
+ {handle} Window handle
+
+nvim_list_tabpages() *nvim_list_tabpages()*
+ Gets the current list of tabpage handles
+
+ Return:~
+ List of tabpage handles
+
+nvim_get_current_tabpage() *nvim_get_current_tabpage()*
+ Gets the current tabpage
+
+ Return:~
+ Tabpage handle
+
+nvim_set_current_tabpage({tabpage}) *nvim_set_current_tabpage()*
+ Sets the current tabpage
+
+ Parameters:~
+ {handle} Tabpage handle
+
+nvim_subscribe({event}) *nvim_subscribe()*
+ Subscribes to event broadcasts
+
+ Parameters:~
+ {event} Event type string
+
+nvim_unsubscribe({event}) *nvim_unsubscribe()*
+ Unsubscribes to event broadcasts
+
+ Parameters:~
+ {event} Event type string
+
+nvim_get_color_by_name({name}) *nvim_get_color_by_name()*
+ TODO: Documentation
+
+nvim_get_color_map() *nvim_get_color_map()*
+ TODO: Documentation
+
+nvim_get_api_info() *nvim_get_api_info()*
+ TODO: Documentation
+
+nvim_call_atomic({calls}) *nvim_call_atomic()*
+ Call many api methods atomically
+
+ This has two main usages: Firstly, to perform several requests
+ from an async context atomically, i.e. without processing
+ requests from other rpc clients or redrawing or allowing user
+ interaction in between. Note that api methods that could fire
+ autocommands or do event processing still might do so. For
+ instance invoking the :sleep command might call timer
+ callbacks. Secondly, it can be used to reduce rpc overhead
+ (roundtrips) when doing many requests in sequence.
+
+ Parameters:~
+ {calls} an array of calls, where each call is described
+ by an array with two elements: the request name,
+ and an array of arguments.
+
+ Return:~
+ an array with two elements. The first is an array of
+ return values. The second is NIL if all calls succeeded.
+ If a call resulted in an error, it is a three-element
+ array with the zero-based index of the call which resulted
+ in an error, the error type and the error message. If an
+ error ocurred, the values from all preceding calls will
+ still be returned.
+
+
+==============================================================================
+2. Buffer Functions *api-buffer*
+
+nvim_buf_line_count({buffer}) *nvim_buf_line_count()*
+ Gets the buffer line count
+
+ Parameters:~
+ {buffer} Buffer handle
+
+ Return:~
+ Line count
+
+ *nvim_buf_get_lines()*
+nvim_buf_get_lines({buffer}, {start}, {end}, {strict_indexing})
+ Retrieves a line range from the buffer
+
+ Indexing is zero-based, end-exclusive. Negative indices are
+ interpreted as length+1+index, i e -1 refers to the index past
+ the end. So to get the last element set start=-2 and end=-1.
+
+ Out-of-bounds indices are clamped to the nearest valid value,
+ unless `strict_indexing` is set.
+
+ Parameters:~
+ {buffer} Buffer handle
+ {start} First line index
+ {end} Last line index (exclusive)
+ {strict_indexing} Whether out-of-bounds should be an
+ error.
+
+ Return:~
+ Array of lines
+
+ *nvim_buf_set_lines()*
+nvim_buf_set_lines({buffer}, {start}, {end}, {strict_indexing},
+ {replacement})
+ Replaces line range on the buffer
+
+ Indexing is zero-based, end-exclusive. Negative indices are
+ interpreted as length+1+index, i e -1 refers to the index past
+ the end. So to change or delete the last element set start=-2
+ and end=-1.
+
+ To insert lines at a given index, set both start and end to
+ the same index. To delete a range of lines, set replacement to
+ an empty array.
+
+ Out-of-bounds indices are clamped to the nearest valid value,
+ unless `strict_indexing` is set.
+
+ Parameters:~
+ {buffer} Buffer handle
+ {start} First line index
+ {end} Last line index (exclusive)
+ {strict_indexing} Whether out-of-bounds should be an
+ error.
+ {replacement} Array of lines to use as replacement
+
+nvim_buf_get_var({buffer}, {name}) *nvim_buf_get_var()*
+ Gets a buffer-scoped (b:) variable.
+
+ Parameters:~
+ {buffer} Buffer handle
+ {name} Variable name
+
+ Return:~
+ Variable value
+
+nvim_buf_set_var({buffer}, {name}, {value}) *nvim_buf_set_var()*
+ Sets a buffer-scoped (b:) variable
+
+ Parameters:~
+ {buffer} Buffer handle
+ {name} Variable name
+ {value} Variable value
+
+nvim_buf_del_var({buffer}, {name}) *nvim_buf_del_var()*
+ Removes a buffer-scoped (b:) variable
+
+ Parameters:~
+ {buffer} Buffer handle
+ {name} Variable name
+
+nvim_buf_get_option({buffer}, {name}) *nvim_buf_get_option()*
+ Gets a buffer option value
+
+ Parameters:~
+ {buffer} Buffer handle
+ {name} Option name
+
+ Return:~
+ Option value
+
+nvim_buf_set_option({buffer}, {name}, {value}) *nvim_buf_set_option()*
+ Sets a buffer option value. Passing 'nil' as value deletes the
+ option (only works if there's a global fallback)
+
+ Parameters:~
+ {buffer} Buffer handle
+ {name} Option name
+ {value} Option value
+
+nvim_buf_get_number({buffer}) *nvim_buf_get_number()*
+ Gets the buffer number
+
+ Parameters:~
+ {buffer} Buffer handle
+
+ Return:~
+ Buffer number
+
+nvim_buf_get_name({buffer}) *nvim_buf_get_name()*
+ Gets the full file name for the buffer
+
+ Parameters:~
+ {buffer} Buffer handle
+
+ Return:~
+ Buffer name
+
+nvim_buf_set_name({buffer}, {name}) *nvim_buf_set_name()*
+ Sets the full file name for a buffer
+
+ Parameters:~
+ {buffer} Buffer handle
+ {name} Buffer name
+
+nvim_buf_is_valid({buffer}) *nvim_buf_is_valid()*
+ Checks if a buffer is valid
+
+ Parameters:~
+ {buffer} Buffer handle
+
+ Return:~
+ true if the buffer is valid, false otherwise
+
+nvim_buf_get_mark({buffer}, {name}) *nvim_buf_get_mark()*
+ Return a tuple (row,col) representing the position of the
+ named mark
+
+ Parameters:~
+ {buffer} Buffer handle
+ {name} Mark name
+
+ Return:~
+ (row, col) tuple
+
+ *nvim_buf_add_highlight()*
+nvim_buf_add_highlight({buffer}, {src_id}, {hl_group}, {line},
+ {col_start}, {col_end})
+ Adds a highlight to buffer.
+
+ This can be used for plugins which dynamically generate
+ highlights to a buffer (like a semantic highlighter or
+ linter). The function adds a single highlight to a buffer.
+ Unlike matchaddpos() highlights follow changes to line
+ numbering (as lines are inserted/removed above the highlighted
+ line), like signs and marks do.
+
+ "src_id" is useful for batch deletion/updating of a set of
+ highlights. When called with src_id = 0, an unique source id
+ is generated and returned. Succesive calls can pass in it as
+ "src_id" to add new highlights to the same source group. All
+ highlights in the same group can then be cleared with
+ nvim_buf_clear_highlight. If the highlight never will be
+ manually deleted pass in -1 for "src_id".
+
+ If "hl_group" is the empty string no highlight is added, but a
+ new src_id is still returned. This is useful for an external
+ plugin to synchrounously request an unique src_id at
+ initialization, and later asynchronously add and clear
+ highlights in response to buffer changes.
+
+ Parameters:~
+ {buffer} Buffer handle
+ {src_id} Source group to use or 0 to use a new group,
+ or -1 for ungrouped highlight
+ {hl_group} Name of the highlight group to use
+ {line} Line to highlight
+ {col_start} Start of range of columns to highlight
+ {col_end} End of range of columns to highlight, or -1
+ to highlight to end of line
+
+ Return:~
+ The src_id that was used
+
+ *nvim_buf_clear_highlight()*
+nvim_buf_clear_highlight({buffer}, {src_id}, {line_start}, {line_end})
+ Clears highlights from a given source group and a range of
+ lines
+
+ To clear a source group in the entire buffer, pass in 1 and -1
+ to line_start and line_end respectively.
+
+ Parameters:~
+ {buffer} Buffer handle
+ {src_id} Highlight source group to clear, or -1 to
+ clear all.
+ {line_start} Start of range of lines to clear
+ {line_end} End of range of lines to clear (exclusive)
+ or -1 to clear to end of file.
+
+
+==============================================================================
+3. Window Functions *api-window*
+
+nvim_win_get_buf({window}) *nvim_win_get_buf()*
+ Gets the current buffer in a window
+
+ Parameters:~
+ {window} Window handle
+
+ Return:~
+ Buffer handle
+
+nvim_win_get_cursor({window}) *nvim_win_get_cursor()*
+ Gets the cursor position in the window
+
+ Parameters:~
+ {window} Window handle
+
+ Return:~
+ (row, col) tuple
+
+nvim_win_set_cursor({window}, {pos}) *nvim_win_set_cursor()*
+ Sets the cursor position in the window
+
+ Parameters:~
+ {window} Window handle
+ {pos} (row, col) tuple representing the new position
+
+nvim_win_get_height({window}) *nvim_win_get_height()*
+ Gets the window height
+
+ Parameters:~
+ {window} Window handle
+
+ Return:~
+ Height as a count of rows
+
+nvim_win_set_height({window}, {height}) *nvim_win_set_height()*
+ Sets the window height. This will only succeed if the screen
+ is split horizontally.
+
+ Parameters:~
+ {window} Window handle
+ {height} Height as a count of rows
+
+nvim_win_get_width({window}) *nvim_win_get_width()*
+ Gets the window width
+
+ Parameters:~
+ {window} Window handle
+
+ Return:~
+ Width as a count of columns
+
+nvim_win_set_width({window}, {width}) *nvim_win_set_width()*
+ Sets the window width. This will only succeed if the screen is
+ split vertically.
+
+ Parameters:~
+ {window} Window handle
+ {width} Width as a count of columns
+
+nvim_win_get_var({window}, {name}) *nvim_win_get_var()*
+ Gets a window-scoped (w:) variable
+
+ Parameters:~
+ {window} Window handle
+ {name} Variable name
+
+ Return:~
+ Variable value
+
+nvim_win_set_var({window}, {name}, {value}) *nvim_win_set_var()*
+ Sets a window-scoped (w:) variable
+
+ Parameters:~
+ {window} Window handle
+ {name} Variable name
+ {value} Variable value
+
+nvim_win_del_var({window}, {name}) *nvim_win_del_var()*
+ Removes a window-scoped (w:) variable
+
+ Parameters:~
+ {window} Window handle
+ {name} Variable name
+
+nvim_win_get_option({window}, {name}) *nvim_win_get_option()*
+ Gets a window option value
+
+ Parameters:~
+ {window} Window handle
+ {name} Option name
+
+ Return:~
+ Option value
+
+nvim_win_set_option({window}, {name}, {value}) *nvim_win_set_option()*
+ Sets a window option value. Passing 'nil' as value deletes the
+ option(only works if there's a global fallback)
+
+ Parameters:~
+ {window} Window handle
+ {name} Option name
+ {value} Option value
+
+nvim_win_get_position({window}) *nvim_win_get_position()*
+ Gets the window position in display cells. First position is
+ zero.
+
+ Parameters:~
+ {window} Window handle
+
+ Return:~
+ (row, col) tuple with the window position
+
+nvim_win_get_tabpage({window}) *nvim_win_get_tabpage()*
+ Gets the window tabpage
+
+ Parameters:~
+ {window} Window handle
+
+ Return:~
+ Tabpage that contains the window
+
+nvim_win_get_number({window}) *nvim_win_get_number()*
+ Gets the window number
+
+ Parameters:~
+ {window} Window handle
+
+ Return:~
+ Window number
+
+nvim_win_is_valid({window}) *nvim_win_is_valid()*
+ Checks if a window is valid
+
+ Parameters:~
+ {window} Window handle
+
+ Return:~
+ true if the window is valid, false otherwise
+
+
+==============================================================================
+4. Tabpage Functions *api-tabpage*
+
+nvim_tabpage_list_wins({tabpage}) *nvim_tabpage_list_wins()*
+ Gets the windows in a tabpage
+
+ Parameters:~
+ {tabpage} Tabpage
+
+ Return:~
+ List of windows in tabpage
+
+nvim_tabpage_get_var({tabpage}, {name}) *nvim_tabpage_get_var()*
+ Gets a tab-scoped (t:) variable
+
+ Parameters:~
+ {tabpage} Tabpage handle
+ {name} Variable name
+
+ Return:~
+ Variable value
+
+nvim_tabpage_set_var({tabpage}, {name}, {value}) *nvim_tabpage_set_var()*
+ Sets a tab-scoped (t:) variable
+
+ Parameters:~
+ {tabpage} Tabpage handle
+ {name} Variable name
+ {value} Variable value
+
+nvim_tabpage_del_var({tabpage}, {name}) *nvim_tabpage_del_var()*
+ Removes a tab-scoped (t:) variable
+
+ Parameters:~
+ {tabpage} Tabpage handle
+ {name} Variable name
+
+nvim_tabpage_get_win({tabpage}) *nvim_tabpage_get_win()*
+ Gets the current window in a tabpage
+
+ Parameters:~
+ {tabpage} Tabpage handle
+
+ Return:~
+ Window handle
+
+nvim_tabpage_get_number({tabpage}) *nvim_tabpage_get_number()*
+ Gets the tabpage number
+
+ Parameters:~
+ {tabpage} Tabpage handle
+
+ Return:~
+ Tabpage number
+
+nvim_tabpage_is_valid({tabpage}) *nvim_tabpage_is_valid()*
+ Checks if a tabpage is valid
+
+ Parameters:~
+ {tabpage} Tabpage handle
+
+ Return:~
+ true if the tabpage is valid, false otherwise
+
+
+==============================================================================
+5. UI Functions *api-ui*
+
+remote_ui_disconnect() *remote_ui_disconnect()*
+ TODO: Documentation
+
+nvim_ui_attach({width}, {height}, {options}) *nvim_ui_attach()*
+ TODO: Documentation
+
+nvim_ui_detach() *nvim_ui_detach()*
+ TODO: Documentation
+
+nvim_ui_try_resize({width}, {height}) *nvim_ui_try_resize()*
+ TODO: Documentation
+
+nvim_ui_set_option({name}, {value}) *nvim_ui_set_option()*
+ TODO: Documentation
+
+ vim:tw=78:ts=8:ft=help:norl: \ No newline at end of file
diff --git a/runtime/doc/autocmd.txt b/runtime/doc/autocmd.txt
index 4f23aee83d..65e091edf5 100644
--- a/runtime/doc/autocmd.txt
+++ b/runtime/doc/autocmd.txt
@@ -49,9 +49,6 @@ effects. Be careful not to destroy your text.
==============================================================================
2. Defining autocommands *autocmd-define*
-Note: The ":autocmd" command cannot be followed by another command, since any
-'|' is considered part of the command.
-
*:au* *:autocmd*
:au[tocmd] [group] {event} {pat} [nested] {cmd}
Add {cmd} to the list of commands that Vim will
@@ -64,6 +61,12 @@ Note: The ":autocmd" command cannot be followed by another command, since any
The special pattern <buffer> or <buffer=N> defines a buffer-local autocommand.
See |autocmd-buflocal|.
+Note: The ":autocmd" command can only be followed by another command when the
+'|' appears before {cmd}. This works: >
+ :augroup mine | au! BufRead | augroup END
+But this sees "augroup" as part of the defined command: >
+ :augroup mine | au BufRead * set tw=70 | augroup END
+
Note that special characters (e.g., "%", "<cword>") in the ":autocmd"
arguments are not expanded when the autocommand is defined. These will be
expanded when the Event is recognized, and the {cmd} is executed. The only
diff --git a/runtime/doc/mbyte.txt b/runtime/doc/mbyte.txt
index 3bdb682a31..355a1da423 100644
--- a/runtime/doc/mbyte.txt
+++ b/runtime/doc/mbyte.txt
@@ -1,4 +1,4 @@
-*mbyte.txt* For Vim version 7.4. Last change: 2013 May 18
+*mbyte.txt* For Vim version 7.4. Last change: 2016 Jul 21
VIM REFERENCE MANUAL by Bram Moolenaar et al.
@@ -849,6 +849,7 @@ text, you can use the 'keymap' option. This will translate one or more
(English) characters to another (non-English) character. This only happens
when typing text, not when typing Vim commands. This avoids having to switch
between two keyboard settings.
+{only available when compiled with the |+keymap| feature}
The value of the 'keymap' option specifies a keymap file to use. The name of
this file is one of these two:
diff --git a/runtime/doc/pi_msgpack.txt b/runtime/doc/pi_msgpack.txt
index 95d6ff7467..d695ac42cb 100644
--- a/runtime/doc/pi_msgpack.txt
+++ b/runtime/doc/pi_msgpack.txt
@@ -128,6 +128,11 @@ msgpack#eval({string}, {dict}) *msgpack#eval()*
always evaluated to |msgpack-special-dict| values, as well as
hexadecimal digits. When evaluating maps order of keys is preserved.
+ Note that in addition to regular integer representations that may be
+ obtained using |msgpack#string()| msgpack#eval() also supports C-style
+ “character” integer constants like `'/'` (equivalent to
+ `char2nr('/')`: `47`). This also allows `'\0'` (number is decimal).
+
*msgpack#equal*
msgpack#equal({msgpack-value}, {msgpack-value}) *msgpack#equal()*
Returns 1 if given values are equal, 0 otherwise. When comparing
diff --git a/runtime/doc/repeat.txt b/runtime/doc/repeat.txt
index b44761cdb5..6cd2ada513 100644
--- a/runtime/doc/repeat.txt
+++ b/runtime/doc/repeat.txt
@@ -1,4 +1,4 @@
-*repeat.txt* For Vim version 7.4. Last change: 2016 Apr 05
+*repeat.txt* For Vim version 7.4. Last change: 2016 Jul 21
VIM REFERENCE MANUAL by Bram Moolenaar
@@ -286,7 +286,9 @@ For writing a Vim script, see chapter 41 of the user manual |usr_41.txt|.
... not converted ...
< When conversion isn't supported by the system, there
- is no error message and no conversion is done.
+ is no error message and no conversion is done. When a
+ line can't be converted there is no error and the
+ original line is kept.
Don't use "ucs-2" or "ucs-4", scripts cannot be in
these encodings (they would contain NUL bytes).
diff --git a/runtime/doc/syntax.txt b/runtime/doc/syntax.txt
index 4886828c82..6194a636b3 100644
--- a/runtime/doc/syntax.txt
+++ b/runtime/doc/syntax.txt
@@ -1040,6 +1040,21 @@ This works immediately.
CLOJURE *ft-clojure-syntax*
+The default syntax groups can be augmented through the
+*g:clojure_syntax_keywords* and *b:clojure_syntax_keywords* variables. The
+value should be a |Dictionary| of syntax group names to a |List| of custom
+identifiers:
+>
+ let g:clojure_syntax_keywords = {
+ \ 'clojureMacro': ["defproject", "defcustom"],
+ \ 'clojureFunc': ["string/join", "string/replace"]
+ \ }
+<
+Refer to the Clojure syntax script for valid syntax group names.
+
+If the |buffer-variable| *b:clojure_syntax_without_core_keywords* is set, only
+language constants and special forms are matched.
+
Setting *g:clojure_fold* enables folding Clojure code via the syntax engine.
Any list, vector, or map that extends over more than one line can be folded
using the standard Vim |fold-commands|.
diff --git a/runtime/doc/usr_41.txt b/runtime/doc/usr_41.txt
index 49fcdf0bb7..bf8d31fef9 100644
--- a/runtime/doc/usr_41.txt
+++ b/runtime/doc/usr_41.txt
@@ -592,7 +592,7 @@ String manipulation: *string-functions*
match() position where a pattern matches in a string
matchend() position where a pattern match ends in a string
matchstr() match of a pattern in a string
- matchstrpos() match and postions of a pattern in a string
+ matchstrpos() match and positions of a pattern in a string
matchlist() like matchstr() and also return submatches
stridx() first index of a short string in a long string
strridx() last index of a short string in a long string
@@ -799,6 +799,7 @@ Command line: *command-line-functions*
setcmdpos() set position of the cursor in the command line
getcmdtype() return the current command-line type
getcmdwintype() return the current command-line window type
+ getcompletion() list of command-line completion matches
Quickfix and location lists: *quickfix-functions*
getqflist() list of quickfix errors
@@ -896,6 +897,7 @@ Mappings: *mapping-functions*
Testing: *test-functions*
assert_equal() assert that two expressions values are equal
assert_notequal() assert that two expressions values are not equal
+ assert_inrange() assert that an expression is inside a range
assert_match() assert that a pattern matches the value
assert_notmatch() assert that a pattern does not match the value
assert_false() assert that an expression is false
diff --git a/runtime/doc/vim_diff.txt b/runtime/doc/vim_diff.txt
index cdd616b6c1..7c9d383a01 100644
--- a/runtime/doc/vim_diff.txt
+++ b/runtime/doc/vim_diff.txt
@@ -77,12 +77,15 @@ Clipboard integration |provider-clipboard|
USER EXPERIENCE ~
-A major goal of Nvim is to work intuitively and consistently. For example,
-Nvim does not have `-X`, a platform-specific option available in some Vim
-builds (with potential surprises: http://stackoverflow.com/q/14635295). Nvim
-avoids features that cannot be provided on all platforms--instead that is
-delegated to external plugins/extensions.
+Working intuitively and consistently is a major goal of Nvim. Examples:
+- Nvim does not have `-X`, a platform-specific option "sometimes" available in
+ Vim (with potential surprises: http://stackoverflow.com/q/14635295). Nvim
+ avoids features that cannot be provided on all platforms--instead that is
+ delegated to external plugins/extensions.
+
+- Test-only globals and functions such as test_autochdir(), test_settime(),
+ etc., are not exposed (because they don't exist).
ARCHITECTURE ~
@@ -271,6 +274,19 @@ MS-DOS support:
Highlight groups:
|hl-VisualNOS|
+Test functions:
+ test_alloc_fail()
+ test_autochdir()
+ test_disable_char_avail()
+ test_garbagecollect_now()
+ test_null_channel()
+ test_null_dict()
+ test_null_job()
+ test_null_list()
+ test_null_partial()
+ test_null_string()
+ test_settime()
+
Other options:
'antialias'
'cpoptions' ("g", "w", "H", "*", "-", "j", and all POSIX flags were removed)
diff --git a/runtime/filetype.vim b/runtime/filetype.vim
index bfb45a3720..93886d5379 100644
--- a/runtime/filetype.vim
+++ b/runtime/filetype.vim
@@ -1,7 +1,7 @@
" Vim support file to detect file types
"
" Maintainer: Bram Moolenaar <Bram@vim.org>
-" Last Change: 2016 Jul 12
+" Last Change: 2016 Jul 21
" Listen very carefully, I will say this only once
if exists("did_load_filetypes")
@@ -530,7 +530,7 @@ au BufNewFile,BufRead configure.in,configure.ac setf config
au BufNewFile,BufRead *.cu setf cuda
" Dockerfile
-au BufNewFile,BufRead Dockerfile setf dockerfile
+au BufNewFile,BufRead Dockerfile,*.Dockerfile setf dockerfile
" WildPackets EtherPeek Decoder
au BufNewFile,BufRead *.dcd setf dcd
@@ -1143,7 +1143,7 @@ au BufNewFile,BufRead *.ist,*.mst setf ist
au BufNewFile,BufRead *.page setf mallard
" Manpage
-au BufNewFile,BufRead *.man setf man
+au BufNewFile,BufRead *.man setf nroff
" Man config
au BufNewFile,BufRead */etc/man.conf,man.config setf manconf
diff --git a/runtime/ftplugin/clojure.vim b/runtime/ftplugin/clojure.vim
index 10fcb9f205..217711f26e 100644
--- a/runtime/ftplugin/clojure.vim
+++ b/runtime/ftplugin/clojure.vim
@@ -1,11 +1,11 @@
" Vim filetype plugin file
-" Language: Clojure
-" Author: Meikel Brandmeyer <mb@kotka.de>
+" Language: Clojure
+" Author: Meikel Brandmeyer <mb@kotka.de>
"
-" Maintainer: Sung Pae <self@sungpae.com>
-" URL: https://github.com/guns/vim-clojure-static
-" License: Same as Vim
-" Last Change: 27 March 2014
+" Maintainer: Sung Pae <self@sungpae.com>
+" URL: https://github.com/guns/vim-clojure-static
+" License: Same as Vim
+" Last Change: 18 July 2016
if exists("b:did_ftplugin")
finish
@@ -43,7 +43,7 @@ setlocal commentstring=;\ %s
" specially and hence are not indented specially.
"
" -*- LISPWORDS -*-
-" Generated from https://github.com/guns/vim-clojure-static/blob/vim-release-010/clj/src/vim_clojure_static/generate.clj
+" Generated from https://github.com/guns/vim-clojure-static/blob/vim-release-011/clj/src/vim_clojure_static/generate.clj
setlocal lispwords=as->,binding,bound-fn,case,catch,cond->,cond->>,condp,def,definline,definterface,defmacro,defmethod,defmulti,defn,defn-,defonce,defprotocol,defrecord,defstruct,deftest,deftest-,deftype,doseq,dotimes,doto,extend,extend-protocol,extend-type,fn,for,if,if-let,if-not,if-some,let,letfn,locking,loop,ns,proxy,reify,set-test,testing,when,when-first,when-let,when-not,when-some,while,with-bindings,with-in-str,with-local-vars,with-open,with-precision,with-redefs,with-redefs-fn,with-test
" Provide insert mode completions for special forms and clojure.core. As
@@ -82,9 +82,9 @@ endif
" Win32 can filter files in the browse dialog
if has("gui_win32") && !exists("b:browsefilter")
let b:browsefilter = "Clojure Source Files (*.clj)\t*.clj\n" .
- \ "ClojureScript Source Files (*.cljs)\t*.cljs\n" .
- \ "Java Source Files (*.java)\t*.java\n" .
- \ "All Files (*.*)\t*.*\n"
+ \ "ClojureScript Source Files (*.cljs)\t*.cljs\n" .
+ \ "Java Source Files (*.java)\t*.java\n" .
+ \ "All Files (*.*)\t*.*\n"
let b:undo_ftplugin .= ' | unlet! b:browsefilter'
endif
diff --git a/runtime/indent/clojure.vim b/runtime/indent/clojure.vim
index 476ac1de1c..7592b10d7d 100644
--- a/runtime/indent/clojure.vim
+++ b/runtime/indent/clojure.vim
@@ -1,17 +1,12 @@
" Vim indent file
-" Language: Clojure
-" Author: Meikel Brandmeyer <mb@kotka.de>
-" URL: http://kotka.de/projects/clojure/vimclojure.html
+" Language: Clojure
+" Author: Meikel Brandmeyer <mb@kotka.de>
+" URL: http://kotka.de/projects/clojure/vimclojure.html
"
-" Maintainer: Sung Pae <self@sungpae.com>
-" URL: https://github.com/guns/vim-clojure-static
-" License: Same as Vim
-" Last Change: 27 March 2014
-
-" TODO: Indenting after multibyte characters is broken:
-" (let [Δ (if foo
-" bar ; Indent error
-" baz)])
+" Maintainer: Sung Pae <self@sungpae.com>
+" URL: https://github.com/guns/vim-clojure-static
+" License: Same as Vim
+" Last Change: 18 July 2016
if exists("b:did_indent")
finish
@@ -57,36 +52,39 @@ if exists("*searchpairpos")
let g:clojure_align_subforms = 0
endif
- function! s:SynIdName()
+ function! s:syn_id_name()
return synIDattr(synID(line("."), col("."), 0), "name")
endfunction
- function! s:CurrentChar()
+ function! s:ignored_region()
+ return s:syn_id_name() =~? '\vstring|regex|comment|character'
+ endfunction
+
+ function! s:current_char()
return getline('.')[col('.')-1]
endfunction
- function! s:CurrentWord()
+ function! s:current_word()
return getline('.')[col('.')-1 : searchpos('\v>', 'n', line('.'))[1]-2]
endfunction
- function! s:IsParen()
- return s:CurrentChar() =~# '\v[\(\)\[\]\{\}]' &&
- \ s:SynIdName() !~? '\vstring|regex|comment|character'
+ function! s:is_paren()
+ return s:current_char() =~# '\v[\(\)\[\]\{\}]' && !s:ignored_region()
endfunction
" Returns 1 if string matches a pattern in 'patterns', which may be a
" list of patterns, or a comma-delimited string of implicitly anchored
" patterns.
- function! s:MatchesOne(patterns, string)
+ function! s:match_one(patterns, string)
let list = type(a:patterns) == type([])
- \ ? a:patterns
- \ : map(split(a:patterns, ','), '"^" . v:val . "$"')
+ \ ? a:patterns
+ \ : map(split(a:patterns, ','), '"^" . v:val . "$"')
for pat in list
if a:string =~# pat | return 1 | endif
endfor
endfunction
- function! s:MatchPairs(open, close, stopat)
+ function! s:match_pairs(open, close, stopat)
" Stop only on vector and map [ resp. {. Ignore the ones in strings and
" comments.
if a:stopat == 0
@@ -95,11 +93,11 @@ if exists("*searchpairpos")
let stopat = a:stopat
endif
- let pos = searchpairpos(a:open, '', a:close, 'bWn', "!s:IsParen()", stopat)
- return [pos[0], virtcol(pos)]
+ let pos = searchpairpos(a:open, '', a:close, 'bWn', "!s:is_paren()", stopat)
+ return [pos[0], col(pos)]
endfunction
- function! s:ClojureCheckForStringWorker()
+ function! s:clojure_check_for_string_worker()
" Check whether there is the last character of the previous line is
" highlighted as a string. If so, we check whether it's a ". In this
" case we have to check also the previous character. The " might be the
@@ -113,17 +111,17 @@ if exists("*searchpairpos")
call cursor(nb, 0)
call cursor(0, col("$") - 1)
- if s:SynIdName() !~? "string"
+ if s:syn_id_name() !~? "string"
return -1
endif
" This will not work for a " in the first column...
- if s:CurrentChar() == '"'
+ if s:current_char() == '"'
call cursor(0, col("$") - 2)
- if s:SynIdName() !~? "string"
+ if s:syn_id_name() !~? "string"
return -1
endif
- if s:CurrentChar() != '\\'
+ if s:current_char() != '\\'
return -1
endif
call cursor(0, col("$") - 1)
@@ -138,40 +136,40 @@ if exists("*searchpairpos")
return indent(".")
endfunction
- function! s:CheckForString()
+ function! s:check_for_string()
let pos = getpos('.')
try
- let val = s:ClojureCheckForStringWorker()
+ let val = s:clojure_check_for_string_worker()
finally
call setpos('.', pos)
endtry
return val
endfunction
- function! s:StripNamespaceAndMacroChars(word)
+ function! s:strip_namespace_and_macro_chars(word)
return substitute(a:word, "\\v%(.*/|[#'`~@^,]*)(.*)", '\1', '')
endfunction
- function! s:ClojureIsMethodSpecialCaseWorker(position)
+ function! s:clojure_is_method_special_case_worker(position)
" Find the next enclosing form.
call search('\S', 'Wb')
" Special case: we are at a '(('.
- if s:CurrentChar() == '('
+ if s:current_char() == '('
return 0
endif
call cursor(a:position)
- let nextParen = s:MatchPairs('(', ')', 0)
+ let next_paren = s:match_pairs('(', ')', 0)
" Special case: we are now at toplevel.
- if nextParen == [0, 0]
+ if next_paren == [0, 0]
return 0
endif
- call cursor(nextParen)
+ call cursor(next_paren)
call search('\S', 'W')
- let w = s:StripNamespaceAndMacroChars(s:CurrentWord())
+ let w = s:strip_namespace_and_macro_chars(s:current_word())
if g:clojure_special_indent_words =~# '\V\<' . w . '\>'
return 1
endif
@@ -179,27 +177,43 @@ if exists("*searchpairpos")
return 0
endfunction
- function! s:IsMethodSpecialCase(position)
+ function! s:is_method_special_case(position)
let pos = getpos('.')
try
- let val = s:ClojureIsMethodSpecialCaseWorker(a:position)
+ let val = s:clojure_is_method_special_case_worker(a:position)
finally
call setpos('.', pos)
endtry
return val
endfunction
- function! GetClojureIndent()
+ " Check if form is a reader conditional, that is, it is prefixed by #?
+ " or @#?
+ function! s:is_reader_conditional_special_case(position)
+ if getline(a:position[0])[a:position[1] - 3 : a:position[1] - 2] == "#?"
+ return 1
+ endif
+
+ return 0
+ endfunction
+
+ " Returns 1 for opening brackets, -1 for _anything else_.
+ function! s:bracket_type(char)
+ return stridx('([{', a:char) > -1 ? 1 : -1
+ endfunction
+
+ " Returns: [opening-bracket-lnum, indent]
+ function! s:clojure_indent_pos()
" Get rid of special case.
if line(".") == 1
- return 0
+ return [0, 0]
endif
" We have to apply some heuristics here to figure out, whether to use
" normal lisp indenting or not.
- let i = s:CheckForString()
+ let i = s:check_for_string()
if i > -1
- return i + !!g:clojure_align_multiline_strings
+ return [0, i + !!g:clojure_align_multiline_strings]
endif
call cursor(0, 1)
@@ -207,28 +221,28 @@ if exists("*searchpairpos")
" Find the next enclosing [ or {. We can limit the second search
" to the line, where the [ was found. If no [ was there this is
" zero and we search for an enclosing {.
- let paren = s:MatchPairs('(', ')', 0)
- let bracket = s:MatchPairs('\[', '\]', paren[0])
- let curly = s:MatchPairs('{', '}', bracket[0])
+ let paren = s:match_pairs('(', ')', 0)
+ let bracket = s:match_pairs('\[', '\]', paren[0])
+ let curly = s:match_pairs('{', '}', bracket[0])
" In case the curly brace is on a line later then the [ or - in
" case they are on the same line - in a higher column, we take the
" curly indent.
if curly[0] > bracket[0] || curly[1] > bracket[1]
if curly[0] > paren[0] || curly[1] > paren[1]
- return curly[1]
+ return curly
endif
endif
" If the curly was not chosen, we take the bracket indent - if
" there was one.
if bracket[0] > paren[0] || bracket[1] > paren[1]
- return bracket[1]
+ return bracket
endif
" There are neither { nor [ nor (, ie. we are at the toplevel.
if paren == [0, 0]
- return 0
+ return paren
endif
" Now we have to reimplement lispindent. This is surprisingly easy, as
@@ -246,58 +260,120 @@ if exists("*searchpairpos")
" - In any other case we use the column of the end of the word + 2.
call cursor(paren)
- if s:IsMethodSpecialCase(paren)
- return paren[1] + &shiftwidth - 1
+ if s:is_method_special_case(paren)
+ return [paren[0], paren[1] + &shiftwidth - 1]
+ endif
+
+ if s:is_reader_conditional_special_case(paren)
+ return paren
endif
" In case we are at the last character, we use the paren position.
if col("$") - 1 == paren[1]
- return paren[1]
+ return paren
endif
" In case after the paren is a whitespace, we search for the next word.
call cursor(0, col('.') + 1)
- if s:CurrentChar() == ' '
+ if s:current_char() == ' '
call search('\v\S', 'W')
endif
" If we moved to another line, there is no word after the (. We
" use the ( position for indent.
if line(".") > paren[0]
- return paren[1]
+ return paren
endif
" We still have to check, whether the keyword starts with a (, [ or {.
" In that case we use the ( position for indent.
- let w = s:CurrentWord()
- if stridx('([{', w[0]) > -1
- return paren[1]
+ let w = s:current_word()
+ if s:bracket_type(w[0]) == 1
+ return paren
endif
" Test words without namespace qualifiers and leading reader macro
" metacharacters.
"
" e.g. clojure.core/defn and #'defn should both indent like defn.
- let ww = s:StripNamespaceAndMacroChars(w)
+ let ww = s:strip_namespace_and_macro_chars(w)
if &lispwords =~# '\V\<' . ww . '\>'
- return paren[1] + &shiftwidth - 1
+ return [paren[0], paren[1] + &shiftwidth - 1]
endif
if g:clojure_fuzzy_indent
- \ && !s:MatchesOne(g:clojure_fuzzy_indent_blacklist, ww)
- \ && s:MatchesOne(g:clojure_fuzzy_indent_patterns, ww)
- return paren[1] + &shiftwidth - 1
+ \ && !s:match_one(g:clojure_fuzzy_indent_blacklist, ww)
+ \ && s:match_one(g:clojure_fuzzy_indent_patterns, ww)
+ return [paren[0], paren[1] + &shiftwidth - 1]
endif
call search('\v\_s', 'cW')
call search('\v\S', 'W')
if paren[0] < line(".")
- return paren[1] + (g:clojure_align_subforms ? 0 : &shiftwidth - 1)
+ return [paren[0], paren[1] + (g:clojure_align_subforms ? 0 : &shiftwidth - 1)]
endif
call search('\v\S', 'bW')
- return virtcol(".") + 1
+ return [line('.'), col('.') + 1]
+ endfunction
+
+ function! GetClojureIndent()
+ let lnum = line('.')
+ let orig_lnum = lnum
+ let orig_col = col('.')
+ let [opening_lnum, indent] = s:clojure_indent_pos()
+
+ " Account for multibyte characters
+ if opening_lnum > 0
+ let indent -= indent - virtcol([opening_lnum, indent])
+ endif
+
+ " Return if there are no previous lines to inherit from
+ if opening_lnum < 1 || opening_lnum >= lnum - 1
+ call cursor(orig_lnum, orig_col)
+ return indent
+ endif
+
+ let bracket_count = 0
+
+ " Take the indent of the first previous non-white line that is
+ " at the same sexp level. cf. src/misc1.c:get_lisp_indent()
+ while 1
+ let lnum = prevnonblank(lnum - 1)
+ let col = 1
+
+ if lnum <= opening_lnum
+ break
+ endif
+
+ call cursor(lnum, col)
+
+ " Handle bracket counting edge case
+ if s:is_paren()
+ let bracket_count += s:bracket_type(s:current_char())
+ endif
+
+ while 1
+ if search('\v[(\[{}\])]', '', lnum) < 1
+ break
+ elseif !s:ignored_region()
+ let bracket_count += s:bracket_type(s:current_char())
+ endif
+ endwhile
+
+ if bracket_count == 0
+ " Check if this is part of a multiline string
+ call cursor(lnum, 1)
+ if s:syn_id_name() !~? '\vstring|regex'
+ call cursor(orig_lnum, orig_col)
+ return indent(lnum)
+ endif
+ endif
+ endwhile
+
+ call cursor(orig_lnum, orig_col)
+ return indent
endfunction
setlocal indentexpr=GetClojureIndent()
diff --git a/runtime/keymap/armenian-eastern_utf-8.vim b/runtime/keymap/armenian-eastern_utf-8.vim
new file mode 100644
index 0000000000..7b03c5ac73
--- /dev/null
+++ b/runtime/keymap/armenian-eastern_utf-8.vim
@@ -0,0 +1,108 @@
+" Maintainer: Benjamin Linskey <vim@benlinskey.com>
+" Last Changed: 2016 July 20
+" URL: https://github.com/blinskey/vim-armenian-keymaps
+
+let b:keymap_name = "hy"
+
+loadkeymap
+
+" Capital letters
+A Ա
+B Բ
+C Գ
+D Դ
+Y Ե
+Z Զ
+E Է
+U Ը
+: Թ
++ Ժ
+I Ի
+L Լ
+Q Խ
+? Ծ
+K Կ
+H Հ
+@ Ձ
+> Ղ
+J Ճ
+M Մ
+# Յ
+N Ն
+< Շ
+O Ո
+{ Չ
+P Պ
+} Ջ
+_ Ռ
+S Ս
+V Վ
+T Տ
+R Ր
+X Ց
+W Ւ
+\" Փ
+G Ք
+) Օ
+F Ֆ
+
+" Lowercase letters
+a ա
+b բ
+c գ
+d դ
+y ե
+z զ
+e է
+u ը
+; թ
+= ժ
+i ի
+l լ
+q խ
+/ ծ
+k կ
+h հ
+2 ձ
+. ղ
+j ճ
+m մ
+3 յ
+n ն
+, շ
+o ո
+[ չ
+p պ
+] ջ
+- ռ
+s ս
+v վ
+t տ
+r ր
+x ց
+w ւ
+' փ
+g ք
+0 օ
+f ֆ
+
+& և
+
+" Punctuation
+` ՝
+~ ՜
+1 ։
+4 ՛
+5 ,
+6 -
+7 .
+8 «
+9 »
+\\ '
+| ՞
+
+" Numbers
+! 1
+$ 3
+% 4
+^ 9
diff --git a/runtime/keymap/armenian-western_utf-8.vim b/runtime/keymap/armenian-western_utf-8.vim
new file mode 100644
index 0000000000..e02485ed8c
--- /dev/null
+++ b/runtime/keymap/armenian-western_utf-8.vim
@@ -0,0 +1,108 @@
+" Maintainer: Benjamin Linskey <vim@benlinskey.com>
+" Last Changed: 2016 July 20
+" URL: https://github.com/blinskey/vim-armenian-keymaps
+
+let b:keymap_name = "hy"
+
+loadkeymap
+
+" Capital letters
+A Ա
+P Բ
+C Գ
+T Դ
+Y Ե
+Z Զ
+E Է
+U Ը
+: Թ
++ Ժ
+I Ի
+L Լ
+Q Խ
+? Ծ
+G Կ
+H Հ
+@ Ձ
+> Ղ
+J Ճ
+M Մ
+# Յ
+N Ն
+< Շ
+O Ո
+{ Չ
+B Պ
+} Ջ
+_ Ռ
+S Ս
+W Վ
+D Տ
+R Ր
+X Ց
+V Ւ
+\" Փ
+K Ք
+) Օ
+F Ֆ
+
+" Lowercase letters
+a ա
+p բ
+c գ
+t դ
+y ե
+z զ
+e է
+u ը
+; թ
+= ժ
+i ի
+l լ
+q խ
+/ ծ
+g կ
+h հ
+2 ձ
+. ղ
+j ճ
+m մ
+3 յ
+n ն
+, շ
+o ո
+[ չ
+b պ
+] ջ
+- ռ
+s ս
+w վ
+d տ
+r ր
+x ց
+v ւ
+' փ
+k ք
+0 օ
+f ֆ
+
+& և
+
+" Punctuation
+` ՝
+~ ՜
+1 ։
+4 ՛
+5 ,
+6 -
+7 .
+8 «
+9 »
+\\ '
+| ՞
+
+" Numbers
+! 1
+$ 3
+% 4
+^ 9
diff --git a/runtime/syntax/clojure.vim b/runtime/syntax/clojure.vim
index 4dc1cde05c..2b48146b5a 100644
--- a/runtime/syntax/clojure.vim
+++ b/runtime/syntax/clojure.vim
@@ -1,37 +1,68 @@
" Vim syntax file
-" Language: Clojure
-" Authors: Toralf Wittner <toralf.wittner@gmail.com>
-" modified by Meikel Brandmeyer <mb@kotka.de>
-" URL: http://kotka.de/projects/clojure/vimclojure.html
+" Language: Clojure
+" Authors: Toralf Wittner <toralf.wittner@gmail.com>
+" modified by Meikel Brandmeyer <mb@kotka.de>
+" URL: http://kotka.de/projects/clojure/vimclojure.html
"
-" Contributors: Joel Holdbrooks <cjholdbrooks@gmail.com> (Regexp support, bug fixes)
+" Contributors: Joel Holdbrooks <cjholdbrooks@gmail.com> (Regexp support, bug fixes)
"
-" Maintainer: Sung Pae <self@sungpae.com>
-" URL: https://github.com/guns/vim-clojure-static
-" License: Same as Vim
-" Last Change: 27 March 2014
+" Maintainer: Sung Pae <self@sungpae.com>
+" URL: https://github.com/guns/vim-clojure-static
+" License: Same as Vim
+" Last Change: 18 July 2016
if exists("b:current_syntax")
finish
endif
+let s:cpo_sav = &cpo
+set cpo&vim
+
if has("folding") && exists("g:clojure_fold") && g:clojure_fold > 0
setlocal foldmethod=syntax
endif
" -*- KEYWORDS -*-
-" 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
-syntax keyword clojureConstant nil
-syntax keyword clojureBoolean false true
-syntax keyword clojureSpecial . catch clojure.core/fn clojure.core/let clojure.core/loop def do finally fn if let loop monitor-enter monitor-exit new quote recur set! throw try var
-syntax keyword clojureException catch finally throw try
-syntax keyword clojureCond case clojure.core/case clojure.core/cond clojure.core/cond-> clojure.core/cond->> clojure.core/condp clojure.core/if-let clojure.core/if-not clojure.core/if-some clojure.core/when clojure.core/when-first clojure.core/when-let clojure.core/when-not clojure.core/when-some cond cond-> cond->> condp if-let if-not if-some when when-first when-let when-not when-some
-syntax keyword clojureRepeat clojure.core/doseq clojure.core/dotimes clojure.core/while doseq dotimes while
-syntax keyword clojureDefine clojure.core/definline clojure.core/definterface clojure.core/defmacro clojure.core/defmethod clojure.core/defmulti clojure.core/defn clojure.core/defn- clojure.core/defonce clojure.core/defprotocol clojure.core/defrecord clojure.core/defstruct clojure.core/deftype definline definterface defmacro defmethod defmulti defn defn- defonce defprotocol defrecord defstruct deftype
-syntax keyword clojureMacro -> ->> .. amap and areduce as-> assert binding bound-fn clojure.core/-> clojure.core/->> clojure.core/.. clojure.core/amap clojure.core/and clojure.core/areduce clojure.core/as-> clojure.core/assert clojure.core/binding clojure.core/bound-fn clojure.core/comment clojure.core/declare clojure.core/delay clojure.core/dosync clojure.core/doto clojure.core/extend-protocol clojure.core/extend-type clojure.core/for clojure.core/future clojure.core/gen-class clojure.core/gen-interface clojure.core/import clojure.core/io! clojure.core/lazy-cat clojure.core/lazy-seq clojure.core/letfn clojure.core/locking clojure.core/memfn clojure.core/ns clojure.core/or clojure.core/proxy clojure.core/proxy-super clojure.core/pvalues clojure.core/refer-clojure clojure.core/reify clojure.core/some-> clojure.core/some->> clojure.core/sync clojure.core/time clojure.core/with-bindings clojure.core/with-in-str clojure.core/with-loading-context clojure.core/with-local-vars clojure.core/with-open clojure.core/with-out-str clojure.core/with-precision clojure.core/with-redefs comment declare delay dosync doto extend-protocol extend-type for future gen-class gen-interface import io! lazy-cat lazy-seq letfn locking memfn ns or proxy proxy-super pvalues refer-clojure reify some-> some->> sync time with-bindings with-in-str with-loading-context with-local-vars with-open with-out-str with-precision with-redefs
-syntax keyword clojureFunc * *' + +' - -' ->ArrayChunk ->Vec ->VecNode ->VecSeq -cache-protocol-fn -reset-methods / < <= = == > >= accessor aclone add-classpath add-watch agent agent-error agent-errors aget alength alias all-ns alter alter-meta! alter-var-root ancestors apply array-map aset aset-boolean aset-byte aset-char aset-double aset-float aset-int aset-long aset-short assoc assoc! assoc-in associative? atom await await-for await1 bases bean bigdec bigint biginteger 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? butlast byte byte-array bytes cast char char-array char? chars chunk chunk-append chunk-buffer chunk-cons chunk-first chunk-next chunk-rest chunked-seq? class class? clear-agent-errors clojure-version clojure.core/* clojure.core/*' clojure.core/+ clojure.core/+' clojure.core/- clojure.core/-' clojure.core/->ArrayChunk clojure.core/->Vec clojure.core/->VecNode clojure.core/->VecSeq clojure.core/-cache-protocol-fn clojure.core/-reset-methods clojure.core// clojure.core/< clojure.core/<= clojure.core/= clojure.core/== clojure.core/> clojure.core/>= clojure.core/accessor clojure.core/aclone clojure.core/add-classpath clojure.core/add-watch clojure.core/agent clojure.core/agent-error clojure.core/agent-errors clojure.core/aget clojure.core/alength clojure.core/alias clojure.core/all-ns clojure.core/alter clojure.core/alter-meta! clojure.core/alter-var-root clojure.core/ancestors clojure.core/apply clojure.core/array-map clojure.core/aset clojure.core/aset-boolean clojure.core/aset-byte clojure.core/aset-char clojure.core/aset-double clojure.core/aset-float clojure.core/aset-int clojure.core/aset-long clojure.core/aset-short clojure.core/assoc clojure.core/assoc! clojure.core/assoc-in clojure.core/associative? clojure.core/atom clojure.core/await clojure.core/await-for clojure.core/await1 clojure.core/bases clojure.core/bean clojure.core/bigdec clojure.core/bigint clojure.core/biginteger clojure.core/bit-and clojure.core/bit-and-not clojure.core/bit-clear clojure.core/bit-flip clojure.core/bit-not clojure.core/bit-or clojure.core/bit-set clojure.core/bit-shift-left clojure.core/bit-shift-right clojure.core/bit-test clojure.core/bit-xor clojure.core/boolean clojure.core/boolean-array clojure.core/booleans clojure.core/bound-fn* clojure.core/bound? clojure.core/butlast clojure.core/byte clojure.core/byte-array clojure.core/bytes clojure.core/cast clojure.core/char clojure.core/char-array clojure.core/char? clojure.core/chars clojure.core/chunk clojure.core/chunk-append clojure.core/chunk-buffer clojure.core/chunk-cons clojure.core/chunk-first clojure.core/chunk-next clojure.core/chunk-rest clojure.core/chunked-seq? clojure.core/class clojure.core/class? clojure.core/clear-agent-errors clojure.core/clojure-version clojure.core/coll? clojure.core/commute clojure.core/comp clojure.core/comparator clojure.core/compare clojure.core/compare-and-set! clojure.core/compile clojure.core/complement clojure.core/concat clojure.core/conj clojure.core/conj! clojure.core/cons clojure.core/constantly clojure.core/construct-proxy clojure.core/contains? clojure.core/count clojure.core/counted? clojure.core/create-ns clojure.core/create-struct clojure.core/cycle clojure.core/dec clojure.core/dec' clojure.core/decimal? clojure.core/delay? clojure.core/deliver clojure.core/denominator clojure.core/deref clojure.core/derive clojure.core/descendants clojure.core/destructure clojure.core/disj clojure.core/disj! clojure.core/dissoc clojure.core/dissoc! clojure.core/distinct clojure.core/distinct? clojure.core/doall clojure.core/dorun clojure.core/double clojure.core/double-array clojure.core/doubles clojure.core/drop clojure.core/drop-last clojure.core/drop-while clojure.core/empty clojure.core/empty? clojure.core/ensure clojure.core/enumeration-seq clojure.core/error-handler clojure.core/error-mode clojure.core/eval clojure.core/even? clojure.core/every-pred clojure.core/every? clojure.core/ex-data clojure.core/ex-info clojure.core/extend clojure.core/extenders clojure.core/extends? clojure.core/false? clojure.core/ffirst clojure.core/file-seq clojure.core/filter clojure.core/filterv clojure.core/find clojure.core/find-keyword clojure.core/find-ns clojure.core/find-protocol-impl clojure.core/find-protocol-method clojure.core/find-var clojure.core/first clojure.core/flatten clojure.core/float clojure.core/float-array clojure.core/float? clojure.core/floats clojure.core/flush clojure.core/fn? clojure.core/fnext clojure.core/fnil clojure.core/force clojure.core/format clojure.core/frequencies clojure.core/future-call clojure.core/future-cancel clojure.core/future-cancelled? clojure.core/future-done? clojure.core/future? clojure.core/gensym clojure.core/get clojure.core/get-in clojure.core/get-method clojure.core/get-proxy-class clojure.core/get-thread-bindings clojure.core/get-validator clojure.core/group-by clojure.core/hash clojure.core/hash-combine clojure.core/hash-map clojure.core/hash-ordered-coll clojure.core/hash-set clojure.core/hash-unordered-coll clojure.core/identical? clojure.core/identity clojure.core/ifn? clojure.core/in-ns clojure.core/inc clojure.core/inc' clojure.core/init-proxy clojure.core/instance? clojure.core/int clojure.core/int-array clojure.core/integer? clojure.core/interleave clojure.core/intern clojure.core/interpose clojure.core/into clojure.core/into-array clojure.core/ints clojure.core/isa? clojure.core/iterate clojure.core/iterator-seq clojure.core/juxt clojure.core/keep clojure.core/keep-indexed clojure.core/key clojure.core/keys clojure.core/keyword clojure.core/keyword? clojure.core/last clojure.core/line-seq clojure.core/list clojure.core/list* clojure.core/list? clojure.core/load clojure.core/load-file clojure.core/load-reader clojure.core/load-string clojure.core/loaded-libs clojure.core/long clojure.core/long-array clojure.core/longs clojure.core/macroexpand clojure.core/macroexpand-1 clojure.core/make-array clojure.core/make-hierarchy clojure.core/map clojure.core/map-indexed clojure.core/map? clojure.core/mapcat clojure.core/mapv clojure.core/max clojure.core/max-key clojure.core/memoize clojure.core/merge clojure.core/merge-with clojure.core/meta clojure.core/method-sig clojure.core/methods clojure.core/min clojure.core/min-key clojure.core/mix-collection-hash clojure.core/mod clojure.core/munge clojure.core/name clojure.core/namespace clojure.core/namespace-munge clojure.core/neg? clojure.core/newline clojure.core/next clojure.core/nfirst clojure.core/nil? clojure.core/nnext clojure.core/not clojure.core/not-any? clojure.core/not-empty clojure.core/not-every? clojure.core/not= clojure.core/ns-aliases clojure.core/ns-imports clojure.core/ns-interns clojure.core/ns-map clojure.core/ns-name clojure.core/ns-publics clojure.core/ns-refers clojure.core/ns-resolve clojure.core/ns-unalias clojure.core/ns-unmap clojure.core/nth clojure.core/nthnext clojure.core/nthrest clojure.core/num clojure.core/number? clojure.core/numerator clojure.core/object-array clojure.core/odd? clojure.core/parents clojure.core/partial clojure.core/partition clojure.core/partition-all clojure.core/partition-by clojure.core/pcalls clojure.core/peek clojure.core/persistent! clojure.core/pmap clojure.core/pop clojure.core/pop! clojure.core/pop-thread-bindings clojure.core/pos? clojure.core/pr clojure.core/pr-str clojure.core/prefer-method clojure.core/prefers clojure.core/print clojure.core/print-ctor clojure.core/print-dup clojure.core/print-method clojure.core/print-simple clojure.core/print-str clojure.core/printf clojure.core/println clojure.core/println-str clojure.core/prn clojure.core/prn-str clojure.core/promise clojure.core/proxy-call-with-super clojure.core/proxy-mappings clojure.core/proxy-name clojure.core/push-thread-bindings clojure.core/quot clojure.core/rand clojure.core/rand-int clojure.core/rand-nth clojure.core/range clojure.core/ratio? clojure.core/rational? clojure.core/rationalize clojure.core/re-find clojure.core/re-groups clojure.core/re-matcher clojure.core/re-matches clojure.core/re-pattern clojure.core/re-seq clojure.core/read clojure.core/read-line clojure.core/read-string clojure.core/realized? clojure.core/record? clojure.core/reduce clojure.core/reduce-kv clojure.core/reduced clojure.core/reduced? clojure.core/reductions clojure.core/ref clojure.core/ref-history-count clojure.core/ref-max-history clojure.core/ref-min-history clojure.core/ref-set clojure.core/refer clojure.core/release-pending-sends clojure.core/rem clojure.core/remove clojure.core/remove-all-methods clojure.core/remove-method clojure.core/remove-ns clojure.core/remove-watch clojure.core/repeat clojure.core/repeatedly clojure.core/replace clojure.core/replicate clojure.core/require clojure.core/reset! clojure.core/reset-meta! clojure.core/resolve clojure.core/rest clojure.core/restart-agent clojure.core/resultset-seq clojure.core/reverse clojure.core/reversible? clojure.core/rseq clojure.core/rsubseq clojure.core/satisfies? clojure.core/second clojure.core/select-keys clojure.core/send clojure.core/send-off clojure.core/send-via clojure.core/seq clojure.core/seq? clojure.core/seque clojure.core/sequence clojure.core/sequential? clojure.core/set clojure.core/set-agent-send-executor! clojure.core/set-agent-send-off-executor! clojure.core/set-error-handler! clojure.core/set-error-mode! clojure.core/set-validator! clojure.core/set? clojure.core/short clojure.core/short-array clojure.core/shorts clojure.core/shuffle clojure.core/shutdown-agents clojure.core/slurp clojure.core/some clojure.core/some-fn clojure.core/some? clojure.core/sort clojure.core/sort-by clojure.core/sorted-map clojure.core/sorted-map-by clojure.core/sorted-set clojure.core/sorted-set-by clojure.core/sorted? clojure.core/special-symbol? clojure.core/spit clojure.core/split-at clojure.core/split-with clojure.core/str clojure.core/string? clojure.core/struct clojure.core/struct-map clojure.core/subs clojure.core/subseq clojure.core/subvec clojure.core/supers clojure.core/swap! clojure.core/symbol clojure.core/symbol? clojure.core/take clojure.core/take-last clojure.core/take-nth clojure.core/take-while clojure.core/test clojure.core/the-ns clojure.core/thread-bound? clojure.core/to-array clojure.core/to-array-2d clojure.core/trampoline clojure.core/transient clojure.core/tree-seq clojure.core/true? clojure.core/type clojure.core/unchecked-add clojure.core/unchecked-add-int clojure.core/unchecked-byte clojure.core/unchecked-char clojure.core/unchecked-dec clojure.core/unchecked-dec-int clojure.core/unchecked-divide-int clojure.core/unchecked-double clojure.core/unchecked-float clojure.core/unchecked-inc clojure.core/unchecked-inc-int clojure.core/unchecked-int clojure.core/unchecked-long clojure.core/unchecked-multiply clojure.core/unchecked-multiply-int clojure.core/unchecked-negate clojure.core/unchecked-negate-int clojure.core/unchecked-remainder-int clojure.core/unchecked-short clojure.core/unchecked-subtract clojure.core/unchecked-subtract-int clojure.core/underive clojure.core/unsigned-bit-shift-right clojure.core/update-in clojure.core/update-proxy clojure.core/use clojure.core/val clojure.core/vals clojure.core/var-get clojure.core/var-set clojure.core/var? clojure.core/vary-meta clojure.core/vec clojure.core/vector clojure.core/vector-of clojure.core/vector? clojure.core/with-bindings* clojure.core/with-meta clojure.core/with-redefs-fn clojure.core/xml-seq clojure.core/zero? clojure.core/zipmap coll? commute comp comparator compare compare-and-set! compile complement concat conj conj! cons constantly construct-proxy contains? count counted? create-ns create-struct cycle dec dec' decimal? delay? deliver denominator deref derive descendants destructure disj disj! dissoc dissoc! distinct distinct? doall dorun 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 extenders extends? false? ffirst file-seq filter filterv find find-keyword find-ns find-protocol-impl find-protocol-method find-var first flatten float float-array float? floats flush fn? fnext fnil force format frequencies future-call future-cancel future-cancelled? future-done? future? 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 ifn? in-ns inc inc' init-proxy instance? int int-array integer? interleave intern interpose into into-array ints isa? iterate iterator-seq juxt keep keep-indexed key keys keyword keyword? last line-seq list list* list? load load-file load-reader load-string loaded-libs long long-array longs macroexpand macroexpand-1 make-array make-hierarchy map map-indexed map? mapcat mapv max max-key memoize merge merge-with meta method-sig methods min min-key mix-collection-hash mod munge name namespace namespace-munge neg? newline next nfirst nil? nnext not not-any? not-empty not-every? not= 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? parents partial partition partition-all partition-by pcalls peek persistent! pmap pop pop! pop-thread-bindings pos? pr pr-str prefer-method prefers print print-ctor print-dup print-method print-simple print-str printf println println-str prn prn-str promise proxy-call-with-super proxy-mappings proxy-name push-thread-bindings quot 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? reduce reduce-kv reduced reduced? reductions ref ref-history-count ref-max-history ref-min-history ref-set refer 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-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-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? take take-last take-nth take-while test the-ns thread-bound? to-array to-array-2d trampoline transient tree-seq true? 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 unsigned-bit-shift-right update-in update-proxy use val vals var-get var-set var? vary-meta vec vector vector-of vector? with-bindings* with-meta with-redefs-fn xml-seq zero? zipmap
-syntax keyword clojureVariable *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* EMPTY-NODE char-escape-string char-name-string clojure.core/*1 clojure.core/*2 clojure.core/*3 clojure.core/*agent* clojure.core/*allow-unresolved-vars* clojure.core/*assert* clojure.core/*clojure-version* clojure.core/*command-line-args* clojure.core/*compile-files* clojure.core/*compile-path* clojure.core/*compiler-options* clojure.core/*data-readers* clojure.core/*default-data-reader-fn* clojure.core/*e clojure.core/*err* clojure.core/*file* clojure.core/*flush-on-newline* clojure.core/*fn-loader* clojure.core/*in* clojure.core/*math-context* clojure.core/*ns* clojure.core/*out* clojure.core/*print-dup* clojure.core/*print-length* clojure.core/*print-level* clojure.core/*print-meta* clojure.core/*print-readably* clojure.core/*read-eval* clojure.core/*source-path* clojure.core/*unchecked-math* clojure.core/*use-context-classloader* clojure.core/*verbose-defrecords* clojure.core/*warn-on-reflection* clojure.core/EMPTY-NODE clojure.core/char-escape-string clojure.core/char-name-string clojure.core/default-data-readers clojure.core/primitives-classnames clojure.core/unquote clojure.core/unquote-splicing default-data-readers primitives-classnames unquote unquote-splicing
+" 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:clojure_syntax_keywords = {
+ \ 'clojureBoolean': ["false","true"]
+ \ , 'clojureCond': ["case","clojure.core/case","clojure.core/cond","clojure.core/cond->","clojure.core/cond->>","clojure.core/condp","clojure.core/if-let","clojure.core/if-not","clojure.core/if-some","clojure.core/when","clojure.core/when-first","clojure.core/when-let","clojure.core/when-not","clojure.core/when-some","cond","cond->","cond->>","condp","if-let","if-not","if-some","when","when-first","when-let","when-not","when-some"]
+ \ , 'clojureConstant': ["nil"]
+ \ , 'clojureDefine': ["clojure.core/definline","clojure.core/definterface","clojure.core/defmacro","clojure.core/defmethod","clojure.core/defmulti","clojure.core/defn","clojure.core/defn-","clojure.core/defonce","clojure.core/defprotocol","clojure.core/defrecord","clojure.core/defstruct","clojure.core/deftype","definline","definterface","defmacro","defmethod","defmulti","defn","defn-","defonce","defprotocol","defrecord","defstruct","deftype"]
+ \ , 'clojureException': ["catch","finally","throw","try"]
+ \ , 'clojureFunc': ["*","*'","+","+'","-","-'","->ArrayChunk","->Eduction","->Vec","->VecNode","->VecSeq","-cache-protocol-fn","-reset-methods","/","<","<=","=","==",">",">=","Throwable->map","accessor","aclone","add-classpath","add-watch","agent","agent-error","agent-errors","aget","alength","alias","all-ns","alter","alter-meta!","alter-var-root","ancestors","apply","array-map","aset","aset-boolean","aset-byte","aset-char","aset-double","aset-float","aset-int","aset-long","aset-short","assoc","assoc!","assoc-in","associative?","atom","await","await-for","await1","bases","bean","bigdec","bigint","biginteger","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?","butlast","byte","byte-array","bytes","cast","cat","char","char-array","char?","chars","chunk","chunk-append","chunk-buffer","chunk-cons","chunk-first","chunk-next","chunk-rest","chunked-seq?","class","class?","clear-agent-errors","clojure-version","clojure.core/*","clojure.core/*'","clojure.core/+","clojure.core/+'","clojure.core/-","clojure.core/-'","clojure.core/->ArrayChunk","clojure.core/->Eduction","clojure.core/->Vec","clojure.core/->VecNode","clojure.core/->VecSeq","clojure.core/-cache-protocol-fn","clojure.core/-reset-methods","clojure.core//","clojure.core/<","clojure.core/<=","clojure.core/=","clojure.core/==","clojure.core/>","clojure.core/>=","clojure.core/Throwable->map","clojure.core/accessor","clojure.core/aclone","clojure.core/add-classpath","clojure.core/add-watch","clojure.core/agent","clojure.core/agent-error","clojure.core/agent-errors","clojure.core/aget","clojure.core/alength","clojure.core/alias","clojure.core/all-ns","clojure.core/alter","clojure.core/alter-meta!","clojure.core/alter-var-root","clojure.core/ancestors","clojure.core/apply","clojure.core/array-map","clojure.core/aset","clojure.core/aset-boolean","clojure.core/aset-byte","clojure.core/aset-char","clojure.core/aset-double","clojure.core/aset-float","clojure.core/aset-int","clojure.core/aset-long","clojure.core/aset-short","clojure.core/assoc","clojure.core/assoc!","clojure.core/assoc-in","clojure.core/associative?","clojure.core/atom","clojure.core/await","clojure.core/await-for","clojure.core/await1","clojure.core/bases","clojure.core/bean","clojure.core/bigdec","clojure.core/bigint","clojure.core/biginteger","clojure.core/bit-and","clojure.core/bit-and-not","clojure.core/bit-clear","clojure.core/bit-flip","clojure.core/bit-not","clojure.core/bit-or","clojure.core/bit-set","clojure.core/bit-shift-left","clojure.core/bit-shift-right","clojure.core/bit-test","clojure.core/bit-xor","clojure.core/boolean","clojure.core/boolean-array","clojure.core/booleans","clojure.core/bound-fn*","clojure.core/bound?","clojure.core/butlast","clojure.core/byte","clojure.core/byte-array","clojure.core/bytes","clojure.core/cast","clojure.core/cat","clojure.core/char","clojure.core/char-array","clojure.core/char?","clojure.core/chars","clojure.core/chunk","clojure.core/chunk-append","clojure.core/chunk-buffer","clojure.core/chunk-cons","clojure.core/chunk-first","clojure.core/chunk-next","clojure.core/chunk-rest","clojure.core/chunked-seq?","clojure.core/class","clojure.core/class?","clojure.core/clear-agent-errors","clojure.core/clojure-version","clojure.core/coll?","clojure.core/commute","clojure.core/comp","clojure.core/comparator","clojure.core/compare","clojure.core/compare-and-set!","clojure.core/compile","clojure.core/complement","clojure.core/completing","clojure.core/concat","clojure.core/conj","clojure.core/conj!","clojure.core/cons","clojure.core/constantly","clojure.core/construct-proxy","clojure.core/contains?","clojure.core/count","clojure.core/counted?","clojure.core/create-ns","clojure.core/create-struct","clojure.core/cycle","clojure.core/dec","clojure.core/dec'","clojure.core/decimal?","clojure.core/dedupe","clojure.core/delay?","clojure.core/deliver","clojure.core/denominator","clojure.core/deref","clojure.core/derive","clojure.core/descendants","clojure.core/destructure","clojure.core/disj","clojure.core/disj!","clojure.core/dissoc","clojure.core/dissoc!","clojure.core/distinct","clojure.core/distinct?","clojure.core/doall","clojure.core/dorun","clojure.core/double","clojure.core/double-array","clojure.core/doubles","clojure.core/drop","clojure.core/drop-last","clojure.core/drop-while","clojure.core/eduction","clojure.core/empty","clojure.core/empty?","clojure.core/ensure","clojure.core/ensure-reduced","clojure.core/enumeration-seq","clojure.core/error-handler","clojure.core/error-mode","clojure.core/eval","clojure.core/even?","clojure.core/every-pred","clojure.core/every?","clojure.core/ex-data","clojure.core/ex-info","clojure.core/extend","clojure.core/extenders","clojure.core/extends?","clojure.core/false?","clojure.core/ffirst","clojure.core/file-seq","clojure.core/filter","clojure.core/filterv","clojure.core/find","clojure.core/find-keyword","clojure.core/find-ns","clojure.core/find-protocol-impl","clojure.core/find-protocol-method","clojure.core/find-var","clojure.core/first","clojure.core/flatten","clojure.core/float","clojure.core/float-array","clojure.core/float?","clojure.core/floats","clojure.core/flush","clojure.core/fn?","clojure.core/fnext","clojure.core/fnil","clojure.core/force","clojure.core/format","clojure.core/frequencies","clojure.core/future-call","clojure.core/future-cancel","clojure.core/future-cancelled?","clojure.core/future-done?","clojure.core/future?","clojure.core/gensym","clojure.core/get","clojure.core/get-in","clojure.core/get-method","clojure.core/get-proxy-class","clojure.core/get-thread-bindings","clojure.core/get-validator","clojure.core/group-by","clojure.core/hash","clojure.core/hash-combine","clojure.core/hash-map","clojure.core/hash-ordered-coll","clojure.core/hash-set","clojure.core/hash-unordered-coll","clojure.core/identical?","clojure.core/identity","clojure.core/ifn?","clojure.core/in-ns","clojure.core/inc","clojure.core/inc'","clojure.core/init-proxy","clojure.core/instance?","clojure.core/int","clojure.core/int-array","clojure.core/integer?","clojure.core/interleave","clojure.core/intern","clojure.core/interpose","clojure.core/into","clojure.core/into-array","clojure.core/ints","clojure.core/isa?","clojure.core/iterate","clojure.core/iterator-seq","clojure.core/juxt","clojure.core/keep","clojure.core/keep-indexed","clojure.core/key","clojure.core/keys","clojure.core/keyword","clojure.core/keyword?","clojure.core/last","clojure.core/line-seq","clojure.core/list","clojure.core/list*","clojure.core/list?","clojure.core/load","clojure.core/load-file","clojure.core/load-reader","clojure.core/load-string","clojure.core/loaded-libs","clojure.core/long","clojure.core/long-array","clojure.core/longs","clojure.core/macroexpand","clojure.core/macroexpand-1","clojure.core/make-array","clojure.core/make-hierarchy","clojure.core/map","clojure.core/map-entry?","clojure.core/map-indexed","clojure.core/map?","clojure.core/mapcat","clojure.core/mapv","clojure.core/max","clojure.core/max-key","clojure.core/memoize","clojure.core/merge","clojure.core/merge-with","clojure.core/meta","clojure.core/method-sig","clojure.core/methods","clojure.core/min","clojure.core/min-key","clojure.core/mix-collection-hash","clojure.core/mod","clojure.core/munge","clojure.core/name","clojure.core/namespace","clojure.core/namespace-munge","clojure.core/neg?","clojure.core/newline","clojure.core/next","clojure.core/nfirst","clojure.core/nil?","clojure.core/nnext","clojure.core/not","clojure.core/not-any?","clojure.core/not-empty","clojure.core/not-every?","clojure.core/not=","clojure.core/ns-aliases","clojure.core/ns-imports","clojure.core/ns-interns","clojure.core/ns-map","clojure.core/ns-name","clojure.core/ns-publics","clojure.core/ns-refers","clojure.core/ns-resolve","clojure.core/ns-unalias","clojure.core/ns-unmap","clojure.core/nth","clojure.core/nthnext","clojure.core/nthrest","clojure.core/num","clojure.core/number?","clojure.core/numerator","clojure.core/object-array","clojure.core/odd?","clojure.core/parents","clojure.core/partial","clojure.core/partition","clojure.core/partition-all","clojure.core/partition-by","clojure.core/pcalls","clojure.core/peek","clojure.core/persistent!","clojure.core/pmap","clojure.core/pop","clojure.core/pop!","clojure.core/pop-thread-bindings","clojure.core/pos?","clojure.core/pr","clojure.core/pr-str","clojure.core/prefer-method","clojure.core/prefers","clojure.core/print","clojure.core/print-ctor","clojure.core/print-dup","clojure.core/print-method","clojure.core/print-simple","clojure.core/print-str","clojure.core/printf","clojure.core/println","clojure.core/println-str","clojure.core/prn","clojure.core/prn-str","clojure.core/promise","clojure.core/proxy-call-with-super","clojure.core/proxy-mappings","clojure.core/proxy-name","clojure.core/push-thread-bindings","clojure.core/quot","clojure.core/rand","clojure.core/rand-int","clojure.core/rand-nth","clojure.core/random-sample","clojure.core/range","clojure.core/ratio?","clojure.core/rational?","clojure.core/rationalize","clojure.core/re-find","clojure.core/re-groups","clojure.core/re-matcher","clojure.core/re-matches","clojure.core/re-pattern","clojure.core/re-seq","clojure.core/read","clojure.core/read-line","clojure.core/read-string","clojure.core/reader-conditional","clojure.core/reader-conditional?","clojure.core/realized?","clojure.core/record?","clojure.core/reduce","clojure.core/reduce-kv","clojure.core/reduced","clojure.core/reduced?","clojure.core/reductions","clojure.core/ref","clojure.core/ref-history-count","clojure.core/ref-max-history","clojure.core/ref-min-history","clojure.core/ref-set","clojure.core/refer","clojure.core/release-pending-sends","clojure.core/rem","clojure.core/remove","clojure.core/remove-all-methods","clojure.core/remove-method","clojure.core/remove-ns","clojure.core/remove-watch","clojure.core/repeat","clojure.core/repeatedly","clojure.core/replace","clojure.core/replicate","clojure.core/require","clojure.core/reset!","clojure.core/reset-meta!","clojure.core/resolve","clojure.core/rest","clojure.core/restart-agent","clojure.core/resultset-seq","clojure.core/reverse","clojure.core/reversible?","clojure.core/rseq","clojure.core/rsubseq","clojure.core/run!","clojure.core/satisfies?","clojure.core/second","clojure.core/select-keys","clojure.core/send","clojure.core/send-off","clojure.core/send-via","clojure.core/seq","clojure.core/seq?","clojure.core/seque","clojure.core/sequence","clojure.core/sequential?","clojure.core/set","clojure.core/set-agent-send-executor!","clojure.core/set-agent-send-off-executor!","clojure.core/set-error-handler!","clojure.core/set-error-mode!","clojure.core/set-validator!","clojure.core/set?","clojure.core/short","clojure.core/short-array","clojure.core/shorts","clojure.core/shuffle","clojure.core/shutdown-agents","clojure.core/slurp","clojure.core/some","clojure.core/some-fn","clojure.core/some?","clojure.core/sort","clojure.core/sort-by","clojure.core/sorted-map","clojure.core/sorted-map-by","clojure.core/sorted-set","clojure.core/sorted-set-by","clojure.core/sorted?","clojure.core/special-symbol?","clojure.core/spit","clojure.core/split-at","clojure.core/split-with","clojure.core/str","clojure.core/string?","clojure.core/struct","clojure.core/struct-map","clojure.core/subs","clojure.core/subseq","clojure.core/subvec","clojure.core/supers","clojure.core/swap!","clojure.core/symbol","clojure.core/symbol?","clojure.core/tagged-literal","clojure.core/tagged-literal?","clojure.core/take","clojure.core/take-last","clojure.core/take-nth","clojure.core/take-while","clojure.core/test","clojure.core/the-ns","clojure.core/thread-bound?","clojure.core/to-array","clojure.core/to-array-2d","clojure.core/trampoline","clojure.core/transduce","clojure.core/transient","clojure.core/tree-seq","clojure.core/true?","clojure.core/type","clojure.core/unchecked-add","clojure.core/unchecked-add-int","clojure.core/unchecked-byte","clojure.core/unchecked-char","clojure.core/unchecked-dec","clojure.core/unchecked-dec-int","clojure.core/unchecked-divide-int","clojure.core/unchecked-double","clojure.core/unchecked-float","clojure.core/unchecked-inc","clojure.core/unchecked-inc-int","clojure.core/unchecked-int","clojure.core/unchecked-long","clojure.core/unchecked-multiply","clojure.core/unchecked-multiply-int","clojure.core/unchecked-negate","clojure.core/unchecked-negate-int","clojure.core/unchecked-remainder-int","clojure.core/unchecked-short","clojure.core/unchecked-subtract","clojure.core/unchecked-subtract-int","clojure.core/underive","clojure.core/unreduced","clojure.core/unsigned-bit-shift-right","clojure.core/update","clojure.core/update-in","clojure.core/update-proxy","clojure.core/use","clojure.core/val","clojure.core/vals","clojure.core/var-get","clojure.core/var-set","clojure.core/var?","clojure.core/vary-meta","clojure.core/vec","clojure.core/vector","clojure.core/vector-of","clojure.core/vector?","clojure.core/volatile!","clojure.core/volatile?","clojure.core/vreset!","clojure.core/with-bindings*","clojure.core/with-meta","clojure.core/with-redefs-fn","clojure.core/xml-seq","clojure.core/zero?","clojure.core/zipmap","coll?","commute","comp","comparator","compare","compare-and-set!","compile","complement","completing","concat","conj","conj!","cons","constantly","construct-proxy","contains?","count","counted?","create-ns","create-struct","cycle","dec","dec'","decimal?","dedupe","delay?","deliver","denominator","deref","derive","descendants","destructure","disj","disj!","dissoc","dissoc!","distinct","distinct?","doall","dorun","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","extenders","extends?","false?","ffirst","file-seq","filter","filterv","find","find-keyword","find-ns","find-protocol-impl","find-protocol-method","find-var","first","flatten","float","float-array","float?","floats","flush","fn?","fnext","fnil","force","format","frequencies","future-call","future-cancel","future-cancelled?","future-done?","future?","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","ifn?","in-ns","inc","inc'","init-proxy","instance?","int","int-array","integer?","interleave","intern","interpose","into","into-array","ints","isa?","iterate","iterator-seq","juxt","keep","keep-indexed","key","keys","keyword","keyword?","last","line-seq","list","list*","list?","load","load-file","load-reader","load-string","loaded-libs","long","long-array","longs","macroexpand","macroexpand-1","make-array","make-hierarchy","map","map-entry?","map-indexed","map?","mapcat","mapv","max","max-key","memoize","merge","merge-with","meta","method-sig","methods","min","min-key","mix-collection-hash","mod","munge","name","namespace","namespace-munge","neg?","newline","next","nfirst","nil?","nnext","not","not-any?","not-empty","not-every?","not=","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?","parents","partial","partition","partition-all","partition-by","pcalls","peek","persistent!","pmap","pop","pop!","pop-thread-bindings","pos?","pr","pr-str","prefer-method","prefers","print","print-ctor","print-dup","print-method","print-simple","print-str","printf","println","println-str","prn","prn-str","promise","proxy-call-with-super","proxy-mappings","proxy-name","push-thread-bindings","quot","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?","reduce","reduce-kv","reduced","reduced?","reductions","ref","ref-history-count","ref-max-history","ref-min-history","ref-set","refer","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-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-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?","tagged-literal","tagged-literal?","take","take-last","take-nth","take-while","test","the-ns","thread-bound?","to-array","to-array-2d","trampoline","transduce","transient","tree-seq","true?","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","unreduced","unsigned-bit-shift-right","update","update-in","update-proxy","use","val","vals","var-get","var-set","var?","vary-meta","vec","vector","vector-of","vector?","volatile!","volatile?","vreset!","with-bindings*","with-meta","with-redefs-fn","xml-seq","zero?","zipmap"]
+ \ , 'clojureMacro': ["->","->>","..","amap","and","areduce","as->","assert","binding","bound-fn","clojure.core/->","clojure.core/->>","clojure.core/..","clojure.core/amap","clojure.core/and","clojure.core/areduce","clojure.core/as->","clojure.core/assert","clojure.core/binding","clojure.core/bound-fn","clojure.core/comment","clojure.core/declare","clojure.core/delay","clojure.core/dosync","clojure.core/doto","clojure.core/extend-protocol","clojure.core/extend-type","clojure.core/for","clojure.core/future","clojure.core/gen-class","clojure.core/gen-interface","clojure.core/import","clojure.core/io!","clojure.core/lazy-cat","clojure.core/lazy-seq","clojure.core/letfn","clojure.core/locking","clojure.core/memfn","clojure.core/ns","clojure.core/or","clojure.core/proxy","clojure.core/proxy-super","clojure.core/pvalues","clojure.core/refer-clojure","clojure.core/reify","clojure.core/some->","clojure.core/some->>","clojure.core/sync","clojure.core/time","clojure.core/vswap!","clojure.core/with-bindings","clojure.core/with-in-str","clojure.core/with-loading-context","clojure.core/with-local-vars","clojure.core/with-open","clojure.core/with-out-str","clojure.core/with-precision","clojure.core/with-redefs","comment","declare","delay","dosync","doto","extend-protocol","extend-type","for","future","gen-class","gen-interface","import","io!","lazy-cat","lazy-seq","letfn","locking","memfn","ns","or","proxy","proxy-super","pvalues","refer-clojure","reify","some->","some->>","sync","time","vswap!","with-bindings","with-in-str","with-loading-context","with-local-vars","with-open","with-out-str","with-precision","with-redefs"]
+ \ , 'clojureRepeat': ["clojure.core/doseq","clojure.core/dotimes","clojure.core/while","doseq","dotimes","while"]
+ \ , 'clojureSpecial': [".","clojure.core/fn","clojure.core/let","clojure.core/loop","def","do","fn","if","let","loop","monitor-enter","monitor-exit","new","quote","recur","set!","var"]
+ \ , 'clojureVariable': ["*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*","EMPTY-NODE","char-escape-string","char-name-string","clojure.core/*1","clojure.core/*2","clojure.core/*3","clojure.core/*agent*","clojure.core/*allow-unresolved-vars*","clojure.core/*assert*","clojure.core/*clojure-version*","clojure.core/*command-line-args*","clojure.core/*compile-files*","clojure.core/*compile-path*","clojure.core/*compiler-options*","clojure.core/*data-readers*","clojure.core/*default-data-reader-fn*","clojure.core/*e","clojure.core/*err*","clojure.core/*file*","clojure.core/*flush-on-newline*","clojure.core/*fn-loader*","clojure.core/*in*","clojure.core/*math-context*","clojure.core/*ns*","clojure.core/*out*","clojure.core/*print-dup*","clojure.core/*print-length*","clojure.core/*print-level*","clojure.core/*print-meta*","clojure.core/*print-readably*","clojure.core/*read-eval*","clojure.core/*source-path*","clojure.core/*suppress-read*","clojure.core/*unchecked-math*","clojure.core/*use-context-classloader*","clojure.core/*verbose-defrecords*","clojure.core/*warn-on-reflection*","clojure.core/EMPTY-NODE","clojure.core/char-escape-string","clojure.core/char-name-string","clojure.core/default-data-readers","clojure.core/primitives-classnames","clojure.core/unquote","clojure.core/unquote-splicing","default-data-readers","primitives-classnames","unquote","unquote-splicing"]
+ \ }
+
+function! s:syntax_keyword(dict)
+ for key in keys(a:dict)
+ execute 'syntax keyword' key join(a:dict[key], ' ')
+ endfor
+endfunction
+
+if exists('b:clojure_syntax_without_core_keywords') && b:clojure_syntax_without_core_keywords
+ " Only match language specials and primitives
+ for s:key in ['clojureBoolean', 'clojureConstant', 'clojureException', 'clojureSpecial']
+ execute 'syntax keyword' s:key join(s:clojure_syntax_keywords[s:key], ' ')
+ endfor
+else
+ call s:syntax_keyword(s:clojure_syntax_keywords)
+endif
+
+if exists('g:clojure_syntax_keywords')
+ call s:syntax_keyword(g:clojure_syntax_keywords)
+endif
+
+if exists('b:clojure_syntax_keywords')
+ call s:syntax_keyword(b:clojure_syntax_keywords)
+endif
+
+unlet! s:key
+delfunction s:syntax_keyword
" Keywords are symbols:
" static Pattern symbolPat = Pattern.compile("[:]?([\\D&&[^/]].*/)?([\\D&&[^/]][^/]*)");
@@ -43,7 +74,7 @@ syntax match clojureKeyword "\v<:{1,2}%([^ \n\r\t()\[\]{}";@^`~\\%/]+/)*[^ \n\r\
syntax match clojureStringEscape "\v\\%([\\btnfr"]|u\x{4}|[0-3]\o{2}|\o{1,2})" contained
-syntax region clojureString start=/"/ skip=/\\\\\|\\"/ end=/"/ contains=clojureStringEscape,@Spell
+syntax region clojureString matchgroup=clojureStringDelimiter start=/"/ skip=/\\\\\|\\"/ end=/"/ contains=clojureStringEscape,@Spell
syntax match clojureCharacter "\\."
syntax match clojureCharacter "\\o\%([0-3]\o\{2\}\|\o\{1,2\}\)"
@@ -77,7 +108,7 @@ syntax match clojureMeta "\^"
syntax match clojureDeref "@"
syntax match clojureDispatch "\v#[\^'=<_]?"
-" Clojure permits no more than 20 params.
+" Clojure permits no more than 20 anonymous params.
syntax match clojureAnonArg "%\(20\|1\d\|[1-9]\|&\)\?"
syntax match clojureRegexpEscape "\v\\%([\\tnrfae.()\[\]{}^$*?+]|c\u|0[0-3]?\o{1,2}|x%(\x{2}|\{\x{1,6}\})|u\x{4})" contained display
@@ -85,27 +116,27 @@ syntax region clojureRegexpQuoted start=/\\Q/ms=e+1 skip=/\\\\\|\\"/ end=/\\E/me
syntax region clojureRegexpQuote start=/\\Q/ skip=/\\\\\|\\"/ end=/\\E/ end=/"/me=s-1 contains=clojureRegexpQuoted keepend contained
" -*- CHARACTER PROPERTY CLASSES -*-
-" Generated from https://github.com/guns/vim-clojure-static/blob/vim-release-010/clj/src/vim_clojure_static/generate.clj
-" Java version 1.7.0_51
+" Generated from https://github.com/guns/vim-clojure-static/blob/vim-release-011/clj/src/vim_clojure_static/generate.clj
+" Java version 1.8.0_92
syntax match clojureRegexpPosixCharClass "\v\\[pP]\{%(Cntrl|A%(l%(pha|num)|SCII)|Space|Graph|Upper|P%(rint|unct)|Blank|XDigit|Digit|Lower)\}" contained display
syntax match clojureRegexpJavaCharClass "\v\\[pP]\{java%(Whitespace|JavaIdentifier%(Part|Start)|SpaceChar|Mirrored|TitleCase|I%(SOControl|de%(ographic|ntifierIgnorable))|D%(efined|igit)|U%(pperCase|nicodeIdentifier%(Part|Start))|L%(etter%(OrDigit)?|owerCase)|Alphabetic)\}" contained display
-syntax match clojureRegexpUnicodeCharClass "\v\\[pP]\{\cIs%(l%(owercase|etter)|hex%(digit|_digit)|w%(hite%(_space|space)|ord)|noncharacter%(_code_point|codepoint)|p%(rint|unctuation)|ideographic|graph|a%(l%(num|phabetic)|ssigned)|uppercase|titlecase|blank|digit|control)\}" contained display
+syntax match clojureRegexpUnicodeCharClass "\v\\[pP]\{\cIs%(l%(owercase|etter)|hex%(digit|_digit)|w%(hite%(_space|space)|ord)|noncharacter%(_code_point|codepoint)|p%(rint|unctuation)|ideographic|graph|a%(l%(num|phabetic)|ssigned)|uppercase|join%(control|_control)|titlecase|blank|digit|control)\}" contained display
syntax match clojureRegexpUnicodeCharClass "\v\\[pP][NSCMZPL]" contained display
syntax match clojureRegexpUnicodeCharClass "\v\\[pP]\{%(N[dlo]?|P[dcifeos]?|C[ncfos]?|M[nce]?|Z[lsp]?|S[mcko]?|L[muCDlto]?)\}" contained display
syntax match clojureRegexpUnicodeCharClass "\v\\[pP]\{%(Is|gc\=|general_category\=)?%(N[dlo]?|P[dcifeos]?|C[ncfos]?|M[nce]?|Z[lsp]?|S[mcko]?|L[muCDlto]?)\}" contained display
-syntax match clojureRegexpUnicodeCharClass "\v\\[pP]\{\c%(Is|sc\=|script\=)%(l%(epc%(ha)?|y%([dc]i%(an)?)|a%(t%(n|in)|na|oo?)|i%(n%(b|ear_b)|mbu?|su))|vaii?|d%(srt|e%(seret|va%(nagari)?))|g%(lag%(olitic)?|eor%(gian)?|oth%(ic)?|re%(k|ek)|u%(j%(arati|r)|r%(u|mukhi)))|u%(gar%(itic)?|nknown)|a%(r%(ab%(ic)?|m%([ni]|enian))|v%(st|estan))|e%(thi%(opic)?|gyp%(tian_hieroglyphs)?)|z%(inh|yyy|zzz)|r%(un%(ic|r)|ejang|jng)|m%(a%(nd%(aic)?|layalam)|lym|y%(anmar|mr)|tei|ong%(olian)?|eetei_mayek)|c%(a%(n%(adian_aboriginal|s)|ri%(an)?)|y%(priot|r%(l|illic))|prt|uneiform|o%(pt%(ic)?|mmon)|h%(er%(okee)?|am))|i%(n%(scriptional_pa%(rthian|hlavi)|herited)|mperial_aramaic|tal)|b%(eng%(ali)?|a%(t%(ak|k)|li%(nese)?|mum?)|ra%(i%(lle)?|h%(mi)?)|opo%(mofo)?|u%(gi%(nese)?|h%(d|id)))|o%(g%(am|ham)|r%(iya|kh|ya)|sma%(nya)?|l%(d_%(south_arabian|persian|italic|turkic)|ck|_chiki))|p%(rti|h%(oenician|li|ag%(s_pa)?|nx))|k%(h%(m%(r|er)|ar%(oshthi)?)|nda|a%(li|n%(a|nada)|takana|yah_li|ithi)|thi)|yi%(ii)?|t%(elu%(gu)?|i%(finagh|b%(t|etan))|ha%(i|a%(na)?)|a%(i_%(le|tham|viet)|g%(alog|b%(anwa)?)|vt|l[ue]|m%(il|l))|fng|glg)|x%(peo|sux)|n%(ew_tai_lue|koo?)|h%(ira%(gana)?|an%([io]|unoo|g%(ul)?)?|ebr%(ew)?)|java%(nese)?|s%(inh%(ala)?|ha%(vian|w)|a%(ur%(ashtra)?|m%(r|aritan)|rb)|y%(r%(c|iac)|lo%(ti_nagri)?)|und%(anese)?))\}" contained display
-syntax match clojureRegexpUnicodeCharClass "\v\\[pP]\{\c%(In|blk\=|block\=)%(javanese|h%(a%(lfwidth%( and fullwidth forms|andfullwidthforms|_and_fullwidth_forms)|n%(unoo|gul%(compatibilityjamo|syllables|jamo%(extended\-[ab])?|_%(syllables|jamo%(_extended_[ab])?|compatibility_jamo)| %(syllables|compatibility jamo|jamo%( extended\-[ab])?))))|i%(ragana|gh%( %(private use surrogates|surrogates)|_%(private_use_surrogates|surrogates)|surrogates|privateusesurrogates))|ebrew)|i%(pa%([ _]extensions|extensions)|deographic%( description characters|_description_characters|descriptioncharacters)|nscriptional%(%([ _]pa%(rthian|hlavi))|pa%(rthian|hlavi))|mperial%(aramaic|[_ ]aramaic))|l%(e%(tterlike%([_ ]symbols|symbols)|pcha)|ow%([_ ]surrogates|surrogates)|i%(mbu|near%(_b_%(ideograms|syllabary)|b%(ideograms|syllabary)| b %(ideograms|syllabary))|su)|a%(tin%(extended%(additional|\-[dacb])| extended%( additional|\-[dacb])|\-1%(supplement| supplement)|_%(extended_%([dcb]|a%(dditional)?)|1_supplement))|o)|y[cd]ian)|b%(u%(ginese|hid)|ra%(hmi|ille%(patterns|[_ ]patterns))|o%(x%([ _]drawing|drawing)|pomofo%([ _]extended|extended)?)|lock%([ _]elements|elements)|yzantine%( musical symbols|musicalsymbols|_musical_symbols)|engali|a%(linese|mum%(supplement|[ _]supplement)?|tak|sic%([ _]latin|latin)))|e%(gyptian%([ _]hieroglyphs|hieroglyphs)|moticons|nclosed%( %(cjk letters and months|ideographic supplement|alphanumeric%( supplement|s))|cjklettersandmonths|_%(ideographic_supplement|alphanumeric%(_supplement|s)|cjk_letters_and_months)|alphanumerics%(upplement)?|ideographicsupplement)|thiopic%(supplement|_%(supplement|extended%(_a)?)| %(supplement|extended%(\-a)?)|extended%(\-a)?)?)|k%(h%(aroshthi|mer%([_ ]symbols|symbols)?)|a%(takana%(_phonetic_extensions|phoneticextensions| phonetic extensions)?|n%(gxi%([_ ]radicals|radicals)|a%(supplement|[ _]supplement)|bun|nada)|ithi|yah%([ _]li|li)))|r%(u%(nic|mi%(numeralsymbols| numeral symbols|_numeral_symbols))|ejang)|n%(umber%(forms|[ _]forms)|ko|ew%(_tai_lue|tailue| tai lue))|m%(iscellaneous%(technical|symbols%(and%(pictographs|arrows))?|mathematicalsymbols\-[ab]| %(technical|mathematical symbols\-[ab]|symbols%( and %(pictographs|arrows))?)|_%(technical|symbols%(_and_%(pictographs|arrows))?|mathematical_symbols_[ab]))|usical%([_ ]symbols|symbols)|eetei%(mayek|[_ ]mayek)|a%(ndaic|hjong%([ _]tiles|tiles)|layalam|thematical%(alphanumericsymbols| %(alphanumeric symbols|operators)|_%(alphanumeric_symbols|operators)|operators))|yanmar%(extended\-a|_extended_a| extended\-a)?|o%(difier%(_tone_letters| tone letters|toneletters)|ngolian))|d%(e%(seret|vanagari%([ _]extended|extended)?)|ingbats|omino%([ _]tiles|tiles))|yi%(syllables|%([_ ]%(syllables|radicals))|radicals|jing%(hexagramsymbols| hexagram symbols|_hexagram_symbols))|s%(havian|mall%( form variants|formvariants|_form_variants)|p%(acing%(_modifier_letters| modifier letters|modifierletters)|ecials)|a%(maritan|urashtra)|u%(p%(erscripts%(_and_subscripts|andsubscripts| and subscripts)|plementa%(ry%(_private_use_area_[ab]|privateusearea\-[ab]| private use area\-[ab])|l%(_%(arrows_[ab]|mathematical_operators|punctuation)| %(mathematical operators|punctuation|arrows\-[ab])|mathematicaloperators|punctuation|arrows\-[ab])))|rrogates_area|ndanese)|inhala|y%(riac|loti%([_ ]nagri|nagri)))|p%(h%(o%(enician|netic%( extensions%( supplement)?|extensions%(supplement)?|_extensions%(_supplement)?))|a%(istos%([ _]disc|disc)|gs[_\-]pa))|laying%(cards|[_ ]cards)|rivate%(usearea| use area|_use_area))|o%(smanya|l%([ _]chiki|d%( %(south arabian|persian|italic|turkic)|southarabian|_%(south_arabian|persian|italic|turkic)|persian|italic|turkic)|chiki)|riya|ptical%( character recognition|_character_recognition|characterrecognition)|gham)|g%(u%(jarati|rmukhi)|othic|lagolitic|e%(o%(rgian%(supplement|[ _]supplement)?|metric%(shapes|[ _]shapes))|neral%([_ ]punctuation|punctuation))|reek%( %(and coptic|extended)|andcoptic|_extended|extended)?)|c%(o%(ntrol%(pictures|[ _]pictures)|m%(bining%(diacriticalmarks%(supplement|forsymbols)?|halfmarks| %(diacritical marks%( %(supplement|for symbols))?|half marks|marks for symbols)|marksforsymbols|_%(marks_for_symbols|half_marks|diacritical_marks%(_supplement)?))|mon%(_indic_number_forms|indicnumberforms| indic number forms))|ptic|unting%( rod numerals|_rod_numerals|rodnumerals))|y%(rillic%(extended\-[ab]|_%(extended_[ab]|supplementary)|supplement%(ary)?| %(extended\-[ab]|supplement%(ary)?))?|priot%(syllabary|[ _]syllabary))|u%(rrency%([_ ]symbols|symbols)|neiform%(_numbers_and_punctuation|numbersandpunctuation| numbers and punctuation)?)|arian|h%(erokee|am)|jk%(s%(ymbolsandpunctuation|trokes)|compatibility%(forms|ideographs%(supplement)?)?|radicalssupplement| %(compatibility%( %(ideographs%( supplement)?|forms))?|radicals supplement|unified ideographs%( extension [dacb])?|s%(ymbols and punctuation|trokes))|_%(s%(trokes|ymbols_and_punctuation)|radicals_supplement|compatibility%(_%(forms|ideographs%(_supplement)?))?|unified_ideographs%(_extension_[dacb])?)|unifiedideographs%(extension[dacb])?))|t%(i%(betan|finagh)|elugu|a%(mil|i%(xuanjingsymbols|_%(le|xuan_jing_symbols|tham|viet)|le| %(xuan jing symbols|le|tham|viet)|tham|viet)|g%(alog|s|banwa))|ransport%( and map symbols|_and_map_symbols|andmapsymbols)|ha%(i|ana))|a%(l%(chemical%([_ ]symbols|symbols)|phabetic%( presentation forms|_presentation_forms|presentationforms))|ncient%(_%(greek_%(musical_notation|numbers)|symbols)|greek%(numbers|musicalnotation)| %(greek %(numbers|musical notation)|symbols)|symbols)|egean%(numbers|[ _]numbers)|vestan|r%(abic%( %(supplement|presentation forms\-[ab])|supplement|_%(presentation_forms_[ab]|supplement)|presentationforms\-[ab])?|menian|rows))|u%(garitic|nified%(canadianaboriginalsyllabics%(extended)?|_canadian_aboriginal_syllabics%(_extended)?| canadian aboriginal syllabics%( extended)?))|v%(a%(i|riation%( selectors%( supplement)?|selectors%(supplement)?|_selectors%(_supplement)?))|e%(rtical%(forms|[ _]forms)|dic%([ _]extensions|extensions))))\}" contained display
-
-syntax match clojureRegexpPredefinedCharClass "\v%(\\[dDsSwW]|\.)" contained display
-syntax cluster clojureRegexpCharPropertyClasses contains=clojureRegexpPosixCharClass,clojureRegexpJavaCharClass,clojureRegexpUnicodeCharClass
-syntax cluster clojureRegexpCharClasses contains=clojureRegexpPredefinedCharClass,clojureRegexpCharClass,@clojureRegexpCharPropertyClasses
-syntax region clojureRegexpCharClass start="\[" skip=/\\\\\|\\]/ end="]" contained contains=clojureRegexpPredefinedCharClass,@clojureRegexpCharPropertyClasses
-syntax match clojureRegexpBoundary "\\[bBAGZz]" contained display
-syntax match clojureRegexpBoundary "[$^]" contained display
-syntax match clojureRegexpQuantifier "[?*+][?+]\=" contained display
-syntax match clojureRegexpQuantifier "\v\{\d+%(,|,\d+)?}\??" contained display
-syntax match clojureRegexpOr "|" contained display
-syntax match clojureRegexpBackRef "\v\\%([1-9]\d*|k\<[a-zA-z]+\>)" contained display
+syntax match clojureRegexpUnicodeCharClass "\v\\[pP]\{\c%(Is|sc\=|script\=)%(l%(epc%(ha)?|y%([dc]i%(an)?)|a%(t%(n|in)|na|oo?)|i%(n%(b|ear_b)|mbu?|su))|p%(rti|lrd|h%(oenician|li|ag%(s_pa)?|nx))|vaii?|d%(srt|e%(seret|va%(nagari)?))|g%(lag%(olitic)?|eor%(gian)?|oth%(ic)?|re%(k|ek)|u%(j%(arati|r)|r%(u|mukhi)))|u%(gar%(itic)?|nknown)|a%(r%(ab%(ic)?|m%([ni]|enian))|v%(st|estan))|e%(thi%(opic)?|gyp%(tian_hieroglyphs)?)|z%(inh|yyy|zzz)|r%(un%(ic|r)|ejang|jng)|s%(inh%(ala)?|h%(rd|a%(vian|rada|w))|a%(ur%(ashtra)?|m%(r|aritan)|rb)|y%(r%(c|iac)|lo%(ti_nagri)?)|und%(anese)?|ora%(_sompeng)?)|i%(n%(scriptional_pa%(rthian|hlavi)|herited)|mperial_aramaic|tal)|b%(eng%(ali)?|a%(t%(ak|k)|li%(nese)?|mum?)|ra%(i%(lle)?|h%(mi)?)|opo%(mofo)?|u%(gi%(nese)?|h%(d|id)))|o%(g%(am|ham)|r%(iya|kh|ya)|sma%(nya)?|l%(d_%(south_arabian|persian|italic|turkic)|ck|_chiki))|k%(h%(m%(r|er)|ar%(oshthi)?)|nda|a%(li|n%(a|nada)|takana|yah_li|ithi)|thi)|m%(a%(nd%(aic)?|layalam)|lym|y%(anmar|mr)|tei|e%(r%(c|o%(itic_%(hieroglyphs|cursive))?)|etei_mayek)|ong%(olian)?|iao)|yi%(ii)?|x%(peo|sux)|n%(ew_tai_lue|koo?)|h%(ira%(gana)?|an%([io]|unoo|g%(ul)?)?|ebr%(ew)?)|c%(y%(priot|r%(l|illic))|a%(km|n%(adian_aboriginal|s)|ri%(an)?)|prt|h%(er%(okee)?|a%(m|kma))|uneiform|o%(pt%(ic)?|mmon))|t%(elu%(gu)?|i%(finagh|b%(t|etan))|ha%(i|a%(na)?)|a%(i_%(le|tham|viet)|g%(alog|b%(anwa)?)|vt|kri?|l[ue]|m%(il|l))|fng|glg)|java%(nese)?)\}" contained display
+syntax match clojureRegexpUnicodeCharClass "\v\\[pP]\{\c%(In|blk\=|block\=)%(javanese|h%(a%(lfwidth%( and fullwidth forms|andfullwidthforms|_and_fullwidth_forms)|n%(unoo|gul%(compatibilityjamo|syllables|jamo%(extended\-[ab])?|_%(syllables|jamo%(_extended_[ab])?|compatibility_jamo)| %(syllables|compatibility jamo|jamo%( extended\-[ab])?))))|i%(ragana|gh%( %(private use surrogates|surrogates)|_%(private_use_surrogates|surrogates)|surrogates|privateusesurrogates))|ebrew)|i%(pa%([ _]extensions|extensions)|deographic%( description characters|_description_characters|descriptioncharacters)|nscriptional%(%([ _]pa%(rthian|hlavi))|pa%(rthian|hlavi))|mperial%(aramaic|[_ ]aramaic))|l%(e%(tterlike%([_ ]symbols|symbols)|pcha)|ow%([_ ]surrogates|surrogates)|i%(mbu|near%(_b_%(ideograms|syllabary)|b%(ideograms|syllabary)| b %(ideograms|syllabary))|su)|a%(tin%(extended%(additional|\-[dacb])| extended%( additional|\-[dacb])|\-1%(supplement| supplement)|_%(extended_%([dcb]|a%(dditional)?)|1_supplement))|o)|y[cd]ian)|b%(u%(ginese|hid)|ra%(hmi|ille%(patterns|[_ ]patterns))|o%(x%([ _]drawing|drawing)|pomofo%([ _]extended|extended)?)|lock%([ _]elements|elements)|yzantine%( musical symbols|musicalsymbols|_musical_symbols)|engali|a%(linese|mum%(supplement|[ _]supplement)?|tak|sic%([ _]latin|latin)))|e%(gyptian%([ _]hieroglyphs|hieroglyphs)|moticons|nclosed%( %(cjk letters and months|ideographic supplement|alphanumeric%( supplement|s))|cjklettersandmonths|_%(ideographic_supplement|alphanumeric%(_supplement|s)|cjk_letters_and_months)|alphanumerics%(upplement)?|ideographicsupplement)|thiopic%(supplement|_%(supplement|extended%(_a)?)| %(supplement|extended%(\-a)?)|extended%(\-a)?)?)|k%(h%(aroshthi|mer%([_ ]symbols|symbols)?)|a%(takana%(_phonetic_extensions|phoneticextensions| phonetic extensions)?|n%(gxi%([_ ]radicals|radicals)|a%(supplement|[ _]supplement)|bun|nada)|ithi|yah%([ _]li|li)))|m%(i%(ao|scellaneous%(technical|symbols%(and%(pictographs|arrows))?|mathematicalsymbols\-[ab]| %(technical|mathematical symbols\-[ab]|symbols%( and %(pictographs|arrows))?)|_%(technical|symbols%(_and_%(pictographs|arrows))?|mathematical_symbols_[ab])))|usical%([_ ]symbols|symbols)|e%(etei%(mayek%(extensions)?|_mayek%(_extensions)?| mayek%( extensions)?)|roitic%(hieroglyphs|%([_ ]%(hieroglyphs|cursive))|cursive))|a%(ndaic|hjong%([ _]tiles|tiles)|layalam|thematical%(alphanumericsymbols| %(alphanumeric symbols|operators)|_%(alphanumeric_symbols|operators)|operators))|yanmar%(extended\-a|_extended_a| extended\-a)?|o%(difier%(_tone_letters| tone letters|toneletters)|ngolian))|r%(u%(nic|mi%(numeralsymbols| numeral symbols|_numeral_symbols))|ejang)|n%(umber%(forms|[ _]forms)|ko|ew%(_tai_lue|tailue| tai lue))|c%(o%(ntrol%(pictures|[ _]pictures)|m%(bining%(diacriticalmarks%(supplement|forsymbols)?|halfmarks| %(diacritical marks%( %(supplement|for symbols))?|half marks|marks for symbols)|marksforsymbols|_%(marks_for_symbols|half_marks|diacritical_marks%(_supplement)?))|mon%(_indic_number_forms|indicnumberforms| indic number forms))|ptic|unting%( rod numerals|_rod_numerals|rodnumerals))|y%(rillic%(extended\-[ab]|_%(extended_[ab]|supplementary)|supplement%(ary)?| %(extended\-[ab]|supplement%(ary)?))?|priot%(syllabary|[ _]syllabary))|u%(rrency%([_ ]symbols|symbols)|neiform%(_numbers_and_punctuation|numbersandpunctuation| numbers and punctuation)?)|h%(a%(m|kma)|erokee)|arian|jk%(s%(ymbolsandpunctuation|trokes)|compatibility%(forms|ideographs%(supplement)?)?|radicalssupplement| %(compatibility%( %(ideographs%( supplement)?|forms))?|radicals supplement|unified ideographs%( extension [dacb])?|s%(ymbols and punctuation|trokes))|_%(s%(trokes|ymbols_and_punctuation)|radicals_supplement|compatibility%(_%(forms|ideographs%(_supplement)?))?|unified_ideographs%(_extension_[dacb])?)|unifiedideographs%(extension[dacb])?))|d%(e%(seret|vanagari%([ _]extended|extended)?)|ingbats|omino%([ _]tiles|tiles))|yi%(syllables|%([_ ]%(syllables|radicals))|radicals|jing%(hexagramsymbols| hexagram symbols|_hexagram_symbols))|s%(mall%( form variants|formvariants|_form_variants)|p%(acing%(_modifier_letters| modifier letters|modifierletters)|ecials)|ora%(sompeng|[ _]sompeng)|ha%(vian|rada)|a%(maritan|urashtra)|inhala|y%(riac|loti%([_ ]nagri|nagri))|u%(ndanese%(supplement|[ _]supplement)?|p%(erscripts%(_and_subscripts|andsubscripts| and subscripts)|plementa%(ry%(_private_use_area_[ab]|privateusearea\-[ab]| private use area\-[ab])|l%(_%(arrows_[ab]|mathematical_operators|punctuation)| %(mathematical operators|punctuation|arrows\-[ab])|mathematicaloperators|punctuation|arrows\-[ab])))|rrogates_area))|p%(h%(o%(enician|netic%( extensions%( supplement)?|extensions%(supplement)?|_extensions%(_supplement)?))|a%(istos%([ _]disc|disc)|gs[_\-]pa))|laying%(cards|[_ ]cards)|rivate%(usearea| use area|_use_area))|o%(smanya|l%([ _]chiki|d%( %(south arabian|persian|italic|turkic)|southarabian|_%(south_arabian|persian|italic|turkic)|persian|italic|turkic)|chiki)|riya|ptical%( character recognition|_character_recognition|characterrecognition)|gham)|g%(u%(jarati|rmukhi)|othic|lagolitic|e%(o%(rgian%(supplement|[ _]supplement)?|metric%(shapes|[ _]shapes))|neral%([_ ]punctuation|punctuation))|reek%( %(and coptic|extended)|andcoptic|_extended|extended)?)|t%(i%(betan|finagh)|elugu|ransport%( and map symbols|_and_map_symbols|andmapsymbols)|a%(mil|kri|i%(xuanjingsymbols|_%(le|xuan_jing_symbols|tham|viet)|le| %(xuan jing symbols|le|tham|viet)|tham|viet)|g%(alog|s|banwa))|ha%(i|ana))|a%(l%(chemical%([_ ]symbols|symbols)|phabetic%( presentation forms|_presentation_forms|presentationforms))|r%(menian|abic%(extended\-a|mathematicalalphabeticsymbols|supplement|_%(presentation_forms_[ab]|supplement|extended_a|mathematical_alphabetic_symbols)| %(extended\-a|mathematical alphabetic symbols|supplement|presentation forms\-[ab])|presentationforms\-[ab])?|rows)|ncient%(_%(greek_%(musical_notation|numbers)|symbols)|greek%(numbers|musicalnotation)| %(greek %(numbers|musical notation)|symbols)|symbols)|egean%(numbers|[ _]numbers)|vestan)|u%(garitic|nified%(canadianaboriginalsyllabics%(extended)?|_canadian_aboriginal_syllabics%(_extended)?| canadian aboriginal syllabics%( extended)?))|v%(a%(i|riation%( selectors%( supplement)?|selectors%(supplement)?|_selectors%(_supplement)?))|e%(rtical%(forms|[ _]forms)|dic%([ _]extensions|extensions))))\}" contained display
+
+syntax match clojureRegexpPredefinedCharClass "\v%(\\[dDsSwW]|\.)" contained display
+syntax cluster clojureRegexpCharPropertyClasses contains=clojureRegexpPosixCharClass,clojureRegexpJavaCharClass,clojureRegexpUnicodeCharClass
+syntax cluster clojureRegexpCharClasses contains=clojureRegexpPredefinedCharClass,clojureRegexpCharClass,@clojureRegexpCharPropertyClasses
+syntax region clojureRegexpCharClass start="\[" skip=/\\\\\|\\]/ end="]" contained contains=clojureRegexpPredefinedCharClass,@clojureRegexpCharPropertyClasses
+syntax match clojureRegexpBoundary "\\[bBAGZz]" contained display
+syntax match clojureRegexpBoundary "[$^]" contained display
+syntax match clojureRegexpQuantifier "[?*+][?+]\=" contained display
+syntax match clojureRegexpQuantifier "\v\{\d+%(,|,\d+)?}\??" contained display
+syntax match clojureRegexpOr "|" contained display
+syntax match clojureRegexpBackRef "\v\\%([1-9]\d*|k\<[a-zA-z]+\>)" contained display
" Mode modifiers, mode-modified spans, lookaround, regular and atomic
" grouping, and named-capturing.
@@ -123,66 +154,70 @@ syntax match clojureComment ";.*$" contains=clojureCommentTodo,@Spell
syntax match clojureComment "#!.*$"
" -*- TOP CLUSTER -*-
-" Generated from https://github.com/guns/vim-clojure-static/blob/vim-release-010/clj/src/vim_clojure_static/generate.clj
+" Generated from https://github.com/guns/vim-clojure-static/blob/vim-release-011/clj/src/vim_clojure_static/generate.clj
syntax cluster clojureTop contains=@Spell,clojureAnonArg,clojureBoolean,clojureCharacter,clojureComment,clojureCond,clojureConstant,clojureDefine,clojureDeref,clojureDispatch,clojureError,clojureException,clojureFunc,clojureKeyword,clojureMacro,clojureMap,clojureMeta,clojureNumber,clojureQuote,clojureRegexp,clojureRepeat,clojureSexp,clojureSpecial,clojureString,clojureSymbol,clojureUnquote,clojureVarArg,clojureVariable,clojureVector
-syntax region clojureSexp matchgroup=clojureParen start="(" matchgroup=clojureParen end=")" contains=@clojureTop fold
-syntax region clojureVector matchgroup=clojureParen start="\[" matchgroup=clojureParen end="]" contains=@clojureTop fold
-syntax region clojureMap matchgroup=clojureParen start="{" matchgroup=clojureParen end="}" contains=@clojureTop fold
+syntax region clojureSexp matchgroup=clojureParen start="(" end=")" contains=@clojureTop fold
+syntax region clojureVector matchgroup=clojureParen start="\[" end="]" contains=@clojureTop fold
+syntax region clojureMap matchgroup=clojureParen start="{" end="}" contains=@clojureTop fold
" Highlight superfluous closing parens, brackets and braces.
syntax match clojureError "]\|}\|)"
syntax sync fromstart
-highlight default link clojureConstant Constant
-highlight default link clojureBoolean Boolean
-highlight default link clojureCharacter Character
-highlight default link clojureKeyword Keyword
-highlight default link clojureNumber Number
-highlight default link clojureString String
-highlight default link clojureStringEscape Character
-
-highlight default link clojureRegexp Constant
-highlight default link clojureRegexpEscape Character
-highlight default link clojureRegexpCharClass SpecialChar
-highlight default link clojureRegexpPosixCharClass clojureRegexpCharClass
-highlight default link clojureRegexpJavaCharClass clojureRegexpCharClass
-highlight default link clojureRegexpUnicodeCharClass clojureRegexpCharClass
-highlight default link clojureRegexpPredefinedCharClass clojureRegexpCharClass
-highlight default link clojureRegexpBoundary SpecialChar
-highlight default link clojureRegexpQuantifier SpecialChar
-highlight default link clojureRegexpMod SpecialChar
-highlight default link clojureRegexpOr SpecialChar
-highlight default link clojureRegexpBackRef SpecialChar
-highlight default link clojureRegexpGroup clojureRegexp
-highlight default link clojureRegexpQuoted clojureString
-highlight default link clojureRegexpQuote clojureRegexpBoundary
-
-highlight default link clojureVariable Identifier
-highlight default link clojureCond Conditional
-highlight default link clojureDefine Define
-highlight default link clojureException Exception
-highlight default link clojureFunc Function
-highlight default link clojureMacro Macro
-highlight default link clojureRepeat Repeat
-
-highlight default link clojureSpecial Special
-highlight default link clojureVarArg Special
-highlight default link clojureQuote SpecialChar
-highlight default link clojureUnquote SpecialChar
-highlight default link clojureMeta SpecialChar
-highlight default link clojureDeref SpecialChar
-highlight default link clojureAnonArg SpecialChar
-highlight default link clojureDispatch SpecialChar
-
-highlight default link clojureComment Comment
-highlight default link clojureCommentTodo Todo
-
-highlight default link clojureError Error
-
-highlight default link clojureParen Delimiter
+highlight default link clojureConstant Constant
+highlight default link clojureBoolean Boolean
+highlight default link clojureCharacter Character
+highlight default link clojureKeyword Keyword
+highlight default link clojureNumber Number
+highlight default link clojureString String
+highlight default link clojureStringDelimiter String
+highlight default link clojureStringEscape Character
+
+highlight default link clojureRegexp Constant
+highlight default link clojureRegexpEscape Character
+highlight default link clojureRegexpCharClass SpecialChar
+highlight default link clojureRegexpPosixCharClass clojureRegexpCharClass
+highlight default link clojureRegexpJavaCharClass clojureRegexpCharClass
+highlight default link clojureRegexpUnicodeCharClass clojureRegexpCharClass
+highlight default link clojureRegexpPredefinedCharClass clojureRegexpCharClass
+highlight default link clojureRegexpBoundary SpecialChar
+highlight default link clojureRegexpQuantifier SpecialChar
+highlight default link clojureRegexpMod SpecialChar
+highlight default link clojureRegexpOr SpecialChar
+highlight default link clojureRegexpBackRef SpecialChar
+highlight default link clojureRegexpGroup clojureRegexp
+highlight default link clojureRegexpQuoted clojureString
+highlight default link clojureRegexpQuote clojureRegexpBoundary
+
+highlight default link clojureVariable Identifier
+highlight default link clojureCond Conditional
+highlight default link clojureDefine Define
+highlight default link clojureException Exception
+highlight default link clojureFunc Function
+highlight default link clojureMacro Macro
+highlight default link clojureRepeat Repeat
+
+highlight default link clojureSpecial Special
+highlight default link clojureVarArg Special
+highlight default link clojureQuote SpecialChar
+highlight default link clojureUnquote SpecialChar
+highlight default link clojureMeta SpecialChar
+highlight default link clojureDeref SpecialChar
+highlight default link clojureAnonArg SpecialChar
+highlight default link clojureDispatch SpecialChar
+
+highlight default link clojureComment Comment
+highlight default link clojureCommentTodo Todo
+
+highlight default link clojureError Error
+
+highlight default link clojureParen Delimiter
let b:current_syntax = "clojure"
-" vim:sts=8:sw=8:ts=8:noet:smc=0
+let &cpo = s:cpo_sav
+unlet! s:cpo_sav
+
+" vim:sts=8:sw=8:ts=8:noet
diff --git a/runtime/syntax/help.vim b/runtime/syntax/help.vim
index b3c7f2a63e..41bb0b1938 100644
--- a/runtime/syntax/help.vim
+++ b/runtime/syntax/help.vim
@@ -59,7 +59,7 @@ syn match helpSpecial "\[N]"
syn match helpSpecial "N N"he=s+1
syn match helpSpecial "Nth"me=e-2
syn match helpSpecial "N-1"me=e-2
-syn match helpSpecial "{[-a-zA-Z0-9'"*+/:%#=[\]<>.,]\+}"
+syn match helpSpecial "{[-_a-zA-Z0-9'"*+/:%#=[\]<>.,]\+}"
syn match helpSpecial "\s\[[-a-z^A-Z0-9_]\{2,}]"ms=s+1
syn match helpSpecial "<[-a-zA-Z0-9_]\+>"
syn match helpSpecial "<[SCM]-.>"
diff --git a/runtime/syntax/python.vim b/runtime/syntax/python.vim
index 2a0ea5de2b..fa42b3e2d2 100644
--- a/runtime/syntax/python.vim
+++ b/runtime/syntax/python.vim
@@ -1,7 +1,7 @@
" Vim syntax file
" Language: Python
" Maintainer: Zvezdan Petkovic <zpetkovic@acm.org>
-" Last Change: 2016 Feb 20
+" Last Change: 2016 Jul 21
" Credits: Neil Schemenauer <nas@python.ca>
" Dmitry Vasiliev
"
@@ -72,7 +72,7 @@ set cpo&vim
" built-in below (use 'from __future__ import print_function' in 2)
" - async and await were added in Python 3.5 and are soft keywords.
"
-syn keyword pythonStatement False, None, True
+syn keyword pythonStatement False None True
syn keyword pythonStatement as assert break continue del exec global
syn keyword pythonStatement lambda nonlocal pass print return with yield
syn keyword pythonStatement class def nextgroup=pythonFunction skipwhite
diff --git a/runtime/syntax/sqloracle.vim b/runtime/syntax/sqloracle.vim
index 8afe2686bf..f9e24af98c 100644
--- a/runtime/syntax/sqloracle.vim
+++ b/runtime/syntax/sqloracle.vim
@@ -4,7 +4,12 @@
" Repository: https://github.com/chrisbra/vim-sqloracle-syntax
" License: Vim
" Previous Maintainer: Paul Moore
-" Last Change: 2015 Nov 24
+" Last Change: 2016 Jul 22
+
+" Changes:
+" 02.04.2016: Support for when keyword
+" 03.04.2016: Support for join related keywords
+" 22.07.2016: Support Oracle Q-Quote-Syntax
if exists("b:current_syntax")
finish
@@ -24,10 +29,11 @@ syn keyword sqlKeyword index initial initrans into is level link logging loop
syn keyword sqlKeyword maxextents maxtrans mode modify monitoring
syn keyword sqlKeyword nocache nocompress nologging noparallel nowait of offline on online start
syn keyword sqlKeyword parallel successful synonym table tablespace then to trigger uid
-syn keyword sqlKeyword unique user validate values view whenever
+syn keyword sqlKeyword unique user validate values view when whenever
syn keyword sqlKeyword where with option order pctfree pctused privileges procedure
syn keyword sqlKeyword public resource return row rowlabel rownum rows
syn keyword sqlKeyword session share size smallint type using
+syn keyword sqlKeyword join cross inner outer left right
syn keyword sqlOperator not and or
syn keyword sqlOperator in any some all between exists
@@ -47,8 +53,13 @@ syn keyword sqlType boolean char character date float integer long
syn keyword sqlType mlslabel number raw rowid varchar varchar2 varray
" Strings:
-syn region sqlString start=+"+ skip=+\\\\\|\\"+ end=+"+
-syn region sqlString start=+'+ skip=+\\\\\|\\'+ end=+'+
+syn region sqlString matchgroup=Quote start=+"+ skip=+\\\\\|\\"+ end=+"+
+syn region sqlString matchgroup=Quote start=+'+ skip=+\\\\\|\\'+ end=+'+
+syn region sqlString matchgroup=Quote start=+n\?q'\z([^[(<{]\)+ end=+\z1'+
+syn region sqlString matchgroup=Quote start=+n\?q'<+ end=+>'+
+syn region sqlString matchgroup=Quote start=+n\?q'{+ end=+}'+
+syn region sqlString matchgroup=Quote start=+n\?q'(+ end=+)'+
+syn region sqlString matchgroup=Quote start=+n\?q'\[+ end=+]'+
" Numbers:
syn match sqlNumber "-\=\<\d*\.\=[0-9_]\>"
@@ -118,6 +129,7 @@ syn keyword sqlTodo TODO FIXME XXX DEBUG NOTE contained
" Define the default highlighting.
command -nargs=+ HiLink hi def link <args>
+HiLink Quote Special
HiLink sqlComment Comment
HiLink sqlFunction Function
HiLink sqlKeyword sqlSpecial
diff --git a/runtime/syntax/vim.vim b/runtime/syntax/vim.vim
index cd96a55eda..63618e902e 100644
--- a/runtime/syntax/vim.vim
+++ b/runtime/syntax/vim.vim
@@ -637,7 +637,9 @@ if !filereadable(s:perlpath)
endif
if g:vimsyn_embed =~# 'p' && filereadable(s:perlpath)
unlet! b:current_syntax
+ let s:foldmethod = &l:foldmethod
exe "syn include @vimPerlScript ".s:perlpath
+ let &l:foldmethod = s:foldmethod
VimFoldp syn region vimPerlRegion matchgroup=vimScriptDelim start=+pe\%[rl]\s*<<\s*\z(.*\)$+ end=+^\z1$+ contains=@vimPerlScript
VimFoldp syn region vimPerlRegion matchgroup=vimScriptDelim start=+pe\%[rl]\s*<<\s*$+ end=+\.$+ contains=@vimPerlScript
syn cluster vimFuncBodyList add=vimPerlRegion
@@ -659,7 +661,9 @@ if !filereadable(s:rubypath)
endif
if g:vimsyn_embed =~# 'r' && filereadable(s:rubypath)
unlet! b:current_syntax
+ let s:foldmethod = &l:foldmethod
exe "syn include @vimRubyScript ".s:rubypath
+ let &l:foldmethod = s:foldmethod
VimFoldr syn region vimRubyRegion matchgroup=vimScriptDelim start=+rub[y]\s*<<\s*\z(.*\)$+ end=+^\z1$+ contains=@vimRubyScript
syn region vimRubyRegion matchgroup=vimScriptDelim start=+rub[y]\s*<<\s*$+ end=+\.$+ contains=@vimRubyScript
syn cluster vimFuncBodyList add=vimRubyRegion
diff --git a/scripts/gen_api_vimdoc.py b/scripts/gen_api_vimdoc.py
new file mode 100644
index 0000000000..d7165187f4
--- /dev/null
+++ b/scripts/gen_api_vimdoc.py
@@ -0,0 +1,514 @@
+#!/usr/bin/env python
+"""Parses Doxygen XML output to generate Neovim's API documentation.
+
+This would be easier using lxml and XSLT, but:
+
+ 1. This should avoid needing Python dependencies, especially ones that are
+ C modules that have library dependencies (lxml requires libxml and
+ libxslt).
+ 2. I wouldn't know how to deal with nested indentation in <para> tags using
+ XSLT.
+
+Each function documentation is formatted with the following rules:
+
+ - Maximum width of 78 characters (`text_width`).
+ - Spaces for indentation.
+ - Function signature and helptag are on the same line.
+ - Helptag is right aligned.
+ - Signature and helptag must have a minimum of 8 spaces between them.
+ - If the signature is too long, it is placed on the line after the
+ helptag. The signature wraps at `text_width - 8` characters with
+ subsequent lines indented to the open parenthesis.
+ - Documentation body will be indented by 16 spaces.
+ - Subsection bodies are indented an additional 4 spaces.
+ - Documentation body consists of the function description, parameter details,
+ return description, and C declaration.
+ - Parameters are omitted for the `void` and `Error *` types, or if the
+ parameter is marked as [out].
+ - Each function documentation is separated by a single line.
+
+The C declaration is added to the end to show actual argument types.
+"""
+import os
+import re
+import sys
+import shutil
+import textwrap
+import subprocess
+
+from xml.dom import minidom
+
+# Text at the top of the doc file.
+preamble = '''
+Note: This documentation is generated from Neovim's API source code.
+'''
+
+doc_filename = 'api-funcs.txt'
+
+# Section name overrides.
+section_name = {
+ 'vim.c': 'Global',
+}
+
+# Section ordering.
+section_order = (
+ 'vim.c',
+ 'buffer.c',
+ 'window.c',
+ 'tabpage.c',
+ 'ui.c',
+)
+
+param_exclude = (
+ 'channel_id',
+)
+
+text_width = 78
+script_path = os.path.abspath(__file__)
+base_dir = os.path.dirname(os.path.dirname(script_path))
+src_dir = os.path.join(base_dir, 'src/nvim/api')
+out_dir = os.path.join(base_dir, 'tmp/api_doc')
+filter_cmd = '%s %s' % (sys.executable, script_path)
+seen_funcs = set()
+
+# Tracks `xrefsect` titles. As of this writing, used only for separating
+# deprecated functions.
+xrefs = set()
+
+
+# XML Parsing Utilities {{{
+def find_first(parent, name):
+ """Finds the first matching node within parent."""
+ sub = parent.getElementsByTagName(name)
+ if not sub:
+ return None
+ return sub[0]
+
+
+def get_children(parent, name):
+ """Yield matching child nodes within parent."""
+ for child in parent.childNodes:
+ if child.nodeType == child.ELEMENT_NODE and child.nodeName == name:
+ yield child
+
+
+def get_child(parent, name):
+ """Get the first matching child node."""
+ for child in get_children(parent, name):
+ return child
+ return None
+
+
+def clean_text(text):
+ """Cleans text.
+
+ Only cleans superfluous whitespace at the moment.
+ """
+ return ' '.join(text.split()).strip()
+
+
+def clean_lines(text):
+ """Removes superfluous lines.
+
+ The beginning and end of the string is trimmed. Empty lines are collapsed.
+ """
+ return re.sub(r'\A\n\s*\n*|\n\s*\n*\Z', '', re.sub(r'(\n\s*\n+)+', '\n\n', text))
+
+
+def get_text(parent):
+ """Combine all text in a node."""
+ if parent.nodeType == parent.TEXT_NODE:
+ return parent.data
+
+ out = ''
+ for node in parent.childNodes:
+ if node.nodeType == node.TEXT_NODE:
+ out += clean_text(node.data)
+ elif node.nodeType == node.ELEMENT_NODE:
+ out += ' ' + get_text(node)
+ return out
+
+
+def doc_wrap(text, prefix='', width=70, func=False):
+ """Wraps text to `width`.
+
+ The first line is prefixed with `prefix`, and subsequent lines are aligned.
+ If `func` is True, only wrap at commas.
+ """
+ if not width:
+ return text
+
+ indent_space = ' ' * len(prefix)
+
+ if func:
+ lines = [prefix]
+ for part in text.split(', '):
+ if part[-1] not in ');':
+ part += ', '
+ if len(lines[-1]) + len(part) > width:
+ lines.append(indent_space)
+ lines[-1] += part
+ return '\n'.join(x.rstrip() for x in lines).rstrip()
+
+ return '\n'.join(textwrap.wrap(text.strip(), width=width,
+ initial_indent=prefix,
+ subsequent_indent=indent_space))
+
+
+def parse_params(parent, width=62):
+ """Parse Doxygen `parameterlist`."""
+ name_length = 0
+ items = []
+ for child in parent.childNodes:
+ if child.nodeType == child.TEXT_NODE:
+ continue
+
+ name_node = find_first(child, 'parametername')
+ if name_node.getAttribute('direction') == 'out':
+ continue
+
+ name = get_text(name_node)
+ if name in param_exclude:
+ continue
+
+ name = '{%s}' % name
+ name_length = max(name_length, len(name) + 2)
+
+ desc = ''
+ desc_node = get_child(child, 'parameterdescription')
+ if desc_node:
+ desc = parse_parblock(desc_node, width=None)
+ items.append((name.strip(), desc.strip()))
+
+ out = 'Parameters:~\n'
+ for name, desc in items:
+ name = ' %s' % name.ljust(name_length)
+ out += doc_wrap(desc, prefix=name, width=width) + '\n'
+ return out.strip()
+
+
+def parse_para(parent, width=62):
+ """Parse doxygen `para` tag.
+
+ I assume <para> is a paragraph block or "a block of text". It can contain
+ text nodes, or other tags.
+ """
+ line = ''
+ lines = []
+ for child in parent.childNodes:
+ if child.nodeType == child.TEXT_NODE:
+ line += child.data
+ elif child.nodeName == 'computeroutput':
+ line += '`%s`' % get_text(child)
+ else:
+ if line:
+ lines.append(doc_wrap(line, width=width))
+ line = ''
+
+ if child.nodeName == 'parameterlist':
+ lines.append(parse_params(child, width=width))
+ elif child.nodeName == 'xrefsect':
+ title = get_text(get_child(child, 'xreftitle'))
+ xrefs.add(title)
+ xrefdesc = parse_para(get_child(child, 'xrefdescription'))
+ lines.append(doc_wrap(xrefdesc, prefix='%s: ' % title,
+ width=width) + '\n')
+ elif child.nodeName == 'simplesect':
+ kind = child.getAttribute('kind')
+ if kind == 'return':
+ lines.append('%s:~' % kind.title())
+ lines.append(doc_wrap(parse_para(child),
+ prefix=' ',
+ width=width))
+ else:
+ lines.append(get_text(child))
+
+ if line:
+ lines.append(doc_wrap(line, width=width))
+ return clean_lines('\n'.join(lines).strip())
+
+
+def parse_parblock(parent, width=62):
+ """Parses a nested block of `para` tags.
+
+ Named after the \parblock command, but not directly related.
+ """
+ paragraphs = []
+ for child in parent.childNodes:
+ if child.nodeType == child.TEXT_NODE:
+ paragraphs.append(doc_wrap(child.data, width=width))
+ elif child.nodeName == 'para':
+ paragraphs.append(parse_para(child, width=width))
+ else:
+ paragraphs.append(doc_wrap(get_text(child), width=width))
+ paragraphs.append('')
+ return clean_lines('\n'.join(paragraphs).strip())
+# }}}
+
+
+def parse_source_xml(filename):
+ """Collects API functions.
+
+ This returns two strings:
+ 1. The API functions
+ 2. The deprecated API functions
+
+ The caller decides what to do with the deprecated documentation.
+ """
+ global xrefs
+ xrefs = set()
+ functions = []
+ deprecated_functions = []
+
+ dom = minidom.parse(filename)
+ for member in dom.getElementsByTagName('memberdef'):
+ if member.getAttribute('static') == 'yes' or \
+ member.getAttribute('kind') != 'function':
+ continue
+
+ loc = find_first(member, 'location')
+ if 'private' in loc.getAttribute('file'):
+ continue
+
+ return_type = get_text(get_child(member, 'type'))
+ if return_type == '':
+ continue
+
+ if return_type.startswith(('ArrayOf', 'DictionaryOf')):
+ parts = return_type.strip('_').split('_')
+ return_type = '%s(%s)' % (parts[0], ', '.join(parts[1:]))
+
+ name = get_text(get_child(member, 'name'))
+
+ vimtag = '*%s()*' % name
+ args = []
+ type_length = 0
+
+ for param in get_children(member, 'param'):
+ arg_type = get_text(get_child(param, 'type')).strip()
+ arg_name = ''
+ declname = get_child(param, 'declname')
+ if declname:
+ arg_name = get_text(declname).strip()
+
+ if arg_name in param_exclude:
+ continue
+
+ if arg_type.endswith('*'):
+ arg_type = arg_type.strip('* ')
+ arg_name = '*' + arg_name
+ type_length = max(type_length, len(arg_type))
+ args.append((arg_type, arg_name))
+
+ c_args = []
+ for arg_type, arg_name in args:
+ c_args.append(' ' + (
+ '%s %s' % (arg_type.ljust(type_length), arg_name)).strip())
+
+ c_decl = textwrap.indent('%s %s(\n%s\n);' % (return_type, name,
+ ',\n'.join(c_args)),
+ ' ')
+
+ prefix = '%s(' % name
+ suffix = '%s)' % ', '.join('{%s}' % a[1] for a in args
+ if a[0] not in ('void', 'Error'))
+
+ # Minimum 8 chars between signature and vimtag
+ lhs = (text_width - 8) - len(prefix)
+
+ if len(prefix) + len(suffix) > lhs:
+ signature = vimtag.rjust(text_width) + '\n'
+ signature += doc_wrap(suffix, width=text_width-8, prefix=prefix,
+ func=True)
+ else:
+ signature = prefix + suffix
+ signature += vimtag.rjust(text_width - len(signature))
+
+ doc = ''
+ desc = find_first(member, 'detaileddescription')
+ if desc:
+ doc = parse_parblock(desc)
+ if 'DEBUG' in os.environ:
+ print(textwrap.indent(
+ re.sub(r'\n\s*\n+', '\n',
+ desc.toprettyxml(indent=' ', newl='\n')), ' ' * 16))
+
+ if not doc:
+ doc = 'TODO: Documentation'
+
+ if 'INCLUDE_C_DECL' in os.environ:
+ doc += '\n\nC Declaration:~\n>\n'
+ doc += c_decl
+ doc += '\n<'
+
+ func_doc = signature + '\n'
+ func_doc += textwrap.indent(clean_lines(doc), ' ' * 16)
+ func_doc = re.sub(r'^\s+([<>])$', r'\1', func_doc, flags=re.M)
+
+ if 'Deprecated' in xrefs:
+ deprecated_functions.append(func_doc)
+ else:
+ functions.append(func_doc)
+
+ xrefs.clear()
+
+ return '\n\n'.join(functions), '\n\n'.join(deprecated_functions)
+
+
+def gen_docs(config):
+ """Generate documentation.
+
+ Doxygen is called and configured through stdin.
+ """
+ p = subprocess.Popen(['doxygen', '-'], stdin=subprocess.PIPE)
+ p.communicate(config.format(input=src_dir, output=out_dir,
+ filter=filter_cmd).encode('utf8'))
+ if p.returncode:
+ sys.exit(p.returncode)
+
+ title_length = 0
+ sections = {}
+ sep = '=' * text_width
+
+ base = os.path.join(out_dir, 'xml')
+ dom = minidom.parse(os.path.join(base, 'index.xml'))
+ for compound in dom.getElementsByTagName('compound'):
+ if compound.getAttribute('kind') != 'file':
+ continue
+
+ filename = get_text(find_first(compound, 'name'))
+ if filename.endswith('.c'):
+ functions, deprecated = parse_source_xml(
+ os.path.join(base, '%s.xml' % compound.getAttribute('refid')))
+
+ if not functions and not deprecated:
+ continue
+
+ if functions or deprecated:
+ name = os.path.splitext(os.path.basename(filename))[0]
+ if name == 'ui':
+ name = name.upper()
+ else:
+ name = name.title()
+
+ doc = ''
+ if functions:
+ doc += '\n\n' + functions
+
+ if 'INCLUDE_DEPRECATED' in os.environ and deprecated:
+ doc += '\n\n\nDeprecated %s Functions:~\n\n' % name
+ doc += deprecated
+
+ if doc:
+ filename = os.path.basename(filename)
+ name = section_name.get(filename, name)
+ title = '%s Functions' % name
+ helptag = '*api-%s*' % name.lower()
+ title_length = max(title_length, len(title))
+ sections[filename] = (title, helptag, doc)
+
+ if not sections:
+ return
+
+ title_left = '*%s*' % doc_filename
+ title_center = 'Neovim API Function Reference'
+ title_right = '{Nvim}'
+ margin = max(len(title_left), len(title_right))
+ head = (title_left.ljust(margin) +
+ title_center.center(text_width - margin * 2) +
+ title_right.rjust(margin)) + '\n'
+
+ head += '\n%s\n\n' % doc_wrap(preamble, width=text_width)
+ head += 'Contents:\n\n'
+
+ docs = ''
+
+ title_length += len(str(len(section_order))) + 2
+ i = 0
+ for filename in section_order:
+ if filename not in sections:
+ continue
+ title, helptag, section_doc = sections.pop(filename)
+
+ i += 1
+ docs += sep
+ title = '%d. %s' % (i, title)
+ head += (title.ljust(title_length) + ' ' +
+ helptag.replace('*', '|') + '\n')
+ docs += '\n%s%s' % (title, helptag.rjust(text_width - len(title)))
+ docs += section_doc
+ docs += '\n\n\n'
+
+ if sections:
+ # In case new API sources are added without updating the order dict.
+ for title, helptag, section_doc in sections.values():
+ i += 1
+ docs += sep
+ title = '%d. %s' % (i, title)
+ head += (title.ljust(title_length) + ' ' +
+ helptag.replace('*', '|') + '\n')
+ docs += '\n%s%s' % (title, helptag.rjust(text_width - len(title)))
+ docs += section_doc
+ docs += '\n\n\n'
+
+ docs = '%s\n%s' % (head, docs)
+ docs = docs.rstrip() + '\n\n'
+ docs += ' vim:tw=78:ts=8:ft=help:norl:'
+
+ doc_file = os.path.join(base_dir, 'runtime/doc', doc_filename)
+ with open(doc_file, 'wb') as fp:
+ fp.write(docs.encode('utf8'))
+
+ shutil.rmtree(out_dir)
+
+
+def filter_source(filename):
+ """Filters the source to fix macros that confuse Doxygen."""
+ with open(filename, 'rt') as fp:
+ print(re.sub(r'^(ArrayOf|DictionaryOf)(\(.*?\))',
+ lambda m: m.group(1)+'_'.join(
+ re.split(r'[^\w]+', m.group(2))),
+ fp.read(), flags=re.M))
+
+
+# Doxygen Config {{{
+Doxyfile = '''
+OUTPUT_DIRECTORY = {output}
+INPUT = {input}
+INPUT_ENCODING = UTF-8
+FILE_PATTERNS = *.h *.c
+RECURSIVE = YES
+INPUT_FILTER = "{filter}"
+EXCLUDE =
+EXCLUDE_SYMLINKS = NO
+EXCLUDE_PATTERNS = */private/*
+EXCLUDE_SYMBOLS =
+
+GENERATE_HTML = NO
+GENERATE_DOCSET = NO
+GENERATE_HTMLHELP = NO
+GENERATE_QHP = NO
+GENERATE_TREEVIEW = NO
+GENERATE_LATEX = NO
+GENERATE_RTF = NO
+GENERATE_MAN = NO
+GENERATE_DOCBOOK = NO
+GENERATE_AUTOGEN_DEF = NO
+
+GENERATE_XML = YES
+XML_OUTPUT = xml
+XML_PROGRAMLISTING = NO
+
+ENABLE_PREPROCESSING = YES
+MACRO_EXPANSION = YES
+EXPAND_ONLY_PREDEF = NO
+'''
+# }}}
+
+if __name__ == "__main__":
+ if len(sys.argv) > 1:
+ filter_source(sys.argv[1])
+ else:
+ gen_docs(Doxyfile)
+
+# vim: set ft=python ts=4 sw=4 tw=79 et fdm=marker :
diff --git a/src/nvim/eval.c b/src/nvim/eval.c
index 45f317fbea..4501c2e0a6 100644
--- a/src/nvim/eval.c
+++ b/src/nvim/eval.c
@@ -5162,12 +5162,18 @@ dict_equal (
dictitem_T *item2;
int todo;
- if (d1 == NULL || d2 == NULL)
- return FALSE;
- if (d1 == d2)
- return TRUE;
- if (dict_len(d1) != dict_len(d2))
- return FALSE;
+ if (d1 == NULL && d2 == NULL) {
+ return true;
+ }
+ if (d1 == NULL || d2 == NULL) {
+ return false;
+ }
+ if (d1 == d2) {
+ return true;
+ }
+ if (dict_len(d1) != dict_len(d2)) {
+ return false;
+ }
todo = (int)d1->dv_hashtab.ht_used;
for (hi = d1->dv_hashtab.ht_array; todo > 0; ++hi) {
@@ -6669,9 +6675,12 @@ dictitem_T *dict_find(dict_T *d, char_u *key, int len)
char_u *tofree = NULL;
hashitem_T *hi;
- if (len < 0)
+ if (d == NULL) {
+ return NULL;
+ }
+ if (len < 0) {
akey = key;
- else if (len >= AKEYLEN) {
+ } else if (len >= AKEYLEN) {
tofree = akey = vim_strnsave(key, len);
} else {
/* Avoid a malloc/free by using buf[]. */
@@ -9242,7 +9251,7 @@ static void filter_map(typval_T *argvars, typval_T *rettv, int map)
dict_T *d = NULL;
typval_T save_val;
typval_T save_key;
- int rem;
+ int rem = false;
int todo;
char_u *ermsg = (char_u *)(map ? "map()" : "filter()");
char_u *arg_errmsg = (char_u *)(map ? N_("map() argument")
@@ -10067,7 +10076,7 @@ static void f_getbufvar(typval_T *argvars, typval_T *rettv, FunPtr fptr)
} else if (STRCMP(varname, "changedtick") == 0) {
rettv->v_type = VAR_NUMBER;
rettv->vval.v_number = curbuf->b_changedtick;
- done = TRUE;
+ done = true;
} else {
/* Look up the variable. */
/* Let getbufvar({nr}, "") return the "b:" dictionary. */
@@ -15064,7 +15073,6 @@ static void f_serverstop(typval_T *argvars, typval_T *rettv, FunPtr fptr)
static void f_setbufvar(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
buf_T *buf;
- aco_save_T aco;
char_u *varname, *bufvarname;
typval_T *varp;
char_u nbuf[NUMBUFLEN];
@@ -15077,29 +15085,34 @@ static void f_setbufvar(typval_T *argvars, typval_T *rettv, FunPtr fptr)
varp = &argvars[2];
if (buf != NULL && varname != NULL && varp != NULL) {
- /* set curbuf to be our buf, temporarily */
- aucmd_prepbuf(&aco, buf);
-
if (*varname == '&') {
long numval;
char_u *strval;
- int error = FALSE;
+ int error = false;
+ aco_save_T aco;
+
+ // set curbuf to be our buf, temporarily
+ aucmd_prepbuf(&aco, buf);
++varname;
numval = get_tv_number_chk(varp, &error);
strval = get_tv_string_buf_chk(varp, nbuf);
if (!error && strval != NULL)
set_option_value(varname, numval, strval, OPT_LOCAL);
+
+ // reset notion of buffer
+ aucmd_restbuf(&aco);
} else {
+ buf_T *save_curbuf = curbuf;
+
bufvarname = xmalloc(STRLEN(varname) + 3);
+ curbuf = buf;
STRCPY(bufvarname, "b:");
STRCPY(bufvarname + 2, varname);
set_var(bufvarname, varp, TRUE);
xfree(bufvarname);
+ curbuf = save_curbuf;
}
-
- /* reset notion of buffer */
- aucmd_restbuf(&aco);
}
}
@@ -15516,7 +15529,10 @@ static void f_setreg(typval_T *argvars, typval_T *rettv, FunPtr fptr)
}
if (argvars[1].v_type == VAR_LIST) {
- int len = argvars[1].vval.v_list->lv_len;
+ list_T *ll = argvars[1].vval.v_list;
+ // If the list is NULL handle like an empty list.
+ int len = ll == NULL ? 0 : ll->lv_len;
+
// First half: use for pointers to result lines; second half: use for
// pointers to allocated copies.
char_u **lstval = xmalloc(sizeof(char_u *) * ((len + 1) * 2));
@@ -15525,7 +15541,7 @@ static void f_setreg(typval_T *argvars, typval_T *rettv, FunPtr fptr)
char_u **curallocval = allocval;
char_u buf[NUMBUFLEN];
- for (listitem_T *li = argvars[1].vval.v_list->lv_first;
+ for (listitem_T *li = ll == NULL ? NULL : ll->lv_first;
li != NULL;
li = li->li_next) {
char_u *strval = get_tv_string_buf_chk(&li->li_tv, buf);
@@ -17249,14 +17265,6 @@ static void f_termopen(typval_T *argvars, typval_T *rettv, FunPtr fptr)
return;
}
-/*
- * "test(list)" function: Just checking the walls...
- */
-static void f_test(typval_T *argvars, typval_T *rettv, FunPtr fptr)
-{
- /* Used for unit testing. Change the code below to your liking. */
-}
-
static bool callback_from_typval(Callback *callback, typval_T *arg)
{
if (arg->v_type == VAR_PARTIAL && arg->vval.v_partial != NULL) {
diff --git a/src/nvim/eval.lua b/src/nvim/eval.lua
index 980a8d2326..5fb99fecc6 100644
--- a/src/nvim/eval.lua
+++ b/src/nvim/eval.lua
@@ -302,7 +302,6 @@ return {
tanh={args=1, func="float_op_wrapper", data="&tanh"},
tempname={},
termopen={args={1, 2}},
- test={args=1},
timer_start={args={2,3}},
timer_stop={args=1},
tolower={args=1},
diff --git a/src/nvim/ex_cmds.c b/src/nvim/ex_cmds.c
index fcaf17a0fc..b1a17e8c44 100644
--- a/src/nvim/ex_cmds.c
+++ b/src/nvim/ex_cmds.c
@@ -1611,6 +1611,7 @@ int do_write(exarg_T *eap)
int retval = FAIL;
char_u *free_fname = NULL;
buf_T *alt_buf = NULL;
+ int name_was_missing;
if (not_writing()) /* check 'write' option */
return FAIL;
@@ -1734,6 +1735,7 @@ int do_write(exarg_T *eap)
fname = curbuf->b_sfname;
}
+ name_was_missing = curbuf->b_ffname == NULL;
retval = buf_write(curbuf, ffname, fname, eap->line1, eap->line2,
eap, eap->append, eap->forceit, TRUE, FALSE);
@@ -1743,7 +1745,11 @@ int do_write(exarg_T *eap)
curbuf->b_p_ro = FALSE;
redraw_tabline = TRUE;
}
- /* Change directories when the 'acd' option is set. */
+ }
+
+ // Change directories when the 'acd' option is set and the file name
+ // got changed or set.
+ if (eap->cmdidx == CMD_saveas || name_was_missing) {
do_autochdir();
}
}
diff --git a/src/nvim/ex_docmd.c b/src/nvim/ex_docmd.c
index 79a0b5849f..eccece7ac7 100644
--- a/src/nvim/ex_docmd.c
+++ b/src/nvim/ex_docmd.c
@@ -1374,7 +1374,7 @@ static char_u * do_one_cmd(char_u **cmdlinep,
}
continue;
}
- if (!checkforcmd(&ea.cmd, "noswapfile", 6)) {
+ if (!checkforcmd(&ea.cmd, "noswapfile", 3)) {
break;
}
cmdmod.noswapfile = true;
@@ -1711,7 +1711,7 @@ static char_u * do_one_cmd(char_u **cmdlinep,
xfree(p);
// If the autocommands did something and didn't cause an error, try
// finding the command again.
- p = (ret && !aborting()) ? find_command(&ea, NULL) : NULL;
+ p = (ret && !aborting()) ? find_command(&ea, NULL) : ea.cmd;
}
if (p == NULL) {
diff --git a/src/nvim/fileio.c b/src/nvim/fileio.c
index 529b48adbd..bbfa56dfbf 100644
--- a/src/nvim/fileio.c
+++ b/src/nvim/fileio.c
@@ -5652,13 +5652,14 @@ static event_T event_name2nr(char_u *start, char_u **end)
int i;
int len;
- /* the event name ends with end of line, a blank or a comma */
- for (p = start; *p && !ascii_iswhite(*p) && *p != ','; ++p)
- ;
- for (i = 0; event_names[i].name != NULL; ++i) {
- len = (int) event_names[i].len;
- if (len == p - start && STRNICMP(event_names[i].name, start, len) == 0)
+ // the event name ends with end of line, '|', a blank or a comma */
+ for (p = start; *p && !ascii_iswhite(*p) && *p != ',' && *p != '|'; p++) {
+ }
+ for (i = 0; event_names[i].name != NULL; i++) {
+ len = (int)event_names[i].len;
+ if (len == p - start && STRNICMP(event_names[i].name, start, len) == 0) {
break;
+ }
}
if (*p == ',')
++p;
@@ -5700,7 +5701,7 @@ find_end_event (
}
pat = arg + 1;
} else {
- for (pat = arg; *pat && !ascii_iswhite(*pat); pat = p) {
+ for (pat = arg; *pat && *pat != '|' && !ascii_iswhite(*pat); pat = p) {
if ((int)event_name2nr(pat, &p) >= (int)NUM_EVENTS) {
if (have_group)
EMSG2(_("E216: No such event: %s"), pat);
@@ -5815,8 +5816,9 @@ void au_event_restore(char_u *old_ei)
*
* Mostly a {group} argument can optionally appear before <event>.
*/
-void do_autocmd(char_u *arg, int forceit)
+void do_autocmd(char_u *arg_in, int forceit)
{
+ char_u *arg = arg_in;
char_u *pat;
char_u *envpat = NULL;
char_u *cmd;
@@ -5825,10 +5827,13 @@ void do_autocmd(char_u *arg, int forceit)
int nested = FALSE;
int group;
- /*
- * Check for a legal group name. If not, use AUGROUP_ALL.
- */
- group = au_get_grouparg(&arg);
+ if (*arg == '|') {
+ arg = (char_u *)"";
+ group = AUGROUP_ALL; // no argument, use all groups
+ } else {
+ // Check for a legal group name. If not, use AUGROUP_ALL.
+ group = au_get_grouparg(&arg);
+ }
/*
* Scan over the events.
@@ -5838,50 +5843,54 @@ void do_autocmd(char_u *arg, int forceit)
if (pat == NULL)
return;
- /*
- * Scan over the pattern. Put a NUL at the end.
- */
pat = skipwhite(pat);
- cmd = pat;
- while (*cmd && (!ascii_iswhite(*cmd) || cmd[-1] == '\\'))
- cmd++;
- if (*cmd)
- *cmd++ = NUL;
-
- /* Expand environment variables in the pattern. Set 'shellslash', we want
- * forward slashes here. */
- if (vim_strchr(pat, '$') != NULL || vim_strchr(pat, '~') != NULL) {
+ if (*pat == '|') {
+ pat = (char_u *)"";
+ cmd = (char_u *)"";
+ } else {
+ // Scan over the pattern. Put a NUL at the end.
+ cmd = pat;
+ while (*cmd && (!ascii_iswhite(*cmd) || cmd[-1] == '\\')) {
+ cmd++;
+ }
+ if (*cmd) {
+ *cmd++ = NUL;
+ }
+
+ // Expand environment variables in the pattern. Set 'shellslash', we want
+ // forward slashes here.
+ if (vim_strchr(pat, '$') != NULL || vim_strchr(pat, '~') != NULL) {
#ifdef BACKSLASH_IN_FILENAME
- int p_ssl_save = p_ssl;
+ int p_ssl_save = p_ssl;
- p_ssl = TRUE;
+ p_ssl = true;
#endif
- envpat = expand_env_save(pat);
+ envpat = expand_env_save(pat);
#ifdef BACKSLASH_IN_FILENAME
- p_ssl = p_ssl_save;
+ p_ssl = p_ssl_save;
#endif
- if (envpat != NULL)
- pat = envpat;
- }
+ if (envpat != NULL) {
+ pat = envpat;
+ }
+ }
- /*
- * Check for "nested" flag.
- */
- cmd = skipwhite(cmd);
- if (*cmd != NUL && STRNCMP(cmd, "nested", 6) == 0 && ascii_iswhite(cmd[6])) {
- nested = TRUE;
- cmd = skipwhite(cmd + 6);
- }
+ // Check for "nested" flag.
+ cmd = skipwhite(cmd);
+ if (*cmd != NUL && STRNCMP(cmd, "nested", 6) == 0
+ && ascii_iswhite(cmd[6])) {
+ nested = true;
+ cmd = skipwhite(cmd + 6);
+ }
- /*
- * Find the start of the commands.
- * Expand <sfile> in it.
- */
- if (*cmd != NUL) {
- cmd = expand_sfile(cmd);
- if (cmd == NULL) /* some error */
- return;
- need_free = TRUE;
+ // Find the start of the commands.
+ // Expand <sfile> in it.
+ if (*cmd != NUL) {
+ cmd = expand_sfile(cmd);
+ if (cmd == NULL) { // some error
+ return;
+ }
+ need_free = true;
+ }
}
/*
@@ -5895,16 +5904,17 @@ void do_autocmd(char_u *arg, int forceit)
/*
* Loop over the events.
*/
- last_event = (event_T)-1; /* for listing the event name */
- last_group = AUGROUP_ERROR; /* for listing the group name */
- if (*arg == '*' || *arg == NUL) {
+ last_event = (event_T)-1; // for listing the event name
+ last_group = AUGROUP_ERROR; // for listing the group name
+ if (*arg == '*' || *arg == NUL || *arg == '|') {
for (event = (event_T)0; (int)event < (int)NUM_EVENTS;
- event = (event_T)((int)event + 1))
- if (do_autocmd_event(event, pat,
- nested, cmd, forceit, group) == FAIL)
+ event = (event_T)((int)event + 1)) {
+ if (do_autocmd_event(event, pat, nested, cmd, forceit, group) == FAIL) {
break;
+ }
+ }
} else {
- while (*arg && !ascii_iswhite(*arg)) {
+ while (*arg && *arg != '|' && !ascii_iswhite(*arg)) {
event_T event = event_name2nr(arg, &arg);
assert(event < NUM_EVENTS);
if (do_autocmd_event(event, pat, nested, cmd, forceit, group) == FAIL) {
@@ -5931,7 +5941,8 @@ static int au_get_grouparg(char_u **argp)
char_u *arg = *argp;
int group = AUGROUP_ALL;
- p = skiptowhite(arg);
+ for (p = arg; *p && !ascii_iswhite(*p) && *p != '|'; p++) {
+ }
if (p > arg) {
group_name = vim_strnsave(arg, (int)(p - arg));
group = au_find_group(group_name);
diff --git a/src/nvim/os/time.c b/src/nvim/os/time.c
index 2205ad0958..8ce2ecf4f4 100644
--- a/src/nvim/os/time.c
+++ b/src/nvim/os/time.c
@@ -7,6 +7,7 @@
#include <uv.h>
#include "nvim/os/time.h"
+#include "nvim/os/input.h"
#include "nvim/event/loop.h"
#include "nvim/vim.h"
#include "nvim/main.h"
@@ -34,10 +35,10 @@ uint64_t os_hrtime(void)
return uv_hrtime();
}
-/// Sleeps for a certain amount of milliseconds
+/// Sleeps for a certain amount of milliseconds.
///
/// @param milliseconds Number of milliseconds to sleep
-/// @param ignoreinput If true, allow a SIGINT to interrupt us
+/// @param ignoreinput If true, only SIGINT (CTRL-C) can interrupt.
void os_delay(uint64_t milliseconds, bool ignoreinput)
{
if (ignoreinput) {
@@ -46,26 +47,42 @@ void os_delay(uint64_t milliseconds, bool ignoreinput)
}
LOOP_PROCESS_EVENTS_UNTIL(&main_loop, NULL, (int)milliseconds, got_int);
} else {
- os_microdelay(milliseconds * 1000);
+ os_microdelay(milliseconds * 1000u, ignoreinput);
}
}
-/// Sleeps for a certain amount of microseconds
+/// Sleeps for a certain amount of microseconds.
///
-/// @param microseconds Number of microseconds to sleep
-void os_microdelay(uint64_t microseconds)
+/// @param ms Number of microseconds to sleep.
+/// @param ignoreinput If true, ignore all input (including SIGINT/CTRL-C).
+/// If false, waiting is aborted on any input.
+void os_microdelay(uint64_t ms, bool ignoreinput)
{
- uint64_t elapsed = 0;
- uint64_t ns = microseconds * 1000; // convert to nanoseconds
+ uint64_t elapsed = 0u;
uint64_t base = uv_hrtime();
+ // Convert microseconds to nanoseconds, or UINT64_MAX on overflow.
+ const uint64_t ns = (ms < UINT64_MAX / 1000u) ? ms * 1000u : UINT64_MAX;
uv_mutex_lock(&delay_mutex);
while (elapsed < ns) {
- if (uv_cond_timedwait(&delay_cond, &delay_mutex, ns - elapsed)
- == UV_ETIMEDOUT)
+ // If ignoring input, we simply wait the full delay.
+ // Else we check for input in ~100ms intervals.
+ const uint64_t ns_delta = ignoreinput
+ ? ns - elapsed
+ : MIN(ns - elapsed, 100000000u); // 100ms
+
+ const int rv = uv_cond_timedwait(&delay_cond, &delay_mutex, ns_delta);
+ if (0 != rv && UV_ETIMEDOUT != rv) {
+ assert(false);
+ break;
+ } // Else: Timeout proceeded normally.
+
+ if (!ignoreinput && os_char_avail()) {
break;
- uint64_t now = uv_hrtime();
+ }
+
+ const uint64_t now = uv_hrtime();
elapsed += now - base;
base = now;
}
diff --git a/src/nvim/path.c b/src/nvim/path.c
index 6149e1ab99..3d1def8dd4 100644
--- a/src/nvim/path.c
+++ b/src/nvim/path.c
@@ -417,15 +417,11 @@ char *FullName_save(char *fname, bool force)
}
char *buf = xmalloc(MAXPATHL);
- char *new_fname = NULL;
- if (vim_FullName(fname, buf, MAXPATHL, force) != FAIL) {
- new_fname = xstrdup(buf);
- } else {
- new_fname = xstrdup(fname);
+ if (vim_FullName(fname, buf, MAXPATHL, force) == FAIL) {
+ xfree(buf);
+ return xstrdup(fname);
}
- xfree(buf);
-
- return new_fname;
+ return buf;
}
/// Saves the absolute path.
@@ -1649,30 +1645,37 @@ bool vim_isAbsName(char_u *name)
/// Save absolute file name to "buf[len]".
///
-/// @param fname is the filename to evaluate
-/// @param[out] buf is the buffer for returning the absolute path for `fname`
-/// @param len is the length of `buf`
-/// @param force is a flag to force expanding even if the path is absolute
+/// @param fname filename to evaluate
+/// @param[out] buf contains `fname` absolute path, or:
+/// - truncated `fname` if longer than `len`
+/// - unmodified `fname` if absolute path fails or is a URL
+/// @param len length of `buf`
+/// @param force flag to force expanding even if the path is absolute
///
/// @return FAIL for failure, OK otherwise
int vim_FullName(const char *fname, char *buf, size_t len, bool force)
FUNC_ATTR_NONNULL_ARG(2)
{
- int retval = OK;
- int url;
-
*buf = NUL;
- if (fname == NULL)
+ if (fname == NULL) {
return FAIL;
+ }
- url = path_with_url(fname);
- if (!url)
- retval = path_get_absolute_path((char_u *)fname, (char_u *)buf, len, force);
- if (url || retval == FAIL) {
- /* something failed; use the file name (truncate when too long) */
+ if (strlen(fname) > (len - 1)) {
+ xstrlcpy(buf, fname, len); // truncate
+ return FAIL;
+ }
+
+ if (path_with_url(fname)) {
xstrlcpy(buf, fname, len);
+ return OK;
}
- return retval;
+
+ int rv = path_get_absolute_path((char_u *)fname, (char_u *)buf, len, force);
+ if (rv == FAIL) {
+ xstrlcpy(buf, fname, len); // something failed; use the filename
+ }
+ return rv;
}
/// Get the full resolved path for `fname`
diff --git a/src/nvim/testdir/Makefile b/src/nvim/testdir/Makefile
index 84a0c0b889..612071e2e2 100644
--- a/src/nvim/testdir/Makefile
+++ b/src/nvim/testdir/Makefile
@@ -43,8 +43,8 @@ NEW_TESTS = \
test_quickfix.res \
test_signs.res \
test_syntax.res \
- test_usercommands.res \
test_timers.res \
+ test_usercommands.res \
test_viml.res \
test_visual.res \
test_window_id.res \
diff --git a/src/nvim/testdir/test_autocmd.vim b/src/nvim/testdir/test_autocmd.vim
index 1dceb70cd4..5675697dc4 100644
--- a/src/nvim/testdir/test_autocmd.vim
+++ b/src/nvim/testdir/test_autocmd.vim
@@ -19,6 +19,7 @@ if has('timers')
call timer_start(100, 'ExitInsertMode')
call feedkeys('a', 'x!')
call assert_equal(1, g:triggered)
+ au! CursorHoldI
endfunc
func Test_cursorhold_insert_ctrl_x()
@@ -29,6 +30,7 @@ if has('timers')
" CursorHoldI does not trigger after CTRL-X
call feedkeys("a\<C-X>", 'x!')
call assert_equal(0, g:triggered)
+ au! CursorHoldI
endfunc
endif
@@ -58,5 +60,34 @@ function Test_bufunload()
bwipeout
call assert_equal(["bufunload", "bufdelete", "bufwipeout"], s:li)
+ au! test_bufunload_group
augroup! test_bufunload_group
endfunc
+
+func s:AddAnAutocmd()
+ augroup vimBarTest
+ au BufReadCmd * echo 'hello'
+ augroup END
+ call assert_equal(3, len(split(execute('au vimBarTest'), "\n")))
+endfunc
+
+func Test_early_bar()
+ " test that a bar is recognized before the {event}
+ call s:AddAnAutocmd()
+ augroup vimBarTest | au! | augroup END
+ call assert_equal(1, len(split(execute('au vimBarTest'), "\n")))
+
+ call s:AddAnAutocmd()
+ augroup vimBarTest| au!| augroup END
+ call assert_equal(1, len(split(execute('au vimBarTest'), "\n")))
+
+ " test that a bar is recognized after the {event}
+ call s:AddAnAutocmd()
+ augroup vimBarTest| au!BufReadCmd| augroup END
+ call assert_equal(1, len(split(execute('au vimBarTest'), "\n")))
+
+ " test that a bar is recognized after the {group}
+ call s:AddAnAutocmd()
+ au! vimBarTest|echo 'hello'
+ call assert_equal(1, len(split(execute('au vimBarTest'), "\n")))
+endfunc
diff --git a/src/nvim/testdir/test_expr.vim b/src/nvim/testdir/test_expr.vim
index 571a37c62c..7483973fca 100644
--- a/src/nvim/testdir/test_expr.vim
+++ b/src/nvim/testdir/test_expr.vim
@@ -81,3 +81,14 @@ func Test_loop_over_null_list()
call assert_true(0, 'should not get here')
endfor
endfunc
+
+func Test_compare_null_dict()
+ call assert_fails('let x = v:_null_dict[10]')
+ call assert_equal({}, {})
+ call assert_equal(v:_null_dict, v:_null_dict)
+ call assert_notequal({}, v:_null_dict)
+endfunc
+
+func Test_set_reg_null_list()
+ call setreg('x', v:_null_list)
+endfunc
diff --git a/src/nvim/testdir/test_usercommands.vim b/src/nvim/testdir/test_usercommands.vim
index f593d16dbf..d0864ec64c 100644
--- a/src/nvim/testdir/test_usercommands.vim
+++ b/src/nvim/testdir/test_usercommands.vim
@@ -8,31 +8,57 @@ function Test_cmdmods()
MyCmd
aboveleft MyCmd
+ abo MyCmd
belowright MyCmd
+ bel MyCmd
botright MyCmd
+ bo MyCmd
browse MyCmd
+ bro MyCmd
confirm MyCmd
+ conf MyCmd
hide MyCmd
+ hid MyCmd
keepalt MyCmd
+ keepa MyCmd
keepjumps MyCmd
+ keepj MyCmd
keepmarks MyCmd
+ kee MyCmd
keeppatterns MyCmd
+ keepp MyCmd
+ leftabove MyCmd " results in :aboveleft
+ lefta MyCmd
lockmarks MyCmd
+ loc MyCmd
+ " noautocmd MyCmd
noswapfile MyCmd
+ nos MyCmd
+ rightbelow MyCmd " results in :belowright
+ rightb MyCmd
+ " sandbox MyCmd
silent MyCmd
+ sil MyCmd
tab MyCmd
topleft MyCmd
+ to MyCmd
+ " unsilent MyCmd
verbose MyCmd
+ verb MyCmd
vertical MyCmd
+ vert MyCmd
aboveleft belowright botright browse confirm hide keepalt keepjumps
\ keepmarks keeppatterns lockmarks noswapfile silent tab
\ topleft verbose vertical MyCmd
- call assert_equal(' aboveleft belowright botright browse confirm ' .
- \ 'hide keepalt keepjumps keepmarks keeppatterns lockmarks ' .
- \ 'noswapfile silent tab topleft verbose vertical aboveleft ' .
- \ 'belowright botright browse confirm hide keepalt keepjumps ' .
+ call assert_equal(' aboveleft aboveleft belowright belowright botright ' .
+ \ 'botright browse browse confirm confirm hide hide ' .
+ \ 'keepalt keepalt keepjumps keepjumps keepmarks keepmarks ' .
+ \ 'keeppatterns keeppatterns aboveleft aboveleft lockmarks lockmarks noswapfile ' .
+ \ 'noswapfile belowright belowright silent silent tab topleft topleft verbose verbose ' .
+ \ 'vertical vertical ' .
+ \ 'aboveleft belowright botright browse confirm hide keepalt keepjumps ' .
\ 'keepmarks keeppatterns lockmarks noswapfile silent tab topleft ' .
\ 'verbose vertical ', g:mods)
@@ -46,3 +72,33 @@ function Test_cmdmods()
delcommand MyQCmd
unlet g:mods
endfunction
+
+func Test_Ambiguous()
+ command Doit let g:didit = 'yes'
+ command Dothat let g:didthat = 'also'
+ call assert_fails('Do', 'E464:')
+ Doit
+ call assert_equal('yes', g:didit)
+ Dothat
+ call assert_equal('also', g:didthat)
+ unlet g:didit
+ unlet g:didthat
+
+ delcommand Doit
+ Do
+ call assert_equal('also', g:didthat)
+ delcommand Dothat
+endfunc
+
+func Test_CmdUndefined()
+ call assert_fails('Doit', 'E492:')
+ au CmdUndefined Doit :command Doit let g:didit = 'yes'
+ Doit
+ call assert_equal('yes', g:didit)
+ delcommand Doit
+
+ call assert_fails('Dothat', 'E492:')
+ au CmdUndefined * let g:didnot = 'yes'
+ call assert_fails('Dothat', 'E492:')
+ call assert_equal('yes', g:didnot)
+endfunc
diff --git a/src/nvim/version.c b/src/nvim/version.c
index f6f984bc8b..19062be730 100644
--- a/src/nvim/version.c
+++ b/src/nvim/version.c
@@ -313,7 +313,7 @@ static int included_patches[] = {
// 2130 NA
// 2129 NA
2128,
- // 2127,
+ 2127,
2126,
// 2125 NA
2124,
@@ -330,14 +330,14 @@ static int included_patches[] = {
// 2113,
2112,
// 2111,
- // 2110,
+ 2110,
2109,
// 2108 NA
// 2107,
// 2106,
// 2105 NA
// 2104,
- // 2103,
+ 2103,
// 2102 NA
// 2101,
// 2100,
@@ -397,7 +397,7 @@ static int included_patches[] = {
// 2046,
// 2045 NA
// 2044,
- // 2043,
+ 2043,
// 2042 NA
// 2041 NA
// 2040 NA
@@ -425,7 +425,7 @@ static int included_patches[] = {
// 2018,
// 2017,
// 2016 NA
- // 2015,
+ 2015,
2014,
2013,
2012,
@@ -593,7 +593,7 @@ static int included_patches[] = {
// 1850 NA
// 1849 NA
// 1848 NA
- // 1847,
+ 1847,
// 1846 NA
// 1845 NA
// 1844 NA
@@ -602,7 +602,7 @@ static int included_patches[] = {
1841,
1840,
1839,
- // 1838 NA
+ 1838,
1837,
1836,
1835,
@@ -689,7 +689,6 @@ static int included_patches[] = {
1755,
1754,
1753,
- // 1753,
1752,
1751,
// 1750 NA
diff --git a/test/functional/ex_cmds/ctrl_c_spec.lua b/test/functional/ex_cmds/ctrl_c_spec.lua
new file mode 100644
index 0000000000..b0acb02000
--- /dev/null
+++ b/test/functional/ex_cmds/ctrl_c_spec.lua
@@ -0,0 +1,62 @@
+local helpers = require('test.functional.helpers')(after_each)
+local Screen = require('test.functional.ui.screen')
+local clear, feed, source = helpers.clear, helpers.feed, helpers.source
+local execute = helpers.execute
+
+if helpers.pending_win32(pending) then return end
+
+describe("CTRL-C (mapped)", function()
+ before_each(function()
+ clear()
+ end)
+
+ it("interrupts :global", function()
+ if helpers.skip_fragile(pending,
+ (os.getenv("TRAVIS") and os.getenv("CLANG_SANITIZER") == "ASAN_UBSAN"))
+ then
+ return
+ end
+
+ source([[
+ set nomore nohlsearch undolevels=-1
+ nnoremap <C-C> <NOP>
+ ]])
+
+ execute("silent edit! test/functional/fixtures/bigfile.txt")
+ local screen = Screen.new(52, 6)
+ screen:attach()
+ screen:set_default_attr_ids({
+ [0] = {foreground = Screen.colors.White,
+ background = Screen.colors.Red},
+ [1] = {bold = true,
+ foreground = Screen.colors.SeaGreen}
+ })
+
+ screen:expect([[
+ ^0000;<control>;Cc;0;BN;;;;;N;NULL;;;; |
+ 0001;<control>;Cc;0;BN;;;;;N;START OF HEADING;;;; |
+ 0002;<control>;Cc;0;BN;;;;;N;START OF TEXT;;;; |
+ 0003;<control>;Cc;0;BN;;;;;N;END OF TEXT;;;; |
+ 0004;<control>;Cc;0;BN;;;;;N;END OF TRANSMISSION;;;;|
+ |
+ ]])
+
+ local function test_ctrl_c(ms)
+ feed(":global/^/p<CR>")
+ helpers.sleep(ms)
+ feed("<C-C>")
+ screen:expect([[Interrupt]], nil, nil, nil, true)
+ end
+
+ -- The test is time-sensitive. Try different sleep values.
+ local ms_values = {1, 10, 100}
+ for i, ms in ipairs(ms_values) do
+ if i < #ms_values then
+ local status, _ = pcall(test_ctrl_c, ms)
+ if status then break end
+ else -- Call the last attempt directly.
+ test_ctrl_c(ms)
+ end
+ end
+ end)
+end)
diff --git a/test/functional/ex_cmds/global_spec.lua b/test/functional/ex_cmds/global_spec.lua
deleted file mode 100644
index 81a0ef3248..0000000000
--- a/test/functional/ex_cmds/global_spec.lua
+++ /dev/null
@@ -1,74 +0,0 @@
-local helpers = require('test.functional.helpers')(after_each)
-local Screen = require('test.functional.ui.screen')
-local clear, feed, source = helpers.clear, helpers.feed, helpers.source
-
-if helpers.pending_win32(pending) then return end
-
-describe(':global', function()
- before_each(function()
- clear()
- end)
-
- it('is interrupted by mapped CTRL-C', function()
- if os.getenv("TRAVIS") and os.getenv("CLANG_SANITIZER") == "ASAN_UBSAN" then
- -- XXX: ASAN_UBSAN is too slow to react to the CTRL-C.
- pending("", function() end)
- return
- end
-
- source([[
- set nomore
- set undolevels=-1
- nnoremap <C-C> <NOP>
- for i in range(0, 99999)
- put ='XXX'
- endfor
- put ='ZZZ'
- 1
- .delete
- ]])
-
- local screen = Screen.new(52, 6)
- screen:attach()
- screen:set_default_attr_ids({
- [0] = {foreground = Screen.colors.White,
- background = Screen.colors.Red},
- [1] = {bold = true,
- foreground = Screen.colors.SeaGreen}
- })
-
- screen:expect([[
- ^XXX |
- XXX |
- XXX |
- XXX |
- XXX |
- |
- ]])
-
- local function test_ctrl_c(ms)
- feed(":global/^/p<CR>")
- helpers.sleep(ms)
- feed("<C-C>")
- screen:expect([[
- XXX |
- XXX |
- XXX |
- XXX |
- {0:Interrupted} |
- Interrupt: {1:Press ENTER or type command to continue}^ |
- ]])
- end
-
- -- The test is time-sensitive. Try with different sleep values.
- local ms_values = {10, 50, 100}
- for i, ms in ipairs(ms_values) do
- if i < #ms_values then
- local status, _ = pcall(test_ctrl_c, ms)
- if status then break end
- else -- Call the last attempt directly.
- test_ctrl_c(ms)
- end
- end
- end)
-end)
diff --git a/test/functional/helpers.lua b/test/functional/helpers.lua
index f3332cff4f..5eec3afe65 100644
--- a/test/functional/helpers.lua
+++ b/test/functional/helpers.lua
@@ -14,6 +14,7 @@ local neq = global_helpers.neq
local eq = global_helpers.eq
local ok = global_helpers.ok
+local start_dir = lfs.currentdir()
local nvim_prog = os.getenv('NVIM_PROG') or 'build/bin/nvim'
local nvim_argv = {nvim_prog, '-u', 'NONE', '-i', 'NONE', '-N',
'--cmd', 'set shortmess+=I background=light noswapfile noautoindent laststatus=1 undodir=. directory=. viewdir=. backupdir=.',
@@ -21,6 +22,9 @@ local nvim_argv = {nvim_prog, '-u', 'NONE', '-i', 'NONE', '-N',
local mpack = require('mpack')
+local tmpname = global_helpers.tmpname
+local uname = global_helpers.uname
+
-- Formulate a path to the directory containing nvim. We use this to
-- help run test executables. It helps to keep the tests working, even
-- when the build is not in the default location.
@@ -334,44 +338,6 @@ local function write_file(name, text, dont_dedent)
file:close()
end
--- Tries to get platform name from $SYSTEM_NAME, uname; fallback is "Windows".
-local uname = (function()
- local platform = nil
- return (function()
- if platform then
- return platform
- end
-
- platform = os.getenv("SYSTEM_NAME")
- if platform then
- return platform
- end
-
- local status, f = pcall(io.popen, "uname -s")
- if status then
- platform = f:read("*l")
- else
- platform = 'Windows'
- end
- return platform
- end)
-end)()
-
-local function tmpname()
- local fname = os.tmpname()
- if uname() == 'Windows' and fname:sub(1, 2) == '\\s' then
- -- In Windows tmpname() returns a filename starting with
- -- special sequence \s, prepend $TEMP path
- local tmpdir = os.getenv('TEMP')
- return tmpdir..fname
- elseif fname:match('^/tmp') and uname() == 'Darwin' then
- -- In OS X /tmp links to /private/tmp
- return '/private'..fname
- else
- return fname
- end
-end
-
local function source(code)
local fname = tmpname()
write_file(fname, code)
@@ -475,6 +441,12 @@ end
local function rmdir(path)
local ret, _ = pcall(do_rmdir, path)
+ if not ret and os_name() == "windows" then
+ -- Maybe "Permission denied"; try again after changing the nvim
+ -- process to the top-level directory.
+ nvim_command([[exe 'cd '.fnameescape(']]..start_dir.."')")
+ ret, _ = pcall(do_rmdir, path)
+ end
-- During teardown, the nvim process may not exit quickly enough, then rmdir()
-- will fail (on Windows).
if not ret then -- Try again.
@@ -520,12 +492,12 @@ local function create_callindex(func)
end
-- Helper to skip tests. Returns true in Windows systems.
--- pending_func is pending() from busted
-local function pending_win32(pending_func)
+-- pending_fn is pending() from busted
+local function pending_win32(pending_fn)
clear()
if uname() == 'Windows' then
- if pending_func ~= nil then
- pending_func('FIXME: Windows', function() end)
+ if pending_fn ~= nil then
+ pending_fn('FIXME: Windows', function() end)
end
return true
else
@@ -533,6 +505,22 @@ local function pending_win32(pending_func)
end
end
+-- Calls pending() and returns `true` if the system is too slow to
+-- run fragile or expensive tests. Else returns `false`.
+local function skip_fragile(pending_fn, cond)
+ if pending_fn == nil or type(pending_fn) ~= type(function()end) then
+ error("invalid pending_fn")
+ end
+ if cond then
+ pending_fn("skipped (test is fragile on this system)", function() end)
+ return true
+ elseif os.getenv("TEST_SKIP_FRAGILE") then
+ pending_fn("skipped (TEST_SKIP_FRAGILE)", function() end)
+ return true
+ end
+ return false
+end
+
local funcs = create_callindex(nvim_call)
local meths = create_callindex(nvim)
local uimeths = create_callindex(ui)
@@ -601,6 +589,7 @@ return function(after_each)
curwinmeths = curwinmeths,
curtabmeths = curtabmeths,
pending_win32 = pending_win32,
+ skip_fragile = skip_fragile,
tmpname = tmpname,
NIL = mpack.NIL,
}
diff --git a/test/functional/legacy/autochdir_spec.lua b/test/functional/legacy/autochdir_spec.lua
new file mode 100644
index 0000000000..06f7c1dd11
--- /dev/null
+++ b/test/functional/legacy/autochdir_spec.lua
@@ -0,0 +1,26 @@
+local lfs = require('lfs')
+local helpers = require('test.functional.helpers')(after_each)
+local clear, eq = helpers.clear, helpers.eq
+local eval, execute = helpers.eval, helpers.execute
+
+describe('autochdir behavior', function()
+ local dir = 'Xtest-functional-legacy-autochdir'
+
+ before_each(function()
+ lfs.mkdir(dir)
+ clear()
+ end)
+
+ after_each(function()
+ helpers.rmdir(dir)
+ end)
+
+ -- Tests vim/vim/777 without test_autochdir().
+ it('sets filename', function()
+ execute('set acd')
+ execute('new')
+ execute('w '..dir..'/Xtest')
+ eq('Xtest', eval("expand('%')"))
+ eq(dir, eval([[substitute(getcwd(), '.*[/\\]\(\k*\)', '\1', '')]]))
+ end)
+end)
diff --git a/test/functional/plugin/msgpack_spec.lua b/test/functional/plugin/msgpack_spec.lua
index c8da8e8f6c..5ba19708cf 100644
--- a/test/functional/plugin/msgpack_spec.lua
+++ b/test/functional/plugin/msgpack_spec.lua
@@ -652,6 +652,8 @@ describe('In autoload/msgpack.vim', function()
eval_eq('integer', ('a'):byte(), '\'a\'')
eval_eq('integer', 0xAB, '\'«\'')
+ eval_eq('integer', 0, '\'\\0\'')
+ eval_eq('integer', 10246567, '\'\\10246567\'')
end)
it('correctly loads constants', function()
diff --git a/test/functional/plugin/shada_spec.lua b/test/functional/plugin/shada_spec.lua
index b1209a22e9..b543037ae2 100644
--- a/test/functional/plugin/shada_spec.lua
+++ b/test/functional/plugin/shada_spec.lua
@@ -609,6 +609,18 @@ describe('In autoload/shada.vim', function()
'abc',
-1,
]}] ]]):gsub('\n', ''))
+ -- Regression: NUL separator must be properly supported
+ sd2strings_eq({
+ 'History entry with timestamp ' .. epoch .. ':',
+ ' @ Description_ Value',
+ ' - history type SEARCH',
+ ' - contents ""',
+ ' - separator \'\\0\'',
+ }, ([[ [{'type': 4, 'timestamp': 0, 'data': [
+ 1,
+ '',
+ 0x0
+ ]}] ]]):gsub('\n', ''))
end)
it('works with register items', function()
@@ -837,7 +849,7 @@ describe('In autoload/shada.vim', function()
sd2strings_eq({
'Global mark with timestamp ' .. epoch .. ':',
' % Key Description Value',
- ' + n name 20',
+ ' + n name \'\\20\'',
' + f file name "foo"',
' # Value is negative',
' + l line number -10',
@@ -852,7 +864,18 @@ describe('In autoload/shada.vim', function()
sd2strings_eq({
'Global mark with timestamp ' .. epoch .. ':',
' % Key Description Value',
- ' + n name 20',
+ ' + n name 128',
+ ' + f file name "foo"',
+ ' + l line number 1',
+ ' + c column 0',
+ }, ([[ [{'type': 7, 'timestamp': 0, 'data': {
+ 'n': 128,
+ 'f': 'foo',
+ }}] ]]):gsub('\n', ''))
+ sd2strings_eq({
+ 'Global mark with timestamp ' .. epoch .. ':',
+ ' % Key Description Value',
+ ' + n name \'\\20\'',
' + f file name "foo"',
' # Expected integer',
' + l line number "FOO"',
@@ -1123,7 +1146,7 @@ describe('In autoload/shada.vim', function()
'Local mark with timestamp ' .. epoch .. ':',
' % Key Description Value',
' + f file name "foo"',
- ' + n name 20',
+ ' + n name \'\\20\'',
' # Value is negative',
' + l line number -10',
' # Value is negative',
@@ -1138,7 +1161,7 @@ describe('In autoload/shada.vim', function()
'Local mark with timestamp ' .. epoch .. ':',
' % Key Description Value',
' + f file name "foo"',
- ' + n name 20',
+ ' + n name \'\\20\'',
' # Expected integer',
' + l line number "FOO"',
' # Expected integer',
@@ -1932,13 +1955,13 @@ describe('In autoload/shada.vim', function()
'Buffer list with timestamp ' .. epoch .. ':',
' % Key Description Value',
' # Expected binary string',
- ' + f file name 10',
+ ' + f file name \'\\10\'',
' + l line number 1',
' + c column 0',
'',
' % Key Description Value',
' # Expected binary string',
- ' + f file name 20',
+ ' + f file name \'\\20\'',
' + l line number 1',
' + c column 0',
})
@@ -1948,7 +1971,7 @@ describe('In autoload/shada.vim', function()
'Buffer list with timestamp ' .. epoch .. ':',
' % Key Description Value',
' # Expected binary string',
- ' + f file name 10',
+ ' + f file name \'\\10\'',
' + l line number 1',
' + c column 0',
'',
diff --git a/test/functional/ui/mouse_spec.lua b/test/functional/ui/mouse_spec.lua
index b729b0db08..17d949825a 100644
--- a/test/functional/ui/mouse_spec.lua
+++ b/test/functional/ui/mouse_spec.lua
@@ -153,9 +153,10 @@ describe('Mouse input', function()
end)
it('in tabline to the left moves tab left', function()
- if os.getenv("TRAVIS") and (helpers.os_name() == "osx"
- or os.getenv("CLANG_SANITIZER") == "ASAN_UBSAN") then
- pending("[Fails on Travis macOS, ASAN_UBSAN. #4874]", function() end)
+ if helpers.skip_fragile(pending,
+ os.getenv("TRAVIS") and (helpers.os_name() == "osx"
+ or os.getenv("CLANG_SANITIZER") == "ASAN_UBSAN")) -- #4874
+ then
return
end
@@ -257,9 +258,10 @@ describe('Mouse input', function()
end)
it('out of tabline to the left moves tab left', function()
- if os.getenv("TRAVIS") and (helpers.os_name() == "osx"
- or os.getenv("CLANG_SANITIZER") == "ASAN_UBSAN") then
- pending("[Fails on Travis macOS, ASAN_UBSAN. #4874]", function() end)
+ if helpers.skip_fragile(pending,
+ os.getenv("TRAVIS") and (helpers.os_name() == "osx"
+ or os.getenv("CLANG_SANITIZER") == "ASAN_UBSAN")) -- #4874
+ then
return
end
diff --git a/test/helpers.lua b/test/helpers.lua
index 4c50c7644f..0bc62da5d7 100644
--- a/test/helpers.lua
+++ b/test/helpers.lua
@@ -52,9 +52,49 @@ local function check_logs()
assert(0 == runtime_errors)
end
+-- Tries to get platform name from $SYSTEM_NAME, uname; fallback is "Windows".
+local uname = (function()
+ local platform = nil
+ return (function()
+ if platform then
+ return platform
+ end
+
+ platform = os.getenv("SYSTEM_NAME")
+ if platform then
+ return platform
+ end
+
+ local status, f = pcall(io.popen, "uname -s")
+ if status then
+ platform = f:read("*l")
+ else
+ platform = 'Windows'
+ end
+ return platform
+ end)
+end)()
+
+local function tmpname()
+ local fname = os.tmpname()
+ if uname() == 'Windows' and fname:sub(1, 2) == '\\s' then
+ -- In Windows tmpname() returns a filename starting with
+ -- special sequence \s, prepend $TEMP path
+ local tmpdir = os.getenv('TEMP')
+ return tmpdir..fname
+ elseif fname:match('^/tmp') and uname() == 'Darwin' then
+ -- In OS X /tmp links to /private/tmp
+ return '/private'..fname
+ else
+ return fname
+ end
+end
+
return {
eq = eq,
neq = neq,
ok = ok,
check_logs = check_logs,
+ uname = uname,
+ tmpname = tmpname,
}
diff --git a/test/unit/formatc.lua b/test/unit/formatc.lua
index 00637e0b8d..e288081960 100644
--- a/test/unit/formatc.lua
+++ b/test/unit/formatc.lua
@@ -219,13 +219,7 @@ local function standalone(...) -- luacheck: ignore
Preprocess.add_to_include_path('./../../build/include')
Preprocess.add_to_include_path('./../../.deps/usr/include')
- local input = Preprocess.preprocess_stream(arg[1])
- local raw = input:read('*all')
- input:close()
-
- if raw == nil then
- print("ERROR: Preprocess.preprocess_stream():read() returned empty")
- end
+ local raw = Preprocess.preprocess('', arg[1])
local formatted
if #arg == 2 and arg[2] == 'no' then
diff --git a/test/unit/helpers.lua b/test/unit/helpers.lua
index 9025c64570..45bbaaeb10 100644
--- a/test/unit/helpers.lua
+++ b/test/unit/helpers.lua
@@ -45,6 +45,8 @@ local function filter_complex_blocks(body)
return table.concat(result, "\n")
end
+local previous_defines = ''
+
-- use this helper to import C files, you can pass multiple paths at once,
-- this helper will return the C namespace of the nvim library.
local function cimport(...)
@@ -66,17 +68,8 @@ local function cimport(...)
return libnvim
end
- local body = nil
- for _ = 1, 10 do
- local stream = Preprocess.preprocess_stream(unpack(paths))
- body = stream:read("*a")
- stream:close()
- if body ~= nil then break end
- end
-
- if body == nil then
- print("ERROR: helpers.lua: Preprocess.preprocess_stream():read() returned empty")
- end
+ local body
+ body, previous_defines = Preprocess.preprocess(previous_defines, unpack(paths))
-- format it (so that the lines are "unique" statements), also filter out
-- Objective-C blocks
diff --git a/test/unit/path_spec.lua b/test/unit/path_spec.lua
index 9b76834383..ccaf0228ab 100644
--- a/test/unit/path_spec.lua
+++ b/test/unit/path_spec.lua
@@ -336,6 +336,17 @@ describe('more path function', function()
eq(FAIL, result)
end)
+ it('fails safely if given length is wrong #5737', function()
+ local force_expansion = 1
+ local filename = 'foo/bar/bazzzzzzz/buz/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/a'
+ local too_short_len = 8
+ local buf = cstr(too_short_len, '')
+ local result = path.vim_FullName(filename, buf, too_short_len, force_expansion)
+ local expected = string.sub(filename, 1, (too_short_len - 1))
+ eq(expected, (ffi.string(buf)))
+ eq(FAIL, result)
+ end)
+
it('uses the filename if the filename is a URL', function()
local force_expansion = 1
local filename = 'http://www.neovim.org'
diff --git a/test/unit/preprocess.lua b/test/unit/preprocess.lua
index 10ba997758..8c2a5c73e5 100644
--- a/test/unit/preprocess.lua
+++ b/test/unit/preprocess.lua
@@ -7,22 +7,22 @@ local ccs = {}
local env_cc = os.getenv("CC")
if env_cc then
- table.insert(ccs, {path = "/usr/bin/env " .. tostring(env_cc), type = "gcc"})
+ table.insert(ccs, {path = {"/usr/bin/env", env_cc}, type = "gcc"})
end
if ffi.os == "Windows" then
- table.insert(ccs, {path = "cl", type = "msvc"})
+ table.insert(ccs, {path = {"cl"}, type = "msvc"})
end
-table.insert(ccs, {path = "/usr/bin/env cc", type = "gcc"})
-table.insert(ccs, {path = "/usr/bin/env gcc", type = "gcc"})
-table.insert(ccs, {path = "/usr/bin/env gcc-4.9", type = "gcc"})
-table.insert(ccs, {path = "/usr/bin/env gcc-4.8", type = "gcc"})
-table.insert(ccs, {path = "/usr/bin/env gcc-4.7", type = "gcc"})
-table.insert(ccs, {path = "/usr/bin/env clang", type = "clang"})
-table.insert(ccs, {path = "/usr/bin/env icc", type = "gcc"})
+table.insert(ccs, {path = {"/usr/bin/env", "cc"}, type = "gcc"})
+table.insert(ccs, {path = {"/usr/bin/env", "gcc"}, type = "gcc"})
+table.insert(ccs, {path = {"/usr/bin/env", "gcc-4.9"}, type = "gcc"})
+table.insert(ccs, {path = {"/usr/bin/env", "gcc-4.8"}, type = "gcc"})
+table.insert(ccs, {path = {"/usr/bin/env", "gcc-4.7"}, type = "gcc"})
+table.insert(ccs, {path = {"/usr/bin/env", "clang"}, type = "clang"})
+table.insert(ccs, {path = {"/usr/bin/env", "icc"}, type = "gcc"})
-local quote_me = '[^%w%+%-%=%@%_%/]' -- complement (needn't quote)
+local quote_me = '[^.%w%+%-%@%_%/]' -- complement (needn't quote)
local function shell_quote(str)
if string.find(str, quote_me) or str == '' then
return "'" .. string.gsub(str, "'", [['"'"']]) .. "'"
@@ -61,12 +61,12 @@ end
-- will produce a string that represents a meta C header file that includes
-- all the passed in headers. I.e.:
--
--- headerize({"stdio.h", "math.h", true}
+-- headerize({"stdio.h", "math.h"}, true)
-- produces:
-- #include <stdio.h>
-- #include <math.h>
--
--- headerize({"vim.h", "memory.h", false}
+-- headerize({"vim.h", "memory.h"}, false)
-- produces:
-- #include "vim.h"
-- #include "memory.h"
@@ -79,8 +79,7 @@ local function headerize(headers, global)
end
local formatted = {}
- for i = 1, #headers do
- local hdr = headers[i]
+ for _, hdr in ipairs(headers) do
formatted[#formatted + 1] = "#include " ..
tostring(pre) ..
tostring(hdr) ..
@@ -91,49 +90,77 @@ local function headerize(headers, global)
end
local Gcc = {
+ preprocessor_extra_flags = {},
+ get_defines_extra_flags = {'-std=c99', '-dM', '-E'},
+ get_declarations_extra_flags = {'-std=c99', '-P', '-E'},
+}
+
+function Gcc:define(name, args, val)
+ local define = '-D' .. name
+ if args ~= nil then
+ define = define .. '(' .. table.concat(args, ',') .. ')'
+ end
+ if val ~= nil then
+ define = define .. '=' .. val
+ end
+ self.preprocessor_extra_flags[#self.preprocessor_extra_flags + 1] = define
+end
+
+function Gcc:undefine(name)
+ self.preprocessor_extra_flags[#self.preprocessor_extra_flags + 1] = (
+ '-U' .. name)
+end
+
+function Gcc:init_defines()
-- preprocessor flags that will hopefully make the compiler produce C
-- declarations that the LuaJIT ffi understands.
- preprocessor_extra_flags = {
- '-D "aligned(ARGS)="',
- '-D "__attribute__(ARGS)="',
- '-D "__asm(ARGS)="',
- '-D "__asm__(ARGS)="',
- '-D "__inline__="',
- '-D "EXTERN=extern"',
- '-D "INIT(...)="',
- '-D_GNU_SOURCE',
- '-DINCLUDE_GENERATED_DECLARATIONS',
-
- -- Needed for FreeBSD
- '-D "_Thread_local="',
-
- -- Needed for macOS Sierra
- '-D "_Nullable="',
- '-D "_Nonnull="',
- '-U__BLOCKS__',
- }
-}
+ self:define('aligned', {'ARGS'}, '')
+ self:define('__attribute__', {'ARGS'}, '')
+ self:define('__asm', {'ARGS'}, '')
+ self:define('__asm__', {'ARGS'}, '')
+ self:define('__inline__', nil, '')
+ self:define('EXTERN', nil, 'extern')
+ self:define('INIT', {'...'}, '')
+ self:define('_GNU_SOURCE')
+ self:define('INCLUDE_GENERATED_DECLARATIONS')
+ -- Needed for FreeBSD
+ self:define('_Thread_local', nil, '')
+ -- Needed for macOS Sierra
+ self:define('_Nullable', nil, '')
+ self:define('_Nonnull', nil, '')
+ self:undefine('__BLOCKS__')
+end
function Gcc:new(obj)
obj = obj or {}
setmetatable(obj, self)
self.__index = self
+ self:init_defines()
return obj
end
function Gcc:add_to_include_path(...)
- local paths = {...}
- for i = 1, #paths do
- local path = paths[i]
- local directive = '-I ' .. '"' .. path .. '"'
+ for i = 1, select('#', ...) do
+ local path = select(i, ...)
local ef = self.preprocessor_extra_flags
- ef[#ef + 1] = directive
+ ef[#ef + 1] = '-I' .. path
+ end
+end
+
+local function argss_to_cmd(...)
+ local cmd = ''
+ for i = 1, select('#', ...) do
+ for _, arg in ipairs(select(i, ...)) do
+ cmd = cmd .. ' ' .. shell_quote(arg)
+ end
end
+ return cmd
end
-- returns a list of the headers files upon which this file relies
function Gcc:dependencies(hdr)
- local out = io.popen(tostring(self.path) .. " -M " .. tostring(hdr) .. " 2>&1")
+ local cmd = argss_to_cmd(self.path, {'-M', hdr}) .. ' 2>&1'
+ local out = io.popen(cmd)
local deps = out:read("*a")
out:close()
if deps then
@@ -143,23 +170,51 @@ function Gcc:dependencies(hdr)
end
end
+local function repeated_call(...)
+ local cmd = argss_to_cmd(...)
+ for _ = 1, 10 do
+ local stream = io.popen(cmd)
+ local ret = stream:read('*a')
+ stream:close()
+ if ret then
+ return ret
+ end
+ end
+ print('ERROR: preprocess.lua: Failed to execute ' .. cmd .. ': nil return after 10 attempts')
+ return nil
+end
+
-- returns a stream representing a preprocessed form of the passed-in headers.
-- Don't forget to close the stream by calling the close() method on it.
-function Gcc:preprocess_stream(...)
+function Gcc:preprocess(previous_defines, ...)
-- create pseudo-header
local pseudoheader = headerize({...}, false)
- local defines = table.concat(self.preprocessor_extra_flags, ' ')
- local cmd = ("echo $hdr | " ..
- tostring(self.path) ..
- " " ..
- tostring(defines) ..
- " -std=c99 -P -E -"):gsub('$hdr', shell_quote(pseudoheader))
+ local pseudoheader_fname = 'tmp_pseudoheader.h'
+ local pseudoheader_file = io.open(pseudoheader_fname, 'w')
+ pseudoheader_file:write(previous_defines)
+ pseudoheader_file:write("\n")
+ pseudoheader_file:write(pseudoheader)
+ pseudoheader_file:flush()
+ pseudoheader_file:close()
+
+ local defines = repeated_call(self.path, self.preprocessor_extra_flags,
+ self.get_defines_extra_flags,
+ {pseudoheader_fname})
+
-- lfs = require("lfs")
-- print("CWD: #{lfs.currentdir!}")
-- print("CMD: #{cmd}")
-- io.stderr\write("CWD: #{lfs.currentdir!}\n")
-- io.stderr\write("CMD: #{cmd}\n")
- return io.popen(cmd)
+
+ local declarations = repeated_call(self.path, self.preprocessor_extra_flags,
+ self.get_declarations_extra_flags,
+ {pseudoheader_fname})
+
+ os.remove(pseudoheader_fname)
+
+ assert(declarations and defines)
+ return declarations, defines
end
local Clang = Gcc:new()
@@ -197,8 +252,8 @@ return {
includes = function(hdr)
return cc:dependencies(hdr)
end,
- preprocess_stream = function(...)
- return cc:preprocess_stream(...)
+ preprocess = function(...)
+ return cc:preprocess(...)
end,
add_to_include_path = function(...)
return cc:add_to_include_path(...)