[
  {
    "path": ".gitignore",
    "content": "/doc/tags\n"
  },
  {
    "path": "README.markdown",
    "content": "# Welcome to the future (of the past)\n\nTimL is a Lisp dialect implemented in and compiling down to VimL, the\nscripting language provided by the Vim text editor.  Think Clojure meets VimL.\n\n## Is this a joke?\n\nIf you mean the 6,000 lines of working code, then no, I poured hundreds upon\nhundreds of very serious hours into that.  But if you're referring to the fact\nit's woefully underdocumented, adds considerable overhead to an already slow\nhost platform, and ultimately unlikely to gain any traction, then yeah,\nprobably.\n\n## Language features\n\n* Clojure like syntax and API, including everything from rich syntax literals\n  to destructuring.\n* Namespaces, including `refer` and `alias`.\n* `timl.core`, a tiny but growing API resembling `clojure.core`.\n* The same persistent collection types and interfaces, including vectors, hash\n  maps, hash sets, lists, and lazy sequences.\n* Macros, including syntax quoting and the implicit `&form` and `&env`.\n* Metadata.  (Some collection types don't support it yet.)\n* Reference types, including vars, atoms, futures.\n* Extensible type system, including `defmethod` for duck typing.  (This is the\n  most significant departure from Clojure.)\n* Caching compiler generates real VimL.\n\n## VimL interop\n\n* TimL functions are actually VimL dictionaries (objects) containing a\n  dictionary function (method) and a reference to the enclosing scope.\n* Defining a symbol `baz` in namespace `foo.bar` actually defines\n  `g:foo#bar.baz`.  If that symbol refers to something callable (like a\n  function), calling `foo#bar#baz()` on the VimL side will invoke it.\n* Arbitrary Vim variables and options can be referred to using VimL notation:\n  `b:did_ftplugin`, `v:version`, `&expandtab`. You can also change them with\n  `set!`: `(set! &filetype \"timl\")`.\n* `#*function` returns a reference to a built-in or user defined function.\n  You can call it like any other function: `(#*toupper \"TimL is pretty neat\")`.\n* Interact with VimL exceptions with `throw`/`try`/`catch`/`finally`.\n* Call a Vim command with `execute`: `(execute \"wq\")`.\n* Lisp macros are a wonderful way to encapsulate and hide a lot of the pain\n  points of VimL.  The current standard library barely scratches the surface\n  here.\n\n## Getting started\n\nIf you don't have a preferred installation method, I recommend\ninstalling [pathogen.vim](https://github.com/tpope/vim-pathogen), and\nthen simply copy and paste:\n\n    cd ~/.vim/bundle\n    git clone git://github.com/tpope/timl.git\n\nOnce help tags have been generated, you can view the manual with `:help timl`.\nThere's not a whole lot there, yet.  If you know Clojure, you can probably\nguess a bunch of the function names.\n\nStart a repl with `:TLrepl`.  Tab complete is your friend.  The first time may\ntake several seconds (if your computer is a piece of shit), but compilation is\ncached, so subsequent invocations will be super quick, even if Vim is\nrestarted.\n\nThe familiar `ns` macro from Clojure is mostly identical in TimL. \n`:refer-clojure` is now `:refer-timl`, which is identical to \n`(refer 'timl.core opts)`. `:use` only supports symbol arguments.\n\n    (ns my.ns\n      (:refer-timl :exclude [+])\n      (:use timl.repl)\n      (:require [timl.file :as file]\n                [timl.test]))\n\nYou can use Clojure's `in-ns`, `require`, `refer`, `alias`, and `use`,\nhowever `use` and `require` are limited to a single argument.\n\n    (in-ns 'my.ns)\n    (use 'timl.repl)\n    (require 'timl.file)\n    (alias 'file 'timl.file)\n\nPut files in `autoload/*.tim` in the runtime path and they will be requirable.\n\n## License\n\nCopyright © Tim Pope.\n\nThe use and distribution terms for this software are covered by the [Eclipse\nPublic License 1.0](http://opensource.org/licenses/eclipse-1.0.php), which can\nbe found in the file epl-v10.html at the root of this distribution.\n\nBy using this software in any fashion, you are agreeing to be bound by the\nterms of this license.  You must not remove this notice, or any other, from\nthis software.\n"
  },
  {
    "path": "autoload/timl/array.vim",
    "content": "\" Maintainer: Tim Pope <http://tpo.pe/>\n\nif exists('g:autoloaded_timl_array')\n  finish\nendif\nlet g:autoloaded_timl_array = 1\n\nfunction! timl#array#lock(array) abort\n  lockvar 1 a:array\n  return a:array\nendfunction\n\nlet s:type = type([])\nfunction! timl#array#coerce(seq) abort\n  if type(a:seq) ==# s:type\n    return a:seq is# g:timl#nil ? [] : a:seq\n  elseif timl#type#string(a:seq) ==# 'timl.lang/Vector'\n    return copy(a:seq.array)\n  endif\n  let array = []\n  let _ = {'seq': timl#coll#seq(a:seq)}\n  while _.seq isnot# g:timl#nil\n    call add(array, timl#coll#first(_.seq))\n    let _.seq = timl#coll#next(_.seq)\n  endwhile\n  return array\nendfunction\n\nfunction! timl#array#seq(this, ...) abort\n  return len(a:this) <= (a:0 ? a:1 : 0) ? g:timl#nil : timl#array_seq#create(a:this, a:0 ? a:1 : 0)\nendfunction\n\nfunction! timl#array#car(this) abort\n  return get(a:this, 0, g:timl#nil)\nendfunction\n\nfunction! timl#array#cdr(this) abort\n  return len(a:this) <= 1 ? g:timl#empty_list : timl#array_seq#create(a:this, 1)\nendfunction\n\nfunction! timl#array#lookup(this, idx, ...) abort\n  if type(a:idx) == type(0)\n    return get(a:this, a:idx, a:0 ? a:1 g:timl#nil)\n  endif\n  return a:0 ? a:1 : g:timl#nil\nendfunction\n\nfunction! timl#array#nth(this, idx, ...) abort\n  let idx = timl#number#int(a:idx)\n  if a:0\n    return get(a:this, idx, a:1)\n  else\n    return a:this[idx]\n  endif\nendfunction\n\nfunction! timl#array#conj(this, ...) abort\n  return a:this + a:000\nendfunction\n\nfunction! timl#array#conjb(this, ...) abort\n  return extend(a:this, a:000)\nendfunction\n\nfunction! timl#array#assocb(this, ...) abort\n  let this = a:this\n  for i in range(0, len(a:000)-2, 2)\n    if (timl#number#integerp(a:000[i]) && a:000[i] ==# len(a:this)) || islocked('this')\n      call add(this, a:000[i+1])\n    else\n      let this[a:000[i]] = a:000[i+1]\n    endif\n  endfor\n  return this\nendfunction\n\nfunction! timl#array#dissocb(this, ...) abort\n  let _ = {}\n  for _.key in a:000\n    if timl#number#integerp(_.key) && _.key < len(a:this) && (-_.key-1) < len(a:this)\n      call remove(a:this, _.key)\n    endif\n  endfor\n  return a:this\nendfunction\n\nfunction! timl#array#empty(this) abort\n  return []\nendfunction\n\nfunction! timl#array#persistentb(this) abort\n  return timl#vector#claim(a:this)\nendfunction\n"
  },
  {
    "path": "autoload/timl/array_seq.vim",
    "content": "\" Maintainer: Tim Pope <http://tpo.pe>\n\nif exists(\"g:autoloaded_timl_array_seq\")\n  finish\nendif\nlet g:autoloaded_timl_array_seq = 1\n\nfunction! timl#array_seq#create(array, ...) abort\n  let cc = timl#type#bless(s:type, {\n        \\ 'array': a:array,\n        \\ 'meta': g:timl#nil,\n        \\ 'i': a:0 ? a:1 : 0})\n  lockvar 1 cc\n  return cc\nendfunction\n\nfunction! timl#array_seq#car(seq) abort\n  return get(a:seq.array, a:seq.i, g:timl#nil)\nendfunction\n\nfunction! timl#array_seq#cdr(seq) abort\n  if len(a:seq.array) - a:seq.i <= 1\n    return g:timl#empty_list\n  else\n    return timl#array_seq#create(a:seq.array, a:seq.i+1)\n  endif\nendfunction\n\nfunction! timl#array_seq#length(this) abort\n  return len(a:this.array) - a:this.i\nendfunction\n\nlet s:chunk_size = 32\n\nfunction! timl#array_seq#chunk_first(this) abort\n  return a:this.array[a:this.i : min([a:this.i+s:chunk_size, len(a:this.array)])-1]\nendfunction\n\nfunction! timl#array_seq#chunk_rest(this) abort\n  if len(a:this.array) - a:this.i <= s:chunk_size\n    return g:timl#empty_list\n  else\n    return timl#array_seq#create(a:this.array, a:this.i+s:chunk_size)\n  endif\nendfunction\n\nlet s:type = timl#type#core_define('ArraySeq', ['array', 'i', 'meta'], {\n      \\ 'get-meta': 'timl#meta#from_attribute',\n      \\ 'with-meta': 'timl#meta#copy_assign_lock',\n      \\ 'seq': 'timl#function#identity',\n      \\ 'equiv': 'timl#equality#seq',\n      \\ 'car': 'timl#array_seq#car',\n      \\ 'cdr': 'timl#array_seq#cdr',\n      \\ 'length': 'timl#array_seq#length',\n      \\ 'conj': 'timl#cons#conj',\n      \\ 'empty': 'timl#list#empty',\n      \\ 'chunk-first': 'timl#array_seq#chunk_first',\n      \\ 'chunk-rest': 'timl#array_seq#chunk_rest'})\n"
  },
  {
    "path": "autoload/timl/atom.vim",
    "content": "\" Maintainer: Tim Pope <http://tpo.pe>\n\nif exists(\"g:autoloaded_timl_atom\")\n  finish\nendif\nlet g:autoloaded_timl_atom = 1\n\nfunction! timl#atom#create(state, meta, validator) abort\n  if a:validator is# g:timl#nil || timl#truth(timl#invoke(a:validator, a:state))\n    return s:type.__call__([a:state, a:meta, a:validator, g:timl#nil])\n  endif\n  throw 'timl: invalid state'\nendfunction\n\nfunction! timl#atom#deref(this) abort\n  return a:this.state\nendfunction\n\nfunction! timl#atom#reset(this, state) abort\n  if a:this.validator is# g:timl#nil || timl#truth(timl#invoke(a:this.validator, a:state))\n    let a:this.state = a:state\n    return a:state\n  endif\n  throw 'timl: invalid state'\nendfunction\n\nfunction! timl#atom#swap(this, fn, ...) abort\n  return timl#atom#reset(a:this, timl#call(a:fn, [a:this.state] + a:000))\nendfunction\n\nfunction! timl#atom#compare_and_set(this, old, new) abort\n  if a:this.state is# a:this.old\n  return timl#atom#reset(a:this, a:new)\nendfunction\n\nfunction! timl#atom#reset_meta(this, meta) abort\n  let a:this.meta = a:meta\n  return a:this\nendfunction\n\nfunction! timl#atom#set_validator(this, validator) abort\n  if a:validator is g:timl#nil || timl#truth(timl#invoke(a:validator, a:this.state))\n    let a:this.validator = a:validator\n    return a:this\n  endif\n  throw 'timl: invalid state'\nendfunction\n\nfunction! timl#atom#get_validator(this) abort\n  return a:this.validator\nendfunction\n\nlet s:type = timl#type#core_define('Atom', ['state', 'meta', 'validator', 'watches'], {\n      \\ 'get-meta': 'timl#meta#from_attribute',\n      \\ 'reset!': 'timl#atom#reset',\n      \\ 'swap!': 'timl#atom#swap',\n      \\ 'compare-and-set!': 'timl#atom#compare_and_set',\n      \\ 'reset-meta!': 'timl#atom#reset_meta',\n      \\ 'set-validator!': 'timl#atom#set_validator',\n      \\ 'get-validator': 'timl#atom#get_validator',\n      \\ 'deref': 'timl#atom#deref'})\n"
  },
  {
    "path": "autoload/timl/bootstrap.vim",
    "content": "\" Maintainer: Tim Pope <http://tpo.pe/>\n\nif exists(\"g:autoloaded_timl_bootstrap\")\n  finish\nendif\nlet g:autoloaded_timl_bootstrap = 1\n\n\" Section: Setup\n\nfunction! s:function(name) abort\n  return function(substitute(a:name,'^s:',matchstr(expand('<sfile>'), '.*\\zs<SNR>\\d\\+_'),''))\nendfunction\n\nfunction! s:implement(type, ...) abort\n  let type = timl#symbol#intern(a:type)\n  for i in range(0, a:0-1, 2)\n    call timl#type#define_method(s:ns, timl#symbol#intern(a:000[i]), type, s:function(a:000[i+1]))\n  endfor\nendfunction\n\nlet s:fn_type = timl#type#core_create('Function')\nfunction! s:intern_fn(name, apply, ...) abort\n  let fn = {'name': a:name, 'ns': s:ns}\n  if a:0\n    call extend(fn, a:1)\n  endif\n  call timl#type#bless(s:fn_type, fn)\n  let fn.__call__ = s:function(a:apply)\n  call timl#namespace#intern(s:ns, a:name, fn)\nendfunction\n\nlet s:ns = timl#namespace#create(timl#symbol#intern('timl.core'))\nlet s:langns = timl#namespace#create(timl#symbol#intern('timl.lang'))\nlet s:vimns = timl#namespace#create(timl#symbol#intern('vim'))\n\nfunction! s:apply(_) dict abort\n  return call(self.invoke, a:_, self)\nendfunction\n\nfunction! s:predicate(_) dict abort\n  return call(self.test, a:_, self) ? g:timl#true : g:timl#false\nendfunction\n\nlet s:k_help = timl#keyword#intern('help')\nfunction! s:define_call(name, fn) abort\n  if a:fn =~# '^[a-z0-9_]\\+$'\n    let name = timl#symbol#intern_with_meta(a:name, timl#map#create([s:k_help, a:fn.'()']))\n  else\n    let name = timl#symbol#intern(a:name)\n  endif\n  call s:intern_fn(name, 's:apply', {'invoke': s:function(a:fn)})\nendfunction\n\nfunction! s:define_pred(name, fn) abort\n  if a:fn =~# '^[a-z0-9_]\\+$'\n    let name = timl#symbol#intern_with_meta(a:name, timl#map#create([s:k_help, a:fn.'()']))\n  else\n    let name = timl#symbol#intern(a:name)\n  endif\n  call s:intern_fn(name, 's:predicate', {'test': s:function(a:fn)})\nendfunction\n\nfunction! s:define_apply(name, fn) abort\n  call s:intern_fn(timl#symbol#intern(a:name), a:fn)\nendfunction\n\n\" Section: Namespace\n\ncall s:define_apply('load', 'timl#loader#all_relative')\ncall s:define_apply('require', 'timl#loader#require_all')\ncall s:define_apply('use', 'timl#loader#use_all')\ncall s:define_call('create-ns', 'timl#namespace#create')\ncall s:define_call('find-ns', 'timl#namespace#find')\ncall s:define_call('the-ns', 'timl#namespace#the')\ncall s:define_call('ns-name', 'timl#namespace#name')\ncall s:define_call('ns-map', 'timl#namespace#map')\ncall s:define_call('ns-aliases', 'timl#namespace#aliases')\ncall s:define_call('all-ns', 'timl#namespace#all')\ncall s:define_call('in-ns', 'timl#namespace#select')\ncall s:define_call('refer', 'timl#namespace#refer')\ncall s:define_call('alias', 'timl#namespace#alias')\ncall s:define_call('intern', 'timl#namespace#intern')\n\n\" Section: Var\n\ncall s:define_call('var-get', 'timl#var#get')\ncall s:define_call('find-var', 'timl#var#find')\ncall s:define_pred('var?', 'timl#var#test')\ncall s:define_call('munge', 'timl#var#munge')\n\n\" Section: Type Sytem\n\ncall s:define_pred('isa?', 'timl#type#isap')\ncall s:define_pred('can?', 'timl#type#canp')\n\ncall s:implement('timl.lang/Type',\n      \\ 'hash', 'timl#hash#str_attribute',\n      \\ 'call', 'timl#function#call')\n\n\" Section: Meta\n\ncall s:define_call('meta', 'timl#meta#get')\ncall s:define_call('vary-meta', 'timl#meta#vary')\ncall s:define_call('alter-meta!', 'timl#meta#alter')\n\n\" Section: Symbol/Keyword\n\ncall s:define_call('symbol', 'timl#symbol#intern')\ncall s:define_call('keyword', 'timl#keyword#intern')\ncall s:define_call('gensym', 'timl#symbol#gen')\ncall s:define_pred('symbol?', 'timl#symbol#test')\ncall s:define_pred('keyword?', 'timl#keyword#test')\n\n\" Section: Equality\n\ncall s:define_apply('identical?', 'timl#equality#identical')\ncall s:define_apply('=', 'timl#equality#all')\ncall s:define_apply('not=', 'timl#equality#not')\n\n\" Section: Nil\n\ncall s:define_pred('nil?', 'timl#nil#test')\ncall timl#nil#identity()\n\n\" Section: Number\n\ncall timl#type#define(s:vimns, timl#symbol('Number'), g:timl#nil)\ncall s:implement('vim/Number',\n      \\ 'hash', 'timl#function#identity',\n      \\ 'to-string', 'string')\n\ncall s:define_call('num', 'timl#num#coerce')\ncall s:define_call('int', 'timl#number#int')\ncall s:define_call('float', 'timl#number#float')\ncall s:define_pred('number?', 'timl#number#test')\ncall s:define_pred('integer?', 'timl#number#integerp')\ncall s:define_pred('float?', 'timl#number#floatp')\ncall s:define_apply('+', 'timl#number#sum')\ncall s:define_apply('*', 'timl#number#product')\ncall s:define_apply('-', 'timl#number#minus')\ncall s:define_apply('/', 'timl#number#solidus')\ncall s:define_apply('>', 'timl#number#gt')\ncall s:define_apply('<', 'timl#number#lt')\ncall s:define_apply('>=', 'timl#number#gteq')\ncall s:define_apply('<=', 'timl#number#lteq')\ncall s:define_apply('==', 'timl#number#equiv')\ncall s:define_apply('max', 'max')\ncall s:define_apply('min', 'min')\ncall s:define_call('inc', 'timl#number#inc')\ncall s:define_call('dec', 'timl#number#dec')\ncall s:define_call('rem', 'timl#number#rem')\ncall s:define_call('quot', 'timl#number#quot')\ncall s:define_call('mod', 'timl#number#mod')\ncall s:define_call('bit-not', 'timl#number#bit_not')\ncall s:define_apply('bit-or', 'timl#number#bit_or')\ncall s:define_apply('bit-xor', 'timl#number#bit_xor')\ncall s:define_apply('bit-and', 'timl#number#bit_and')\ncall s:define_apply('bit-and-not', 'timl#number#bit_and_not')\ncall s:define_call('bit-shift-left', 'timl#number#bit_shift_left')\ncall s:define_call('bit-shift-right', 'timl#number#bit_shift_right')\ncall s:define_call('bit-flip', 'timl#number#bit_flip')\ncall s:define_call('bit-set', 'timl#number#bit_set')\ncall s:define_call('bit-clear', 'timl#number#bit_clear')\ncall s:define_pred('bit-test', 'timl#number#bit_test')\ncall s:define_call('not-negative', 'timl#number#not_negative')\ncall s:define_pred('zero?', 'timl#number#zerop')\ncall s:define_pred('nonzero?', 'timl#number#nonzerop')\ncall s:define_pred('pos?', 'timl#number#posp')\ncall s:define_pred('neg?', 'timl#number#negp')\ncall s:define_pred('odd?', 'timl#number#oddp')\ncall s:define_pred('even?', 'timl#number#evenp')\n\ncall s:define_call('str2nr', 'str2nr')\nif has('float')\n  call timl#type#define(s:vimns, timl#symbol('Float'), g:timl#nil)\n  call s:implement('vim/Float',\n        \\ 'to-string', 'string')\n  call s:define_call('str2float', 'str2float')\n  call s:define_call('float2nr', 'float2nr')\nendif\n\n\" Section: String\n\ncall timl#type#define(s:vimns, timl#symbol('String'), g:timl#nil)\n\ncall s:implement('vim/String',\n      \\ 'to-string', 'timl#function#identity',\n      \\ 'hash', 'timl#hash#string',\n      \\ 'funcref', 'function',\n      \\ 'seq', 'timl#string#seq',\n      \\ 'lookup', 'timl#string#lookup',\n      \\ 'length', 'timl#string#length')\n\ncall s:define_call('format', 'printf')\ncall s:define_apply('str', 'timl#string#join')\ncall s:define_call('join', 'timl#string#join')\ncall s:define_call('split', 'timl#string#split')\ncall s:define_call('replace', 'timl#string#replace')\ncall s:define_call('replace-one', 'timl#string#replace_one')\ncall s:define_call('re-quote-replacement', 'timl#string#re_quote_replacement')\ncall s:define_call('re-find', 'timl#string#re_find')\ncall s:define_call('subs', 'timl#string#sub')\ncall s:define_apply('pr-str', 'timl#string#pr')\ncall s:define_apply('prn-str', 'timl#string#prn')\ncall s:define_apply('print-str', 'timl#string#print')\ncall s:define_apply('println-str', 'timl#string#println')\n\ncall s:define_pred('string?', 'timl#string#test')\n\ncall s:define_call('char2nr', 'char2nr')\ncall s:define_call('nr2char', 'nr2char')\n\n\" Section: Boolean\n\nlet s:boolean = timl#type#core_define('Boolean', g:timl#nil, {\n      \\ 'hash': 'len'})\n\nif !exists('g:timl#false')\n  call timl#false#identity()\n  call timl#true#identity()\nendif\n\ncall s:define_pred('boolean', 'timl#truth')\ncall s:define_pred('false?', 'timl#false#test')\ncall s:define_pred('true?', 'timl#true#test')\n\n\" Section: Function\n\ncall timl#type#define(s:vimns, timl#symbol('Funcref'), g:timl#nil)\n\ncall s:implement('timl.lang/Function',\n      \\ 'hash', 'timl#function#hash',\n      \\ 'call', 'timl#function#call')\n\ncall s:implement('timl.lang/MultiFn',\n      \\ 'hash', 'timl#function#hash',\n      \\ 'call', 'timl#type#dispatch')\n\ncall s:implement('vim/Funcref',\n      \\ 'funcref', 'timl#function#identity',\n      \\ 'to-string', 'timl#funcref#string',\n      \\ 'hash', 'timl#funcref#hash',\n      \\ 'call', 'timl#funcref#call')\n\ncall s:define_pred('funcref?', 'timl#funcref#test')\n\ncall s:define_apply('apply', 'timl#function#apply')\ncall s:define_call('identity', 'timl#function#identity')\n\ncall s:define_call('fn', 'timl#function#fn')\ncall s:define_call('defn', 'timl#function#defn')\ncall s:define_call('defmacro', 'timl#function#defmacro')\nfor s:x in ['fn', 'defn', 'defmacro']\n  let s:y = timl#namespace#maybe_resolve(s:ns, timl#symbol#intern(s:x))\n  let s:y.meta = timl#map#create([timl#keyword#intern('macro'), g:timl#true])\nendfor\nunlet s:x s:y\n\n\" Section: Array (Vim List)\n\ncall timl#type#define(s:vimns, timl#symbol('List'), g:timl#nil)\ncall s:implement('vim/List',\n      \\ 'seq', 'timl#array#seq',\n      \\ 'car', 'timl#array#car',\n      \\ 'cdr', 'timl#array#cdr',\n      \\ 'lookup', 'timl#array#lookup',\n      \\ 'nth', 'timl#array#nth',\n      \\ 'length', 'len',\n      \\ 'conj', 'timl#array#conj',\n      \\ 'empty', 'timl#array#empty')\n\ncall s:implement('vim/List',\n      \\ 'equiv', 'timl#equality#seq',\n      \\ 'conj!', 'timl#array#conjb',\n      \\ 'assoc!', 'timl#array#assocb',\n      \\ 'dissoc!', 'timl#array#dissocb',\n      \\ 'persistent!', 'timl#array#persistentb')\n\ncall s:define_apply('array', 'timl#array#coerce')\n\n\" Section: Vector\n\ncall timl#type#define(s:langns, timl#symbol('Vector'), g:timl#nil)\n\ncall s:implement('timl.lang/Vector',\n      \\ 'seq', 'timl#vector#seq',\n      \\ 'car', 'timl#vector#car',\n      \\ 'cdr', 'timl#vector#cdr',\n      \\ 'lookup', 'timl#vector#lookup',\n      \\ 'nth', 'timl#vector#nth',\n      \\ 'length', 'timl#vector#length',\n      \\ 'conj', 'timl#vector#conj',\n      \\ 'empty', 'timl#vector#empty',\n      \\ 'call', 'timl#vector#call')\n\ncall s:implement('timl.lang/Vector',\n      \\ 'equiv', 'timl#equality#seq',\n      \\ 'transient', 'timl#vector#transient')\n\ncall s:define_call('subvec', 'timl#vector#sub')\ncall s:define_pred('vector?', 'timl#vector#test')\ncall s:define_call('vec', 'timl#vector#coerce')\ncall s:define_apply('vector', 'timl#vector#coerce')\n\n\" Section: Cons\n\ncall s:define_call('cons', 'timl#cons#create')\ncall s:define_apply('list*', 'timl#cons#spread')\n\n\" Section: List\n\nlet g:timl#empty_list = timl#list#empty()\n\ncall s:define_apply('list', 'timl#list#create')\ncall s:define_pred('list?', 'timl#list#test')\n\n\" Section: Seq\n\ncall s:define_call('first', 'timl#coll#first')\ncall s:define_call('next', 'timl#coll#next')\ncall s:define_call('rest', 'timl#coll#rest')\ncall s:define_pred('empty?', 'timl#coll#emptyp')\ncall s:define_call('ffirst', 'timl#coll#ffirst')\ncall s:define_call('fnext', 'timl#coll#fnext')\ncall s:define_call('nfirst', 'timl#coll#nfirst')\ncall s:define_call('nnext', 'timl#coll#nnext')\ncall s:define_call('second', 'timl#coll#fnext')\n\n\" Section: Chunked Cons\n\ncall s:define_call('chunk-cons', 'timl#chunked_cons#create')\n\n\" Section: Dictionary\n\ncall timl#type#define(s:vimns, timl#symbol('Dictionary'), g:timl#nil)\ncall s:implement('vim/Dictionary',\n      \\ 'seq', 'timl#dictionary#seq',\n      \\ 'lookup', 'timl#dictionary#lookup',\n      \\ 'empty', 'timl#dictionary#empty',\n      \\ 'conj', 'timl#dictionary#conj',\n      \\ 'length', 'len',\n      \\ 'equiv', 'timl#map#equal')\n\ncall s:implement('vim/Dictionary',\n      \\ 'assoc', 'timl#dictionary#assoc',\n      \\ 'dissoc', 'timl#dictionary#dissoc',\n      \\ 'transient', 'timl#dictionary#transient')\n\ncall s:implement('vim/Dictionary',\n      \\ 'conj!', 'timl#dictionary#conjb',\n      \\ 'assoc!', 'timl#dictionary#assocb',\n      \\ 'dissoc!', 'timl#dictionary#dissocb',\n      \\ 'persistent!', 'timl#dictionary#persistentb')\n\ncall s:define_pred('dict?', 'timl#dictionary#test')\ncall s:define_apply('dict', 'timl#dictionary#create')\n\n\" Section: Hash Map\n\ncall timl#type#define(s:langns, timl#symbol('HashMap'), g:timl#nil)\n\ncall s:implement('timl.lang/HashMap',\n      \\ 'seq', 'timl#map#seq',\n      \\ 'lookup', 'timl#map#lookup',\n      \\ 'empty', 'timl#map#empty',\n      \\ 'conj', 'timl#map#conj',\n      \\ 'length', 'timl#map#length',\n      \\ 'equiv', 'timl#map#equal')\n\ncall s:implement('timl.lang/HashMap',\n      \\ 'assoc', 'timl#map#assoc',\n      \\ 'dissoc', 'timl#map#dissoc',\n      \\ 'call', 'timl#map#call')\n\ncall s:define_pred('map?', 'timl#map#test')\ncall s:define_apply('hash-map', 'timl#map#create')\ncall s:define_call('zipmap', 'timl#map#zip')\n\n\" Section: Hash Set\n\ncall s:define_pred('set?', 'timl#set#test')\ncall s:define_call('set', 'timl#set#coerce')\ncall s:define_apply('hash-set', 'timl#set#coerce')\nruntime! autoload/timl/set.vim\n\n\" Section: Collection\n\ncall s:define_pred('coll?', 'timl#coll#test')\ncall s:define_pred('seq?', 'timl#coll#seqp')\ncall s:define_pred('sequential?', 'timl#coll#sequentialp')\ncall s:define_pred('chunked-seq?', 'timl#coll#chunked_seqp')\ncall s:define_call('count', 'timl#coll#count')\ncall s:define_call('get', 'timl#coll#get')\ncall s:define_call('into', 'timl#coll#into')\ncall s:define_call('reduce', 'timl#coll#reduce')\ncall s:define_pred('contains?', 'timl#coll#containsp')\n\n\" Section: Compiler\n\ncall s:define_pred('special-symbol?', 'timl#compiler#specialp')\ncall s:define_call('macroexpand-1', 'timl#compiler#macroexpand_1')\ncall s:define_call('macroexpand-all', 'timl#compiler#macroexpand_all')\n\n\" Section: I/O\n\ncall s:define_apply('echo', 'timl#io#echo')\ncall s:define_apply('echon', 'timl#io#echon')\ncall s:define_apply('echomsg', 'timl#io#echomsg')\ncall s:define_apply('print', 'timl#io#echon')\ncall s:define_apply('println', 'timl#io#println')\ncall s:define_call('newline', 'timl#io#newline')\ncall s:define_call('printf', 'timl#io#printf')\ncall s:define_apply('pr', 'timl#io#pr')\ncall s:define_apply('prn', 'timl#io#prn')\ncall s:define_call('spit', 'timl#io#spit')\ncall s:define_call('slurp', 'timl#io#slurp')\ncall s:define_call('read-string', 'timl#reader#read_string')\n\n\" Section: Reference types\n\ncall s:define_call('force', 'timl#delay#force')\ncall s:define_call('future-call', 'timl#future#call')\nruntime! autoload/timl/atom.vim\n\n\" Section: Time\n\ncall s:define_call('inst', 'timl#inst#create')\ncall s:define_call('sleep', 'timl#inst#sleep')\n\n\" Section: Vim Interop\n\ncall s:define_pred('exists?', 'exists')\ncall s:define_pred('has?', 'has')\n\n\" vim:set et sw=2:\n"
  },
  {
    "path": "autoload/timl/buffer.tim",
    "content": "(ns timl.buffer)\n\n(deftype Buffer [nr])\n\n(defmethod lookup Buffer [self key not-found]\n  (get (#*getbufvar (. self nr) \"\") (str key) not-found))\n\n(defmethod buffer Buffer [buf] buf)\n(defmethod buffer vim/Number [nr] (when (nonzero? (#*bufexists nr)) (Buffer nr)))\n(defmethod buffer vim/String [name] (when-let [nr (not-negative (#*bufnr name))] (Buffer nr)))\n"
  },
  {
    "path": "autoload/timl/chunked_cons.vim",
    "content": "\" Maintainer: Tim Pope <http://tpo.pe>\n\nif exists(\"g:autoloaded_timl_chunked_cons\")\n  finish\nendif\nlet g:autoloaded_timl_chunked_cons = 1\n\nfunction! timl#chunked_cons#create(array, rest, ...) abort\n  lockvar 1 a:array\n  let cc = timl#type#bless(s:type, {\n        \\ 'array': a:array,\n        \\ 'rest': a:rest,\n        \\ 'meta': g:timl#nil,\n        \\ 'i': a:0 ? a:1 : 0})\n  lockvar 1 cc\n  return cc\nendfunction\n\nfunction! timl#chunked_cons#car(this) abort\n  return get(a:this.array, a:this.i, g:timl#nil)\nendfunction\n\nfunction! timl#chunked_cons#cdr(this) abort\n  if len(a:this.array) - a:this.i <= 1\n    return a:this.rest\n  else\n    return timl#chunked_cons#create(a:this.array, a:this.rest, a:this.i+1)\n  endif\nendfunction\n\nfunction! timl#chunked_cons#length(this) abort\n  let c = len(a:this.array) - a:this.i\n  let _ = {'next': timl#coll#seq(a:this.rest)}\n  while timl#type#string(_.next) ==# s:type.str\n    let c += len(_.next.array) - _.next.i\n    let _.next = timl#coll#seq(timl#chunked_cons#chunk_rest(_.next))\n  endwhile\n  return c + timl#coll#count(_.next)\nendfunction\n\nfunction! timl#chunked_cons#chunk_first(this) abort\n  return a:this.array[a:this.i : -1]\nendfunction\n\nfunction! timl#chunked_cons#chunk_rest(this) abort\n  return a:this.rest\nendfunction\n\nlet s:type = timl#type#core_define('ChunkedCons', ['array', 'rest', 'i', 'meta'], {\n      \\ 'get-meta': 'timl#meta#from_attribute',\n      \\ 'with-meta': 'timl#meta#copy_assign_lock',\n      \\ 'seq': 'timl#function#identity',\n      \\ 'equiv': 'timl#equality#seq',\n      \\ 'car': 'timl#chunked_cons#car',\n      \\ 'cdr': 'timl#chunked_cons#cdr',\n      \\ 'length': 'timl#chunked_cons#length',\n      \\ 'conj': 'timl#cons#conj',\n      \\ 'empty': 'timl#list#empty',\n      \\ 'chunk-first': 'timl#chunked_cons#chunk_first',\n      \\ 'chunk-rest': 'timl#chunked_cons#chunk_rest'})\n"
  },
  {
    "path": "autoload/timl/coll.vim",
    "content": "\" Maintainer: Tim Pope <http://tpo.pe/>\n\nif exists('g:timl_autoloaded_coll')\n  finish\nendif\nlet g:timl_autoloaded_coll = 1\n\nfunction! timl#coll#test(coll) abort\n  return timl#type#canp(a:coll, g:timl#core.conj)\nendfunction\n\nfunction! timl#coll#seq(coll) abort\n  return timl#invoke(g:timl#core.seq, a:coll)\nendfunction\n\nfunction! timl#coll#emptyp(seq) abort\n  return timl#coll#seq(a:seq) is# g:timl#nil\nendfunction\n\nfunction! timl#coll#sequentialp(coll) abort\n  return a:coll isnot# g:timl#nil && timl#type#canp(a:coll, g:timl#core.car)\nendfunction\n\nfunction! timl#coll#seqp(obj) abort\n  return timl#type#string(a:obj) =~# '^timl\\.lang/\\%(Cons\\|EmptyList\\)$' ||\n        \\ (timl#type#canp(a:obj, g:timl#core.car) && !timl#vector#test(a:obj))\nendfunction\n\nfunction! timl#coll#first(coll) abort\n  if timl#cons#test(a:coll)\n    return a:coll.car\n  elseif type(a:coll) == type([])\n    return get(a:coll, 0, g:timl#nil)\n  elseif timl#type#canp(a:coll, g:timl#core.car)\n    return timl#invoke(g:timl#core.car, a:coll)\n  else\n    return timl#invoke(g:timl#core.car, timl#coll#seq(a:coll))\n  endif\nendfunction\n\nfunction! timl#coll#rest(coll) abort\n  if timl#cons#test(a:coll)\n    return a:coll.cdr\n  elseif timl#type#canp(a:coll, g:timl#core.cdr)\n    return timl#invoke(g:timl#core.cdr, a:coll)\n  else\n    return timl#invoke(g:timl#core.cdr, timl#coll#seq(a:coll))\n  endif\nendfunction\n\nfunction! timl#coll#next(coll) abort\n  let rest = timl#coll#rest(a:coll)\n  return timl#coll#seq(rest)\nendfunction\n\nfunction! timl#coll#ffirst(seq) abort\n  return timl#coll#first(timl#coll#first(a:seq))\nendfunction\n\nfunction! timl#coll#fnext(seq) abort\n  return timl#coll#first(timl#coll#next(a:seq))\nendfunction\n\nfunction! timl#coll#nfirst(seq) abort\n  return timl#coll#next(timl#coll#first(a:seq))\nendfunction\n\nfunction! timl#coll#nnext(seq) abort\n  return timl#coll#next(timl#coll#next(a:seq))\nendfunction\n\nfunction! timl#coll#chunked_seqp(coll) abort\n  return timl#type#canp(a:coll, g:timl#core.chunk_first)\nendfunction\n\nfunction! timl#coll#get(coll, key, ...) abort\n  if timl#type#canp(a:coll, g:timl#core.lookup)\n    return timl#invoke(g:timl#core.lookup, a:coll, a:key, a:0 ? a:1 : g:timl#nil)\n  else\n    return a:0 ? a:1 : g:timl#nil\n  endif\nendfunction\n\nfunction! timl#coll#containsp(coll, val) abort\n  let sentinel = {}\n  return timl#coll#get(a:coll, a:val, sentinel) isnot# sentinel\nendfunction\n\nfunction! timl#coll#count(counted) abort\n  if timl#type#canp(a:counted, g:timl#core.length)\n    return timl#invoke(g:timl#core.length, a:counted)\n  endif\n  let _ = {'seq': timl#coll#seq(a:counted)}\n  let c = 0\n  while !timl#type#canp(_.seq, g:timl#core.length)\n    let _.seq = timl#coll#next(_.seq)\n    let c += 1\n  endwhile\n  return c + timl#invoke(g:timl#core.length, _.seq)\nendfunction\n\nfunction! timl#coll#into(coll, seq) abort\n  let t = timl#type#string(a:coll)\n  if timl#type#canp(a:coll, g:timl#core.transient)\n    let _ = {'coll': timl#invoke(g:timl#core.transient, a:coll), 'seq': timl#coll#seq(a:seq)}\n    while _.seq isnot# g:timl#nil\n      let _.coll = timl#invoke(g:timl#core.conj_BANG_, _.coll, timl#coll#first(_.seq))\n      let _.seq = timl#coll#next(_.seq)\n    endwhile\n    return timl#invoke(g:timl#core.persistent_BANG_, _.coll)\n  else\n    let _ = {'coll': a:coll, 'seq': timl#coll#seq(a:seq)}\n    while _.seq isnot# g:timl#nil\n      let _.coll = timl#invoke(g:timl#core.conj, _.coll, timl#coll#first(_.seq))\n      let _.seq = timl#coll#next(_.seq)\n    endwhile\n    return _.coll\n  endif\nendfunction\n\nfunction! timl#coll#reduce(f, coll, ...) abort\n  let _ = {}\n  if a:0\n    let _.val = a:coll\n    let _.seq = timl#coll#seq(a:1)\n  else\n    let _.seq = timl#coll#seq(a:coll)\n    if empty(_.seq)\n      return g:timl#nil\n    endif\n    let _.val = timl#coll#first(_.seq)\n    let _.seq = timl#coll#rest(_.seq)\n  endif\n  while _.seq isnot# g:timl#nil\n    let _.val = timl#invoke(a:f, _.val, timl#coll#first(_.seq))\n    let _.seq = timl#coll#next(_.seq)\n  endwhile\n  return _.val\nendfunction\n\nfunction! timl#coll#mutating_map(f, coll) abort\n  return map(a:coll, 'timl#call(a:f, [v:val])')\nendfunction\n\nfunction! timl#coll#mutating_filter(pred, coll) abort\n  return filter(a:coll, 'timl#truth(timl#call(a:pred, [v:val]))')\nendfunction\n"
  },
  {
    "path": "autoload/timl/compiler.vim",
    "content": "\" Maintainer: Tim Pope <http://tpo.pe/>\n\nif exists('g:autoloaded_timl_compiler')\n  finish\nendif\nlet g:autoloaded_timl_compiler = 1\n\n\" Section: Symbol resolution\n\nlet s:specials = {\n      \\ 'if': 1,\n      \\ 'do': 1,\n      \\ 'let*': 1,\n      \\ 'fn*': 1,\n      \\ 'recur': 1,\n      \\ 'def': 1,\n      \\ 'deftype*': 1,\n      \\ 'set!': 1,\n      \\ 'execute': 1,\n      \\ '.': 1,\n      \\ 'quote': 1,\n      \\ 'function': 1,\n      \\ 'var': 1,\n      \\ 'throw': 1,\n      \\ 'try': 1,\n      \\ 'catch': 1,\n      \\ 'finally': 1}\n\nfunction! timl#compiler#specialp(sym) abort\n  return has_key(s:specials, timl#string#coerce(a:sym))\nendfunction\n\nfunction! timl#compiler#resolve(sym) abort\n  if a:sym[0] =~# '^\\w:'\n    return {'location': timl#var#munge(a:sym[0])}\n  elseif a:sym[0][0] ==# '$'\n    return {'location': \"(exists('\".a:sym[0].\"') ? \".a:sym[0].\" : g:timl#nil)\"}\n  elseif (a:sym[0] =~# '^&\\w' && exists(a:sym[0]))\n    return {'location': a:sym[0]}\n  elseif a:sym[0] =~# '\\.[^/]\\+$'\n    return {'location': 'g:'.timl#namespace#munge(a:sym[0])}\n  endif\n  let var = timl#namespace#maybe_resolve(g:timl#core._STAR_ns_STAR_, a:sym)\n  if var isnot# g:timl#nil\n    return var\n  endif\n  throw \"timl#compiler: could not resolve \".timl#string#coerce(a:sym)\nendfunction\n\n\" Section: Macroexpand\n\nlet s:kmacro = timl#keyword#intern('macro')\nfunction! timl#compiler#macroexpand_1(form) abort\n  if timl#coll#seqp(a:form) && timl#symbol#test(timl#coll#first(a:form)) && !timl#compiler#specialp(timl#coll#first(a:form))\n    let var = timl#namespace#maybe_resolve(g:timl#core._STAR_ns_STAR_, timl#coll#first(a:form))\n    if var isnot# g:timl#nil && timl#truth(timl#coll#get(var.meta, s:kmacro))\n      return timl#call(timl#var#get(var), [a:form, {}] + timl#array#coerce(timl#coll#next(a:form)))\n    endif\n  endif\n  return a:form\nendfunction\n\nfunction! timl#compiler#macroexpand_all(form) abort\n  let _ = {'last': g:timl#nil, 'this': a:form}\n  while _.last isnot# _.this\n    let [_.last, _.this] = [_.this, timl#compiler#macroexpand_1(_.this)]\n  endwhile\n  return _.this\nendfunction\n\n\" Section: Serialization\n\nlet s:escapes = {\n      \\ \"\\b\": '\\b',\n      \\ \"\\e\": '\\e',\n      \\ \"\\f\": '\\f',\n      \\ \"\\n\": '\\n',\n      \\ \"\\r\": '\\r',\n      \\ \"\\t\": '\\t',\n      \\ \"\\\"\": '\\\"',\n      \\ \"\\\\\": '\\\\'}\n\nfunction! timl#compiler#serialize(x) abort\n  \" TODO: guard against recursion\n  if timl#keyword#test(a:x)\n    return 'timl#keyword#intern('.timl#compiler#serialize(a:x[0]).')'\n\n  elseif timl#symbol#test(a:x)\n    if a:x.meta isnot# g:timl#nil\n      return 'timl#symbol#intern_with_meta('.timl#compiler#serialize(a:x[0]).', '.timl#compiler#serialize(a:x.meta).')'\n    else\n      return 'timl#symbol#intern('.timl#compiler#serialize(a:x[0]).')'\n    endif\n\n  elseif a:x is# g:timl#nil\n    return 'g:timl#nil'\n\n  elseif a:x is# g:timl#false\n    return 'g:timl#false'\n\n  elseif a:x is# g:timl#true\n    return 'g:timl#true'\n\n  elseif timl#list#emptyp(a:x)\n    if a:x.meta isnot# g:timl#nil\n      return 'timl#meta#with(g:timl#empty_list, '.timl#compiler#serialize(a:x.meta).')'\n    else\n      return 'g:timl#empty_list'\n    endif\n\n  elseif type(a:x) == type([])\n    return '['.join(map(copy(a:x), 'timl#compiler#serialize(v:val)'), ', ').']'\n\n  elseif timl#vector#test(a:x)\n    return 'timl#vector#claim(['.join(map(timl#array#coerce(a:x), 'timl#compiler#serialize(v:val)'), ', ').'])'\n\n  elseif timl#map#test(a:x) && timl#type#string(a:x) !=# 'vim/Dictionary'\n    let _ = {}\n    let keyvals = []\n    let _.seq = timl#coll#seq(a:x)\n    while _.seq isnot# g:timl#nil\n      call extend(keyvals, timl#array#coerce(timl#coll#first(_.seq)))\n      let _.seq = timl#coll#next(_.seq)\n    endwhile\n    return 'timl#map#create('.timl#compiler#serialize(keyvals).')'\n\n  elseif timl#set#test(a:x)\n    let _ = {}\n    let keyvals = []\n    let _.seq = timl#coll#seq(a:x)\n    while _.seq isnot# g:timl#nil\n      call add(keyvals, timl#coll#first(_.seq))\n      let _.seq = timl#coll#next(_.seq)\n    endwhile\n    return 'timl#set#coerce('.timl#compiler#serialize(keyvals).')'\n\n  elseif timl#type#string(a:x) ==# 'timl.lang/Cons'\n    return 'timl#cons#create('\n          \\ . timl#compiler#serialize(a:x.car).','\n          \\ . timl#compiler#serialize(a:x.cdr).','\n          \\ . timl#compiler#serialize(a:x.meta).')'\n\n  elseif timl#type#string(a:x) ==# 'timl.lang/Type'\n    return 'timl#type#find('.timl#compiler#serialize(timl#symbol#intern(a:x.str)).')'\n\n  elseif timl#var#test(a:x)\n    return 'timl#var#find('.timl#compiler#serialize(timl#symbol#intern(a:x.str)).')'\n\n  elseif type(a:x) == type('')\n    return '\"'.substitute(a:x, \"[\\001-\\037\\\"\\\\\\\\]\", '\\=get(s:escapes, submatch(0), printf(\"\\\\%03o\", char2nr(submatch(0))))', 'g').'\"'\n  elseif type(a:x) == 5 && string(a:x) =~# 'n'\n    if string(a:x) ==# 'inf'\n      return '(1/0.0)'\n    elseif string(a:x) ==# '-inf'\n      return '(-1/0.0)'\n    else\n      return '(0/0.0)'\n    endif\n  elseif type(a:x) != type({})\n    return string(a:x)\n\n  elseif timl#type#objectp(a:x)\n    return 'timl#type#bless('.timl#compiler#serialize(a:x.__type__) . ', ' . timl#compiler#serialize(filter(copy(a:x), 'v:key !~# \"^__.*__$\"')).')'\n\n  else\n    let acc = []\n    for [k, V] in items(a:x)\n      call add(acc, timl#compiler#serialize(k) . ': ' . timl#compiler#serialize(V))\n      unlet! V\n    endfor\n    return '{' . join(acc, ', ') . '}'\n\n  endif\nendfunction\n\n\" Section: Emission\n\nfunction! s:emitln(file, str) abort\n  call add(a:file, a:str)\n  return a:file\nendfunction\n\nfunction! s:localfy(name) abort\n  return a:name =~# '^\\h\\w*$' ? 'locals.'.a:name :  'locals['.string(a:name).']'\nendfunction\n\nfunction! s:with_context(env, context) abort\n  let env = copy(a:env)\n  let env.context = a:context\n  return env\nendfunction\n\nfunction! s:copy_locals(env) abort\n  let env = copy(a:env)\n  let env.locals = copy(a:env.locals)\n  return env\nendfunction\n\nfunction! s:let_tmp(file, env, clue, str) abort\n  let a:env.temp[a:clue] = get(a:env.temp, a:clue, 0) + 1\n  let temp = a:clue . a:env.temp[a:clue]\n  call s:emitln(a:file, 'let '.temp.' = '.a:str)\n  return temp\nendfunction\n\nfunction! s:wrap_as_expr(file, env, form) abort\n  let env = s:with_context(a:env, 'return')\n  if has_key(env, 'params')\n    call remove(env, 'params')\n  endif\n  let temp = s:let_tmp(a:file, env, 'thunk', '{\"locals\": copy(locals)}')\n  call s:emitln(a:file, \"function \".temp.\".call() abort\")\n  call s:emitln(a:file, \"let locals = self.locals\")\n  call s:emit(a:file, env, a:form)\n  call s:emitln(a:file, \"endfunction\")\n  return temp.'.call()'\nendfunction\n\nfunction! s:expr_sf_let_STAR_(file, env, form) abort\n  return s:wrap_as_expr(a:file, a:env, a:form)\nendfunction\n\nfunction! s:add_local(env, sym) abort\n  let str = timl#symbol#cast(a:sym)[0]\n  let a:env.locals[str] = s:localfy(str)\nendfunction\n\nlet s:k_as = timl#keyword#intern('as')\nlet s:k_or = timl#keyword#intern('or')\n\nfunction! s:assign(file, env, key, val) abort\n  let _ = {}\n  if timl#symbol#test(a:key)\n    call s:emitln(a:file, 'let '.s:localfy(a:key[0]).' = '.a:val)\n    return s:add_local(a:env, a:key)\n  elseif timl#vector#test(a:key)\n    let coll = s:let_tmp(a:file, a:env, 'coll', a:val)\n    let array = s:let_tmp(a:file, a:env, 'array', 'timl#array#coerce('.coll.')')\n    let _.seq = timl#coll#seq(a:key)\n    let i = 0\n    while _.seq isnot g:timl#nil\n      let _.elem = timl#coll#first(_.seq)\n      let _.seq = timl#coll#next(_.seq)\n      if timl#symbol#is(_.elem, '&')\n        call s:assign(a:file, a:env, timl#coll#first(_.seq), 'timl#array#seq('.array.', '.i.')')\n        let _.seq = timl#coll#next(_.seq)\n      elseif _.elem is# s:k_as\n        call s:assign(a:file, a:env, timl#coll#first(_.seq), coll)\n        let _.seq = timl#coll#next(_.seq)\n      else\n        call s:assign(a:file, a:env, _.elem, 'get('.array.', '.i.', g:timl#nil)')\n      endif\n      let i += 1\n    endwhile\n\n  elseif timl#map#test(a:key)\n    let as = timl#coll#get(a:key, s:k_as, a:key)\n    if as isnot# a:key\n      let coll = s:localfy(timl#symbol#cast(as).name)\n      call s:emitln(a:file, 'let '.coll.' = '.a:val)\n      call s:add_local(a:env, as)\n    else\n      let coll = s:let_tmp(a:file, a:env, 'coll', a:val)\n    endif\n    let or = timl#coll#get(a:key, s:k_or)\n\n    let map = s:let_tmp(a:file, a:env, 'map', 'timl#map#soft_coerce('.coll.')')\n    let _.seq = timl#coll#seq(a:key)\n    while _.seq isnot g:timl#nil\n      let _.pair = timl#coll#first(_.seq)\n      let _.var = timl#coll#first(_.pair)\n      if _.var isnot# s:k_as && _.var isnot# s:k_or\n        if timl#coll#get(or, _.var, or) isnot# or\n          call s:assign(a:file, a:env, timl#coll#first(_.pair), 'timl#coll#get('.map\n                \\ . ', ' . s:expr(a:file, a:env, timl#coll#fnext(_.pair))\n                \\ . ', ' . s:expr(a:file, a:env, timl#coll#get(or, _.var)).')')\n        else\n          call s:assign(a:file, a:env, _.var, 'timl#coll#get('.map.', '.s:expr(a:file, a:env, timl#coll#fnext(_.pair)).')')\n        endif\n      endif\n      let _.seq = timl#coll#next(_.seq)\n    endwhile\n\n  elseif timl#keyword#test(a:key)\n    throw 'timl: invalid binding :'.a:key[0]\n  else\n    throw 'timl: invalid binding type '.timl#type#string(a:key)\n  endif\nendfunction\n\nfunction! s:emit_sf_let_STAR_(file, env, form) abort\n  if a:env.context ==# 'statement'\n    return s:emitln(a:file, 'call '.s:wrap_as_expr(a:file, a:env, a:form))\n  endif\n  let ary = timl#array#coerce(timl#coll#fnext(a:form))\n  let env = s:copy_locals(a:env)\n  for i in range(0, len(ary)-1, 2)\n    call s:assign(a:file, env, ary[i], s:expr(a:file, env, ary[i+1]))\n  endfor\n  let body = timl#coll#nnext(a:form)\n  if timl#coll#count(body) == 1\n    return s:emit(a:file, env, timl#coll#first(body))\n  else\n    return s:emit_sf_do(a:file, env, timl#cons#create(timl#symbol('do'), body))\n  endif\nendfunction\n\nfunction! s:expr_sf_do(file, env, form) abort\n  return s:wrap_as_expr(a:file, a:env, a:form)\nendfunction\n\nfunction! s:emit_sf_do(file, env, form) abort\n  let ary = timl#array#coerce(timl#coll#next(a:form))\n  if empty(ary)\n    return s:emit(a:file, a:env, g:timl#nil)\n  endif\n  for i in range(len(ary) - 1)\n    call s:emit(a:file, s:with_context(a:env, 'statement'), ary[i])\n  endfor\n  call s:emit(a:file, a:env, ary[-1])\nendfunction\n\nfunction! s:expr_sf_if(file, env, form) abort\n  let ary = timl#array#coerce(timl#coll#next(a:form))\n  return 'timl#truth('.s:emit(a:file, a:env, ary[0]) . ')'\n        \\ . ' ? ' . s:emit(a:file, a:env, get(ary, 1, g:timl#nil))\n        \\ . ' : ' . s:emit(a:file, a:env, get(ary, 2, g:timl#nil))\nendfunction\n\nfunction! s:emit_sf_if(file, env, form) abort\n  let ary = timl#array#coerce(timl#coll#next(a:form))\n  call s:emitln(a:file, 'if timl#truth('.s:expr(a:file, a:env, ary[0]).')')\n  call s:emit(a:file, a:env, get(ary, 1, g:timl#nil))\n  call s:emitln(a:file, 'else')\n  call s:emit(a:file, a:env, get(ary, 2, g:timl#nil))\n  call s:emitln(a:file, 'endif')\nendfunction\n\nfunction! s:expr(file, env, form) abort\n  return s:emit(a:file, s:with_context(a:env, 'expr'), a:form)\nendfunction\n\nfunction! s:expr_sf_quote(file, env, form) abort\n  return timl#compiler#serialize(timl#coll#fnext(a:form))\nendfunction\n\nfunction! s:expr_sf_function(file, env, form) abort\n  return \"function(\".timl#compiler#serialize(timl#string#coerce(timl#coll#fnext(a:form))).\")\"\nendfunction\n\nfunction! s:expr_sf_var(file, env, form) abort\n  let sym = timl#symbol#cast(timl#coll#fnext(a:form))\n  let var = timl#namespace#maybe_resolve(g:timl#core._STAR_ns_STAR_, sym)\n  if var isnot# g:timl#nil\n    return timl#compiler#serialize(var)\n  endif\n  throw \"timl#compiler: could not resolve \".timl#string#coerce(sym)\nendfunction\n\nfunction! s:one_fn(file, env, form, name, temp, catch_errors) abort\n  let env = s:copy_locals(a:env)\n  let args = timl#array#coerce(timl#coll#first(a:form))\n  let env.params = args\n  let body = timl#coll#next(a:form)\n  let _ = {}\n  let positional = []\n  let arity = 0\n  for _.arg in args\n    if timl#symbol#is(_.arg, '&')\n      call s:add_local(env, args[-1])\n      let rest = env.locals[args[-1][0]]\n      let arity += 1000\n      break\n    else\n      call s:add_local(env, _.arg)\n      call add(positional, env.locals[_.arg[0]])\n      let arity += 1\n    endif\n  endfor\n  call s:emitln(a:file, \"function! \".a:temp.\"(_) abort\")\n  call s:emitln(a:file, \"let locals = copy(self.locals)\")\n  if len(a:name)\n    call s:emitln(a:file, 'let '.s:localfy(a:name).' = self')\n  endif\n  if a:catch_errors && !empty(positional)\n    call s:emitln(a:file, 'try')\n  endif\n  if !empty(positional)\n    call s:emitln(a:file, \"let [\".join(positional, ', ').(exists('rest') ? '; rest' : '').\"] = a:_\")\n    if exists('rest')\n      call s:emitln(a:file, \"let \".rest.\" = timl#array#seq(rest)\")\n    endif\n  elseif exists('rest')\n    call s:emitln(a:file, \"let \".rest.\" = timl#array#seq(a:_)\")\n  endif\n  if a:catch_errors && !empty(positional)\n    call s:emitln(a:file, 'catch /^Vim(let):E68[78]:/')\n    call s:emitln(a:file, \"throw 'timl: arity error'\")\n    call s:emitln(a:file, 'endtry')\n  endif\n  let c = 0\n  call s:emitln(a:file, \"while 1\")\n  if timl#coll#count(body) == 1\n    call s:emit(a:file, s:with_context(env, 'return'), timl#coll#first(body))\n  else\n    call s:emit_sf_do(a:file, s:with_context(env, 'return'), timl#cons#create(timl#symbol('do'), body))\n  endif\n  call s:emitln(a:file, \"break\")\n  call s:emitln(a:file, \"endwhile\")\n  call s:emitln(a:file, \"endfunction\")\n  return arity\nendfunction\n\nfunction! s:expr_sf_fn_STAR_(file, env, form) abort\n  let env = s:copy_locals(a:env)\n  let _ = {}\n  let _.next = timl#coll#next(a:form)\n  if timl#symbol#test(timl#coll#first(_.next))\n    let name = timl#coll#first(_.next)[0]\n    let env.locals[name] = s:localfy(name)\n    let _.next = timl#coll#next(_.next)\n  else\n    let name = ''\n  endif\n  let temp = s:let_tmp(a:file, a:env, 'fn', 'timl#function#birth(copy(locals)' . (empty(name) ? '' : ', timl#symbol#intern('.string(name).')').')')\n  if timl#vector#test(timl#coll#first(_.next))\n    call s:one_fn(a:file, env, _.next, name, temp.\".__call__\", 1)\n  elseif timl#coll#sequentialp(timl#coll#first(_.next))\n    let c = char2nr('a')\n    let fns = {}\n    while _.next isnot# g:timl#nil\n      let fns[s:one_fn(a:file, env, timl#coll#first(_.next), name, temp.'.'.nr2char(c), 0)] = nr2char(c)\n      let _.next = timl#coll#next(_.next)\n      let c += 1\n    endwhile\n    call s:emitln(a:file, \"function! \".temp.\".__call__(_) abort\")\n    call s:emitln(a:file, \"if 0\")\n    for arity in sort(map(keys(fns), 'printf(\"%04d\", v:val)'))\n      if arity >= 1000\n        call s:emitln(a:file, \"elseif len(a:_) >= \".(arity-1000))\n      else\n        call s:emitln(a:file, \"elseif len(a:_) == \".str2nr(arity))\n      endif\n      call s:emitln(a:file, 'return self.'.fns[str2nr(arity)]. '(a:_)')\n    endfor\n    call s:emitln(a:file, \"else\")\n    call s:emitln(a:file, \"throw 'timl: arity error'\")\n    call s:emitln(a:file, \"endif\")\n    call s:emitln(a:file, \"endfunction\")\n  endif\n  let meta = timl#compiler#location_meta(a:env.file, a:form)\n  if !empty(meta)\n    call s:emitln(a:file, 'let g:timl_functions[join(['.temp.\".__call__])] = \".timl#compiler#serialize(meta))\n  endif\n  return temp\nendfunction\n\nfunction! s:emit_sf_recur(file, env, form) abort\n  if a:env.context !=# 'return' || !has_key(a:env, 'params')\n    throw 'timl#compiler: recur outside of tail position'\n  endif\n  let bindings = map(copy(filter(copy(a:env.params), 'v:val[0] !=# \"&\"')), 'a:env.locals[v:val[0]]')\n  call s:emitln(a:file, 'let ['.join(bindings, ', ').'] = ['.s:expr_args(a:file, a:env, timl#coll#next(a:form)).']')\n  call s:emitln(a:file, 'continue')\nendfunction\n\nfunction! s:expr_sf_execute(file, env, form) abort\n  return s:wrap_as_expr(a:file, a:env, a:form)\nendfunction\n\nfunction! s:emit_sf_execute(file, env, form) abort\n  let expr = map(copy(timl#array#coerce(timl#coll#next(a:form))), 's:expr(a:file, a:env, v:val)')\n  call s:emitln(a:file, 'execute '.join(expr, ' '))\n  return s:emit(a:file, a:env, g:timl#nil)\nendfunction\n\nfunction! s:expr_sf_try(file, env, form) abort\n  return s:wrap_as_expr(a:file, a:env, a:form)\nendfunction\n\nfunction! s:emit_sf_try(file, env, form) abort\n  if a:env.context ==# 'statement'\n    return s:emitln(a:file, 'call '.s:wrap_as_expr(a:file, a:env, a:form))\n  endif\n  call s:emitln(a:file, 'try')\n  let _ = {}\n  let _.seq = timl#coll#next(a:form)\n  let body = []\n  while _.seq isnot# g:timl#nil\n    if timl#coll#seqp(timl#coll#first(_.seq))\n      let _.sym = timl#coll#ffirst(_.seq)\n      if timl#symbol#is(_.sym, 'catch') || timl#symbol#is(_.sym, 'finally')\n        break\n      endif\n    endif\n    call add(body, timl#coll#first(_.seq))\n    let _.seq = timl#coll#next(_.seq)\n  endwhile\n  if timl#coll#count(body) == 1\n    call s:emit(a:file, a:env, timl#coll#first(body))\n  else\n    call s:emit_sf_do(a:file, a:env, timl#cons#create(timl#symbol('do'), body))\n  endif\n  while _.seq isnot# g:timl#nil\n    let _.first = timl#coll#first(_.seq)\n    if timl#coll#seqp(_.first) && timl#symbol#is(timl#coll#first(_.first), 'catch')\n      call s:emitln(a:file, 'catch /'.escape(timl#coll#fnext(_.first), '/').'/')\n      let var = timl#coll#first(timl#coll#nnext(_.first))\n      let env = s:copy_locals(a:env)\n      if timl#symbol#test(var) && var[0] !=# '_'\n        call s:add_local(env, var)\n        call s:emitln(a:file, 'let '.env.locals[var[0]].' = timl#exception#build(v:exception, v:throwpoint)')\n      endif\n      call s:emit_sf_do(a:file, env, timl#cons#create(timl#symbol('do'), timl#coll#next(timl#coll#nnext(_.first))))\n    elseif timl#coll#seqp(_.first) && timl#symbol#is(timl#coll#first(_.first), 'finally')\n      call s:emitln(a:file, 'finally')\n      call s:emit_sf_do(a:file, s:with_context(a:env, 'statement'), timl#cons#create(timl#symbol('do'), timl#coll#next(_.first)))\n    else\n      throw 'timl#compiler: invalid form after catch or finally try'\n    endif\n    let _.seq = timl#coll#next(_.seq)\n  endwhile\n  call s:emitln(a:file, 'endtry')\nendfunction\n\nfunction! s:expr_sf_throw(file, env, form) abort\n  return s:wrap_as_expr(a:file, a:env, a:form)\nendfunction\n\nfunction! s:emit_sf_throw(file, env, form) abort\n  call s:emitln(a:file, 'throw '.s:expr(a:file, a:env, timl#coll#fnext(a:form)))\nendfunction\n\nfunction! s:expr_sf_set_BANG_(file, env, form) abort\n  let target = timl#coll#fnext(a:form)\n  let rest = timl#coll#nnext(a:form)\n  if timl#symbol#test(target)\n    let var = timl#compiler#resolve(target).location\n    if rest isnot# g:timl#nil\n      let val = s:expr(a:file, a:env, timl#coll#first(rest))\n      if var !~# '^[&$]'\n        call s:emitln(a:file, 'unlet! '.var)\n      endif\n      call s:emitln(a:file, 'let '.var.' = '.val)\n    else\n      call s:emitln(a:file, 'if !exists('.string(var).')')\n      call s:emitln(a:file, 'let '.var.' = g:timl#nil')\n      call s:emitln(a:file, 'endif')\n    endif\n    return var\n  elseif timl#coll#seqp(target) && timl#symbol#is(timl#coll#first(target), '.')\n    let key = substitute(timl#string#coerce(timl#coll#first(timl#coll#nnext(target))), '^-', '', '')\n    let target2 = timl#symbol#cast(timl#coll#fnext(target))\n    if has_key(a:env.locals, target2[0])\n      let var = a:env.locals[target2[0]]\n    else\n      let var = timl#compiler#resolve(target2).location\n    endif\n    let val = s:expr(a:file, a:env, timl#coll#first(rest))\n    call s:emitln(a:file, 'let '.var.'['.timl#compiler#serialize(key).'] = '.val)\n    return var.'['.timl#compiler#serialize(key).']'\n  else\n    throw 'timl#compiler: unsupported set! form'\n  endif\nendfunction\n\nlet s:kline = timl#keyword#intern('line')\nlet s:kfile = timl#keyword#intern('file')\nfunction! s:expr_sf_def(file, env, form) abort\n  let rest = timl#coll#next(a:form)\n  let var = timl#symbol#cast(timl#coll#first(rest))\n  if has_key(a:env, 'file')\n    let var = timl#meta#vary(var, g:timl#core.assoc, s:kline, a:env.line, s:kfile, a:env.file)\n  endif\n  if timl#coll#next(rest) isnot# g:timl#nil\n    let val = s:expr(a:file, a:env, timl#coll#fnext(rest))\n    return 'timl#namespace#intern(g:timl#core._STAR_ns_STAR_, '.timl#compiler#serialize(var).', '.val.')'\n  else\n    return 'timl#namespace#intern(g:timl#core._STAR_ns_STAR_, '.timl#compiler#serialize(var).')'\n  endif\nendfunction\n\nfunction! s:expr_sf_deftype_STAR_(file, env, form) abort\n  let rest = timl#coll#next(a:form)\n  let var = timl#symbol#cast(timl#coll#first(rest))\n  let slots = timl#array#coerce(timl#coll#fnext(rest))\n  if has_key(a:env, 'file')\n    let var = timl#meta#vary(var, g:timl#core.assoc, s:kline, a:env.line, s:kfile, a:env.file)\n  endif\n  return 'timl#type#define(g:timl#core._STAR_ns_STAR_, '.timl#compiler#serialize(var).', '.timl#compiler#serialize(slots).')'\nendfunction\n\nfunction! s:expr_dot(file, env, form) abort\n  let val = s:expr(a:file, a:env, timl#coll#fnext(a:form))\n  let key = timl#coll#first(timl#coll#nnext(a:form))\n  if timl#coll#sequentialp(key)\n    return val.'['.timl#compiler#serialize(timl#string#coerce(timl#coll#first(key))).']('.s:expr_args(a:file, a:env, timl#coll#next(key)).')'\n  else\n    return val.'['.timl#compiler#serialize(timl#string#coerce(key)).']'\n  endif\nendfunction\n\nfunction! s:expr_map(file, env, form) abort\n  let kvs = []\n  let _ = {'seq': timl#coll#seq(a:form)}\n  while _.seq isnot# g:timl#nil\n    call extend(kvs, timl#array#coerce(timl#coll#first(_.seq)))\n    let _.seq = timl#coll#next(_.seq)\n  endwhile\n  return 'timl#map#create(['.join(map(kvs, 's:emit(a:file, s:with_context(a:env, \"expr\"), v:val)'), ', ').'])'\nendfunction\n\nfunction! s:expr_args(file, env, form) abort\n  return join(map(copy(timl#array#coerce(a:form)), 's:emit(a:file, s:with_context(a:env, \"expr\"), v:val)'), ', ')\nendfunction\n\nfunction! s:emit(file, env, form) abort\n  let env = a:env\n  try\n    if timl#coll#seqp(a:form)\n      if get(a:form, 'meta', g:timl#nil) isnot# g:timl#nil && has_key(a:form.meta, 'line')\n        let env = copy(env)\n        let env.line = a:form.meta.line\n      endif\n      let First = timl#coll#first(a:form)\n      if timl#symbol#is(First, '.')\n        let expr = s:expr_dot(a:file, env, a:form)\n      elseif timl#symbol#test(First)\n        let munged = timl#var#munge(First[0])\n        if env.context ==# 'expr' && exists('*s:expr_sf_'.munged)\n          let expr = s:expr_sf_{munged}(a:file, env, a:form)\n        elseif exists('*s:emit_sf_'.munged)\n          return s:emit_sf_{munged}(a:file, env, a:form)\n        elseif exists('*s:expr_sf_'.munged)\n          let expr = s:expr_sf_{munged}(a:file, env, a:form)\n        else\n          if has_key(env.locals, First[0])\n            let resolved = env.locals[First[0]]\n          else\n            let var = timl#compiler#resolve(First)\n            if get(var, 'meta', g:timl#nil) isnot# g:timl#nil && timl#truth(timl#coll#get(var.meta, s:kmacro))\n              let E = timl#call(timl#var#get(var), [a:form, env] + timl#array#coerce(timl#coll#next(a:form)))\n              return s:emit(a:file, env, E)\n            endif\n            let resolved = var.location\n          endif\n          let args = s:expr_args(a:file, env, timl#coll#next(a:form))\n          let expr = resolved.'.__call__(['.args.'])'\n        endif\n      elseif First is# g:timl#nil && timl#coll#count(a:form) ==# 0\n        let expr = timl#compiler#serialize(a:form)\n      else\n        let args = s:expr_args(a:file, env, timl#coll#next(a:form))\n        if timl#coll#seqp(First) && timl#symbol#is(timl#coll#first(First), 'function')\n          let expr = timl#var#munge(timl#coll#fnext(First)).'('.args.')'\n        elseif type(First) == type(function('tr'))\n          let expr = join([First]).'('.args.')'\n        else\n          let expr = s:expr(a:file, env, First).'.__call__(['.args.'])'\n        endif\n      endif\n    elseif timl#symbol#test(a:form)\n      if has_key(env.locals, a:form[0])\n        let expr = env.locals[a:form[0]]\n      else\n        let expr = timl#compiler#resolve(a:form).location\n      endif\n    elseif type(a:form) == type([]) && a:form isnot# g:timl#nil\n      let expr = 'timl#function#identity(['.s:expr_args(a:file, env, a:form).'])'\n\n    elseif timl#vector#test(a:form)\n      let expr = 'timl#vector#claim(['.join(map(copy(timl#array#coerce(a:form)), 's:emit(a:file, s:with_context(env, \"expr\"), v:val)'), ', ').'])'\n\n    elseif timl#set#test(a:form)\n      let expr = 'timl#set#coerce(['.join(map(copy(timl#array#coerce(a:form)), 's:emit(a:file, s:with_context(env, \"expr\"), v:val)'), ', ').'])'\n\n    elseif timl#map#test(a:form)\n      let expr = s:expr_map(a:file, env, a:form)\n      if timl#type#string(a:form) == 'vim/Dictionary'\n        let expr = substitute(expr, '\\C#map#', '#dictionary#', '')\n      endif\n\n    else\n      let expr = timl#compiler#serialize(a:form)\n    endif\n    if env.context == 'return'\n      call s:emitln(a:file, 'return '.expr)\n      return ''\n    elseif env.context == 'statement'\n      if expr !~# '^[\"'']' && expr =~# '('\n        call s:emitln(a:file, 'call '.expr)\n      endif\n      return ''\n    else\n      return expr\n    endif\n  catch /^timl#compiler:/\n    let throw = v:exception\n    if throw !~# ' on line'\n      let throw .= ' in ' . env.file . ' on line ' .env.line\n    endif\n    throw throw\n  endtry\nendfunction\n\nif !exists('g:timl_functions')\n  let g:timl_functions = {}\nendif\n\nfunction! timl#compiler#location_meta(file, form) abort\n  let meta = timl#meta#get(a:form)\n  if type(meta) == type({}) && has_key(meta, 'line') && a:file isnot# 'NO_SOURCE_PATH'\n    return {'file': a:file, 'line': meta.line}\n  else\n    return {}\n  endif\nendfunction\n\nfunction! s:function_gc() abort\n  for fn in keys(g:timl_functions)\n    if !timl#funcref#exists(fn)\n      call remove(g:timl_functions, fn)\n    endif\n  endfor\nendfunction\n\naugroup timl#compiler#fn\n  autocmd!\n  autocmd CursorHold * call s:function_gc()\naugroup END\n\n\" Section: Compilation\n\nfunction! timl#compiler#build(x, ...) abort\n  let filename = a:0 ? a:1 : 'NO_SOURCE_PATH'\n  let file = []\n  call s:emit(file, {'file': filename, 'line': 1, 'context': 'return', 'locals': {}, 'temp': {}}, a:x)\n  let body = join(file, \"\\n\").\"\\n\"\n  let s:dict = {}\n  let str = \"function s:dict.call() abort\\n\"\n        \\ . \"let locals = {}\\n\"\n        \\ . \"while 1\\n\"\n        \\ . body\n        \\ . \"endwhile\\n\"\n        \\ . \"endfunction\"\n  execute str\n  let meta = timl#compiler#location_meta(filename, a:x)\n  if !empty(meta)\n    let g:timl_functions[join([s:dict.call])] = meta\n  endif\n  return {'body': body, 'call': s:dict.call}\nendfunction\n\n\" vim:set et sw=2:\n"
  },
  {
    "path": "autoload/timl/cons.vim",
    "content": "\" Maintainer: Tim Pope <http://tpo.pe>\n\nif exists(\"g:autoloaded_timl_cons\")\n  finish\nendif\nlet g:autoloaded_timl_cons = 1\n\nfunction! timl#cons#test(obj) abort\n  return type(a:obj) == type({}) && get(a:obj, '__type__') is# s:type\nendfunction\n\nfunction! timl#cons#create(car, cdr, ...) abort\n  if timl#type#canp(a:cdr, g:timl#core.seq)\n    let cons = timl#type#bless(s:type, {'car': a:car, 'cdr': a:cdr is# g:timl#nil ? g:timl#empty_list : a:cdr, 'meta': a:0 ? a:1 : g:timl#nil})\n    lockvar 1 cons\n    return cons\n  endif\n  throw 'timl: not seqable: '.timl#type#string(a:cdr)\nendfunction\n\nfunction! timl#cons#spread(array) abort\n  if empty(a:array)\n    throw 'timl: arity error'\n  elseif !timl#type#canp(a:array[-1], g:timl#core.seq)\n    throw 'timl: seq required'\n  endif\n  let _ = {'cdr': a:array[-1]}\n  for i in range(len(a:array)-2, 0, -1)\n    let _.cdr = timl#cons#create(a:array[i], _.cdr)\n  endfor\n  return _.cdr\nendfunction\n\nfunction! timl#cons#conj(this, ...) abort\n  let head = a:this\n  let _ = {}\n  for _.e in a:000\n    let head = timl#cons#create(_.e, head)\n  endfor\n  return head\nendfunction\n\nfunction! timl#cons#car(this) abort\n  return a:this.car\nendfunction\n\nfunction! timl#cons#cdr(this) abort\n  return a:this.cdr\nendfunction\n\nlet s:type = timl#type#core_define('Cons', ['car', 'cdr', 'meta'], {\n      \\ 'get-meta': 'timl#meta#from_attribute',\n      \\ 'with-meta': 'timl#meta#copy_assign_lock',\n      \\ 'seq': 'timl#function#identity',\n      \\ 'equiv': 'timl#equality#seq',\n      \\ 'car': 'timl#cons#car',\n      \\ 'cdr': 'timl#cons#cdr',\n      \\ 'conj': 'timl#cons#conj',\n      \\ 'empty': 'timl#list#empty'})\n"
  },
  {
    "path": "autoload/timl/core.tim",
    "content": "(in-ns 'timl.core)\n\n(defmacro lazy-seq [& body]\n  (list '#*timl#lazy_seq#create (cons 'fn* (cons [] body))))\n\n(defmacro let [& args] (cons 'let* args))\n\n(defn concat\n  ([] (lazy-seq nil))\n  ([x] (lazy-seq x))\n  ([x y]\n    (lazy-seq\n      (let [s (seq x)]\n        (if s\n          (if (chunked-seq? s)\n            (chunk-cons (chunk-first s) (concat (chunk-rest s) y))\n            (cons (first s) (concat (rest s) y)))\n          y))))\n  ([x y & zs]\n     (let [cat (fn cat [xys zs]\n                 (lazy-seq\n                   (let [xys (seq xys)]\n                     (if xys\n                       (if (chunked-seq? xys)\n                         (chunk-cons (chunk-first xys) (cat (chunk-rest xys) zs))\n                         (cons (first xys) (cat (rest xys) zs)))\n                       (if zs\n                         (cat (first zs) (next zs)))))))]\n       (cat (concat x y) zs))))\n\n(defmacro defn- [name & fdecl]\n  `(defn ~(with-meta name (assoc (meta name) :private true)) ~@fdecl))\n\n(defmacro deftype [name slots & more]\n  `(let [type# (deftype* ~name ~slots)]\n     type#))\n\n(defmacro when [test & body]\n  `(if ~test (do ~@body)))\n\n(defmacro if-let [bindings then & else]\n  (let [form (first bindings)\n        tst (first (rest bindings))]\n    `(let [temp# ~tst]\n      (if temp#\n        (let [~form temp#] ~then) ~@else))))\n\n(defmacro when-let [bindings & body]\n  (let [form (first bindings)\n        tst (first (rest bindings))]\n    `(let [temp# ~tst]\n      (if temp#\n        (let [~form temp#] ~@body)))))\n\n(defmacro or\n  ([] nil)\n  ([x] x)\n  ([x & xs] `(let [or# ~x] (if or# or# (or ~@xs)))))\n\n(defmacro and\n  ([] true)\n  ([x] x)\n  ([x & xs] `(let [and# ~x] (if and# (and ~@xs) and#))))\n\n(defn map [f coll]\n  (lazy-seq\n    (when-let [s (seq coll)]\n      (if (can? s chunk-first)\n        (concat\n          (#*timl#coll#mutating_map f (chunk-first s))\n          (map f (chunk-rest s)))\n        (cons (f (first s)) (map f (rest s)))))))\n\n(defn dorun\n  ([coll]\n   (when (seq coll)\n     (if (chunked-seq? coll)\n       (recur (chunk-rest coll))\n       (recur (next coll)))))\n  ([n coll]\n   (when (and (seq coll) (pos? n))\n     (recur (dec n) (next coll)))))\n\n(defn doall\n  ([coll]\n   (dorun coll)\n   coll)\n  ([n coll]\n   (dorun n coll)\n   coll))\n\n(defn nthrest [coll n]\n  (if (and (pos? n) (seq coll))\n    (recur (rest coll) (dec n))\n    coll))\n\n(defn take [n coll]\n  (lazy-seq\n    (when (pos? n)\n      (when-let [s (seq coll)]\n        (cons (first s) (take (dec n) (rest s)))))))\n\n(defn drop\n  [n coll]\n  (let [step (fn [n coll]\n              (if-let [s (seq coll)]\n                (if (pos? n)\n                  (recur (dec n) (rest s))\n                  s)))]\n    (lazy-seq (step n coll))))\n\n(defn take-while [pred coll]\n  (lazy-seq\n    (when-let [s (seq coll)]\n      (when (pred (first s))\n        (cons (first s) (take-while pred (rest s)))))))\n\n(defn partition\n  ([n coll]\n   (partition n n coll))\n  ([n step coll]\n   (lazy-seq\n     (when-let [s (seq coll)]\n       (let [p (doall (take n s))]\n         (when (= n (count p))\n           (cons p (partition n step (nthrest s step))))))))\n  ([n step pad coll]\n   (lazy-seq\n     (when-let [s (seq coll)]\n       (let [p (doall (take n s))]\n         (if (= n (count p))\n           (cons p (partition n step pad (nthrest s step)))\n           (list (take n (concat p pad)))))))))\n\n(defmacro declare [& names]\n  `(do ~@(map (fn [n] (list 'def n)) names)))\n\n(defmacro loop [flat & body]\n  (let [bindings (partition 2 flat)]\n    `((fn ~(vec (map first bindings)) ~@body) ~@(vec (map (fn [x] (first (rest x))) bindings)))))\n\n(defn some\n  [pred coll]\n  (when (seq coll)\n    (or (pred (first coll)) (recur pred (next coll)))))\n\n(defn refer-timl [& args]\n  (apply refer 'timl.core args))\n(defmacro ns [name & args]\n  `(do\n     (in-ns '~name)\n     ~(if (some #{:refer-timl} (map first args))\n        `nil\n        `(refer-timl))\n     ~@(map (fn [[cmd & args]]\n              (or (when (#{:require :use} cmd)\n                    (let [qsym (if (#{:require} cmd)\n                                 `require\n                                 `use)]\n                      `(do ~@(map (fn [a1] `(~qsym '~a1)) args))))\n                  (when (#{:refer} cmd)\n                    `(refer ~@(map (fn [a] `'~a) args)))\n                  (when (#{:refer-timl} cmd)\n                    `(refer-timl ~@(map (fn [a] `'~a) args)))))\n            args)))\n\n(defn ns-resolve\n  ([ns sym] (#*timl#namespace#maybe_resolve ns sym))\n  ([ns env sym] (if (contains? (:locals env) sym) nil (ns-resolve ns sym))))\n\n(defn resolve\n  ([sym] (ns-resolve *ns* sym))\n  ([env sym] (ns-resolve *ns* env sym)))\n\n(defmacro defmethod [name type & body]\n  `(#*timl#type#define_method *ns* '~name ~(symbol (. (resolve type) str)) (fn ~@body)))\n\n(load \"core_macros\")\n(load \"core_basics\")\n(load \"core_seq\")\n(load \"core_coll\")\n(load \"core_ref\")\n(load \"core_vim\")\n"
  },
  {
    "path": "autoload/timl/core_basics.tim",
    "content": "(in-ns 'timl.core)\n\n(declare *1 *2 *3 *e)\n\n(defn not [x] (if x false true))\n\n(defn eval [form] (#*timl#eval form))\n\n(defn constantly [x] (fn [& args] x))\n\n(defn partial\n  ([f] f)\n  ([f arg1]\n   (fn [& args] (apply f arg1 args)))\n  ([f arg1 arg2]\n   (fn [& args] (apply f arg1 arg2 args)))\n  ([f arg1 arg2 arg3]\n   (fn [& args] (apply f arg1 arg2 arg3 args)))\n  ([f arg1 arg2 arg3 & more]\n   (fn [& args] (apply f arg1 arg2 arg3 (concat more args)))))\n\n(defn complement [f]\n  (fn [& rest] (not (apply f rest))))\n\n(defn comp\n  ([f] f)\n  ([f & fns] (fn [& args] (f (apply (apply comp fns) args)))))\n\n(defn max-key\n  ([k x] x)\n  ([k x y] (if (> (k x) (k y)) x y))\n  ([k x y & more]\n   (reduce #(max-key k %1 %2) (max-key k x y) more)))\n"
  },
  {
    "path": "autoload/timl/core_coll.tim",
    "content": "(in-ns 'timl.core)\n\n(defn to-array [x] (#*timl#array#coerce x))\n\n(defn find [m k] (when (contains? m k) [k (get m k)]))\n(defn key [x] (first x))\n(defn val [x] (second x))\n(defn keys [m] (map key m))\n(defn vals [m] (map val m))\n(defn get-in [m ks] (reduce get m ks))\n(defn associative? [c] (can? c assoc))\n\n(defn comparator [>]\n  (fn [x y]\n    (if (> x y)\n      1\n      (if (> y x)\n        -1\n        0))))\n\n(defn sort\n  ([xs] (#*sort (to-array xs)))\n  ([op xs]\n   (let [cmp (comparator op)]\n     (#*sort (to-array xs) #*timl#function#invoke_self cmp))))\n\n(defn merge\n  [& maps]\n  (when (some identity maps)\n    (reduce #(conj (or %1 {}) %2) maps)))\n"
  },
  {
    "path": "autoload/timl/core_macros.tim",
    "content": "(in-ns 'timl.core)\n\n(defmacro defonce [name expr]\n  `(when-not (exists? (munge (str \"g:\" (ns-name *ns*) \"#\" '~name)))\n     (def ~name ~expr)))\n\n(defmacro if-not\n  ([cond then] `(if ~cond nil ~then))\n  ([cond then else] `(if ~cond ~else ~then)))\n\n(defmacro when-not [cond & body]\n  (list 'if cond nil (cons 'do body)))\n\n(defmacro cond [& clauses]\n  (when (seq clauses)\n    (list 'if (first clauses)\n          (first (rest clauses))\n          (cons `cond (rest (rest clauses))))))\n\n(defmacro -> [x & forms]\n  (if (seq forms)\n    (let [form (first forms)\n          more (next forms)] (if more `(-> (-> ~x ~form) ~@more) (if (list? form)\n          `(~(first form) ~x ~@(rest form))\n          (list form x))))\n    x))\n\n(defmacro ->> [x & forms]\n  (if-let [[form & more] (seq forms)]\n    (if (list? form)\n      `(->> (~@form ~x) ~@more)\n      `(->> (~form ~x) ~@more))\n    x))\n\n(defmacro binding [bindings & body]\n  (if (seq bindings)\n    `(let [old# ~(first bindings)]\n       (try\n         (set! ~(first bindings) ~(first (rest bindings)))\n         (binding ~(vec (rest (rest bindings))) ~@body)\n         (finally (set! ~(first bindings) old#))))\n    `(do ~@body)))\n\n(defmacro with-out-str [& body]\n  `(let [tempname# (#*tempname)]\n     (execute \"redraw\")\n     (binding [&verbosefile tempname#]\n       (set! l:TimLfn (fn [] ~@body))\n       (execute \"silent call timl#invoke(l:TimLfn)\"))\n     (#*substitute (slurp tempname#) \"^\\n\" \"\" \"g\")))\n\n(defmacro time [& body]\n  `(let [reltime# (#*reltime)\n        result# (do ~@body)]\n     (printf \"Elapsed time: %s secs\\n\" (#*reltimestr (#*reltime reltime#)))\n     result#))\n\n(defmacro comment [& body])\n"
  },
  {
    "path": "autoload/timl/core_ref.tim",
    "content": "(in-ns 'timl.core)\n\n(defn atom\n  ([state] (#*timl#atom#create state nil nil))\n  ([state & {v :validator m :meta}] (#*timl#atom#create state m v)))\n\n(defmacro delay [& body] `(#*timl#delay#create (fn [] ~@body)))\n\n(defmacro future [& body] `(future-call (fn [] ~@body)))\n"
  },
  {
    "path": "autoload/timl/core_seq.tim",
    "content": "(in-ns 'timl.core)\n\n(defn not-empty [xs] (when (seq xs) xs))\n\n(defn filter [pred coll]\n  (lazy-seq\n    (loop [s (seq coll)]\n      (when s\n        (if (chunked-seq? s)\n          (concat\n            (#*timl#coll#mutating_filter pred (chunk-first s))\n            (filter pred (chunk-rest s)))\n          (let [f (first s) r (rest s)]\n            (if (pred f)\n              (cons f (filter pred r))\n              (recur (seq r)))))))))\n\n(defn iterate [f x]\n  (cons x (lazy-seq (iterate f (f x)))))\n\n(defn repeat\n  ([x] (lazy-seq (cons x (repeat x))))\n  ([n x] (take n (repeat x))))\n\n(defn every?\n  [pred coll]\n  (cond\n   (nil? (seq coll)) true\n   (pred (first coll)) (recur pred (next coll))\n   :else false))\n\n(defn range\n  ([] (range 0 Infinity 1))\n  ([end] (range 0 end 1))\n  ([start end] (range start end 1))\n  ([start end step]\n   (let [comp (if (pos? step) < >)\n         closest #(if (comp % %2) % %2)\n         next-start (closest end (+ start (* 1024 step)))]\n     (if (comp start end)\n       (if (integer? next-start)\n         (chunk-cons\n           (#*range start (dec next-start) step)\n           (lazy-seq (range next-start end step)))\n         (cons start (range (+ start step) end step)))\n       ()))))\n\n(defn reductions [f init xs]\n  (cons init\n        (lazy-seq\n          (if xs\n            (reductions f (f init (first xs)) (rest xs))))))\n\n(defn last [xs] (if (next xs) (recur (next xs)) (first xs)))\n(defn butlast [s]\n  (loop [ret '() s s]\n    (if (next s)\n      (recur (conj ret (first s)) (next s))\n      ret)))\n\n(defn remove\n  [pred coll]\n  (filter (complement pred) coll))\n"
  },
  {
    "path": "autoload/timl/core_vim.tim",
    "content": "(in-ns 'timl.core)\n\n(defn stacklist []\n  (drop 1 (#*timl#exception#loclist (#*expand \"<sfile>\"))))\n\n(defmacro with-cwd [dir & body]\n  `(let [has-local# (when (exists? \"*haslocaldir\") (nonzero? (#*haslocaldir)))\n         chdir# (if has-local# \"lchdir\" \"chdir\")\n         back# (#*getcwd)]\n     (try\n       (execute chdir# (#*fnameescape ~dir))\n       ~@body\n       (finally (execute chdir# (#*fnameescape back#))))))\n\n(defmacro save-excursion [& body]\n  `(let [restore# (#*winsaveview)]\n     (try\n       ~@body\n       (finally (#*winrestview restore#)))))\n"
  },
  {
    "path": "autoload/timl/delay.vim",
    "content": "\" Maintainer: Tim Pope <http://tpo.pe>\n\nif exists(\"g:autoloaded_timl_delay\")\n  finish\nendif\nlet g:autoloaded_timl_delay = 1\n\nfunction! timl#delay#create(fn) abort\n  return s:type.__call__([a:fn, g:timl#nil])\nendfunction\n\nfunction! timl#delay#force(this) abort\n  if timl#type#string(a:this) !=# s:type.str\n    return a:this\n  endif\n  return timl#delay#deref(a:this)\nendfunction\n\nfunction! timl#delay#deref(this) abort\n  if a:this.fn is# g:timl#nil\n    return a:this.val\n  endif\n  let a:this.val = timl#call(a:this.fn, [])\n  let a:this.fn = g:timl#nil\n  return a:this.val\nendfunction\n\nfunction! timl#delay#realized(this) abort\n  return a:this.fn is# g:timl#nil ? g:timl#true : g:timl#false\nendfunction\n\nlet s:type = timl#type#core_define('Delay', ['fn', 'val'], {\n      \\ 'realized?': 'timl#delay#realized',\n      \\ 'deref': 'timl#delay#deref'})\n"
  },
  {
    "path": "autoload/timl/dictionary.vim",
    "content": "\" Maintainer: Tim Pope <http://tpo.pe>\n\nif exists(\"g:autoloaded_timl_dictionary\")\n  finish\nendif\nlet g:autoloaded_timl_dictionary = 1\n\nfunction! timl#dictionary#test(coll) abort\n  return timl#type#string(a:coll) ==# 'vim/Dictionary'\nendfunction\n\nfunction! timl#dictionary#create(_) abort\n  let keyvals = len(a:_) == 1 ? a:_[0] : a:_\n  if timl#map#test(keyvals)\n    let _ = {'seq': timl#coll#seq(keyvals)}\n    let dict = {}\n    while _.seq isnot# g:timl#nil\n      let _.first = timl#coll#first(_.seq)\n      let dict[timl#string#coerce(_.first[0])] = _.first[1]\n      let _.seq = timl#coll#next(_.seq)\n    endwhile\n    return dict\n  endif\n  let dictionary = {}\n  for i in range(0, len(keyvals)-1, 2)\n    let dictionary[timl#string#coerce(keyvals[i])] = get(keyvals, i+1, g:timl#nil)\n  endfor\n  return dictionary\nendfunction\n\nfunction! timl#dictionary#seq(dict) abort\n  let items = map(filter(items(a:dict), 'v:val[0][0] !=# \"#\"'), '[v:val[0], v:val[1]]')\n  return empty(items) ? g:timl#nil : timl#array_seq#create(items)\nendfunction\n\nfunction! timl#dictionary#lookup(this, key, ...) abort\n  return get(a:this, timl#string#coerce(a:key), a:0 ? a:1 : g:timl#nil)\nendfunction\n\nfunction! timl#dictionary#empty(this) abort\n  return {}\nendfunction\n\nfunction! timl#dictionary#conj(this, ...) abort\n  let orig = a:this\n  let this = copy(a:this)\n  let _ = {}\n  for _.e in a:000\n    let this[timl#string#coerce(timl#coll#first(_.e))] = timl#coll#fnext(_.e)\n  endfor\n  if islocked('orig')\n    lockvar 1 this\n  endif\n  return this\nendfunction\n\nfunction! timl#dictionary#conjb(this, ...) abort\n  let _ = {}\n  for _.e in a:000\n    let a:this[timl#string#coerce(timl#coll#first(_.e))] = timl#coll#fnext(_.e)\n  endfor\n  return a:this\nendfunction\n\nfunction! timl#dictionary#assoc(this, ...) abort\n  let orig = a:this\n  let this = copy(a:this)\n  for i in range(0, len(a:000)-2, 2)\n    let this[timl#string#coerce(a:000[i])] = a:000[i+1]\n  endfor\n  if islocked('orig')\n    lockvar 1 this\n  endif\n  return this\nendfunction\n\nfunction! timl#dictionary#assocb(this, ...) abort\n  for i in range(0, len(a:000)-2, 2)\n    let a:this[timl#string#coerce(a:000[i])] = a:000[i+1]\n  endfor\n  return a:this\nendfunction\n\nfunction! timl#dictionary#dissoc(this, ...) abort\n  let _ = {}\n  let orig = a:this\n  let this = copy(a:this)\n  for _.x in a:000\n    let key = timl#string#coerce(_.x)\n    if has_key(this, key)\n      call remove(this, key)\n    endif\n  endfor\n  if islocked('orig')\n    lockvar 1 this\n  endif\n  return this\nendfunction\n\nfunction! timl#dictionary#dissocb(this, ...) abort\n  let _ = {}\n  for _.x in a:000\n    let key = timl#string#coerce(_.x)\n    if has_key(a:this, key)\n      call remove(a:this, key)\n    endif\n  endfor\n  return a:this\nendfunction\n\nfunction! timl#dictionary#transient(this) abort\n  let this = a:this\n  return islocked('this') ? copy(this) : this\nendfunction\n\nfunction! timl#dictionary#persistentb(this) abort\n  lockvar 1 a:this\n  return a:this\nendfunction\n"
  },
  {
    "path": "autoload/timl/equality.vim",
    "content": "\" Maintainer: Tim Pope <http://tpo.pe/>\n\nif exists('g:autoloaded_timl_equality')\n  finish\nendif\nlet g:autoloaded_timl_equality = 1\n\nfunction! timl#equality#test(x, y) abort\n  if timl#type#canp(a:x, g:timl#core.equiv)\n    return timl#truth(timl#invoke(g:timl#core.equiv, a:x, a:y))\n  else\n    return type(a:x) ==# type(a:y) && a:x ==# a:y\n  endif\nendfunction\n\nfunction! timl#equality#all(_) abort\n  let _ = {}\n  for _.y in a:_[1:-1]\n    if !timl#equality#test(a:_[0], _.y)\n      return g:timl#false\n    endif\n  endfor\n  return g:timl#true\nendfunction\n\nfunction! timl#equality#not(_) abort\n  return timl#equality#all(a:_) ==# g:timl#false ? g:timl#true : g:timl#false\nendfunction\n\nfunction! timl#equality#identical(_) abort\n  let _ = {}\n  for _.y in a:_[1:-1]\n    if a:_[0] isnot# _.y\n      return g:timl#false\n    endif\n  endfor\n  return g:timl#true\nendfunction\n\nfunction! timl#equality#seq(x, y) abort\n  if a:x is# a:y\n    return g:timl#true\n  elseif !timl#coll#sequentialp(a:y)\n    return g:timl#false\n  endif\n  let _ = {'x': timl#coll#seq(a:x), 'y': timl#coll#seq(a:y)}\n  while _.x isnot# g:timl#nil && _.y isnot# g:timl#nil\n    if !timl#equality#test(timl#coll#first(_.x), timl#coll#first(_.y))\n      return g:timl#false\n    endif\n    let _.x = timl#coll#next(_.x)\n    let _.y = timl#coll#next(_.y)\n  endwhile\n  return _.x is# g:timl#nil && _.y is# g:timl#nil ? g:timl#true : g:timl#false\nendfunction\n"
  },
  {
    "path": "autoload/timl/exception.vim",
    "content": "\" Maintainer: Tim Pope <http://tpo.pe/>\n\nif exists('g:autoloaded_timl_exception')\n  finish\nendif\nlet g:autoloaded_timl_exception = 1\n\nlet s:loctype = timl#type#core_create('Location', ['bufnr', 'filename', 'lnum',\n      \\ 'pattern', 'col', 'vcol', 'nr', 'text', 'type'])\nlet s:locproto = timl#type#bless(s:loctype,\n      \\ {'bufnr': 0, 'filename': '', 'lnum': 0, 'pattern': '', 'col': 0, 'vcol': 0, 'nr': 0, 'text': '', 'type': ''})\nfunction! timl#exception#loclist(throwpoint) abort\n  let list = []\n  if a:throwpoint !~# '^function '\n    call add(list, {\"filename\": matchstr(a:throwpoint, '^.\\{-\\}\\ze\\.\\.')})\n  endif\n  for fn in split(matchstr(a:throwpoint, '\\%( \\|\\.\\.\\)\\zs.\\{-\\}\\ze\\%(,\\|$\\)'), '\\.\\.')\n    call insert(list, copy(s:locproto))\n    let list[0].text = fn\n    if has_key(g:timl_functions, fn)\n      let list[0].filename = g:timl_functions[fn].file\n      let list[0].lnum = g:timl_functions[fn].line\n    else\n      try\n        redir => out\n        exe 'silent verbose function '.(fn =~# '^\\d' ? '{'.fn.'}' : fn)\n      catch\n      finally\n        redir END\n      endtry\n      if fn !~# '^\\d'\n        let list[0].filename = expand(matchstr(out, \"\\n\\tLast set from \\\\zs[^\\n]*\"))\n        let list[0].pattern = '^\\s*fu\\%[nction]!\\=\\s*'.substitute(fn,'^<SNR>\\d\\+_','s:','').'\\s*('\n      endif\n    endif\n  endfor\n  return list\nendfunction\n\nlet s:type = timl#type#core_create('Exception')\nfunction! timl#exception#build(exception, throwpoint) abort\n  let dict = {\"exception\": a:exception, \"throwpoint\": a:throwpoint}\n  let dict.line = +matchstr(a:throwpoint, '\\d\\+$')\n  let dict.qflist = timl#exception#loclist(a:throwpoint)\n  return timl#type#bless(s:type, dict)\nendfunction\n"
  },
  {
    "path": "autoload/timl/false.vim",
    "content": "\" Maintainer: Tim Pope <http://tpo.pe/>\n\nif exists(\"g:autoloaded_timl_false\")\n  finish\nendif\nlet g:autoloaded_timl_false = 1\n\nif !exists('g:timl#false')\n  let g:timl#false = timl#type#bless(timl#type#core_create('Boolean'), {'val': 0})\n  lockvar 1 g:timl#false\nendif\n\nfunction! timl#false#identity() abort\n  return g:timl#false\nendfunction\n\nfunction! timl#false#test(val) abort\n  return a:val is# g:timl#false\nendfunction\n"
  },
  {
    "path": "autoload/timl/file.tim",
    "content": "(ns timl.file)\n\n(defn slash [] (if (and (exists? \"+shellslash\") (not &shellslash)) \"\\\\\" \"/\"))\n\n(defn ^{:help \"filereadable()\"} filereadable? [f] (nonzero? (#*filereadable f)))\n(defn filewritable? [f] (nonzero? (#*filewritable f)))\n(defn directory? [f] (nonzero? (#*isdirectory f)))\n(defn ftype [f]\n  (let [type (#*getftype f)] (when (not= \"\" type) (keyword type))))\n(defn file? [f] (= \"file\" (#*getftype f)))\n(defn mtime [f] (let [time (#*getftime f)] (when (not= -1 time) (inst time))))\n(defn fsize [f] (not-negative (#*getfsize f)))\n(defn expand [f] (#*expand f))\n(defn delete [f] (zero? (#*delete f)))\n(defn rename [from to] (zero? (#*rename from to)))\n\n(defn absolute [f] (#*fnamemodify f \":p\"))\n(defn relative [f] (#*fnamemodify f \":.\"))\n(defn basename [f] (#*fnamemodify f \":t\"))\n(defn dirname [f] (#*fnamemodify f \":h\"))\n(defn shortname [f] (#*fnamemodify f \":~:.\"))\n(defn extname [f] (#*fnamemodify f \":e\"))\n(defn rootname [f] (#*fnamemodify f \":r\"))\n\n(defn join-path [path]\n  (if (string? path)\n    path\n    (join \",\" (map #(#*escape % \",\") path))))\n(defn glob [pat]\n  (binding [&suffixes \"\"\n            &wildignore \"\"]\n    (split (#*glob pat) \"\\n\")))\n(defn glob-path [path pat]\n  (binding [&suffixes \"\"\n            &wildignore \"\"]\n    (split (#*globpath (join-path path) pat) \"\\n\")))\n; TODO: findfile, finddir\n\n(defn help-topics [pattern]\n  (binding [&tags (#*escape (join-path (map #(str % \"/doc/tags\") (split &runtimepath \",\"))) \" \")]\n    (#*taglist pattern)))\n"
  },
  {
    "path": "autoload/timl/ftplugin.tim",
    "content": "(ns timl.ftplugin)\n(require '[timl.plugin-helper :as ph])\n\n(defmacro include-guard [& default]\n  (let [param (or (first default) 'b:did-ftplugin)]\n   `(ph/include-guard ~param)))\n\n; should append to b:undo-ftplugin\n(defmacro setlocal [& opts]\n  `(do\n     (execute (str \"setlocal \" ~(ph/build-option-string opts)))\n     (set! b:undo-ftplugin ~(ph/extract-option-restore opts))))\n"
  },
  {
    "path": "autoload/timl/funcref.vim",
    "content": "\" Maintainer: Tim Pope <http://tpo.pe>\n\nif exists(\"g:autoloaded_timl_funcref\")\n  finish\nendif\nlet g:autoloaded_timl_funcref = 1\n\nfunction! timl#funcref#call(this, _) abort\n  return call(a:this, a:_)\nendfunction\n\nlet s:type = type(function('tr'))\nfunction! timl#funcref#test(this) abort\n  return type(a:this) == s:type\nendfunction\n\nfunction! timl#funcref#string(this) abort\n  return join([a:this])\nendfunction\n\nfunction! timl#funcref#hash(this) abort\n  return timl#hash#string(string(a:this))\nendfunction\n\nfunction! timl#funcref#exists(name) abort\n  return exists(a:name =~# '^\\d\\+$' ? '*{'.a:name.'}' : '*'.a:name)\nendfunction\n\nfunction! timl#funcref#anonymous() abort\n  let d = {}\n  function! d.f() abort\n    return +matchstr(expand('<sfile>'), '\\d\\+$')\n  endfunction\n  return d.f\nendfunction\n"
  },
  {
    "path": "autoload/timl/function.vim",
    "content": "\" Maintainer: Tim Pope <http://tpo.pe/>\n\nif exists('g:autoloaded_timl_function')\n  finish\nendif\nlet g:autoloaded_timl_function = 1\n\nlet s:type = timl#type#core_create('Function')\n\nfunction! timl#function#unimplemented(...) abort\n  throw 'timl: unimplemented'\nendfunction\n\nfunction! timl#function#birth(locals, ...) abort\n  return timl#type#bless(s:type, {\n        \\ 'ns': g:timl#core._STAR_ns_STAR_,\n        \\ 'name': a:0 ? a:1 : g:timl#nil,\n        \\ 'locals': a:locals,\n        \\ '__call__': function('timl#function#unimplemented')})\nendfunction\n\nfunction! timl#function#call(this, _) abort\n  return a:this.__call__(a:_)\nendfunction\n\nfunction! timl#function#apply(_) abort\n  if len(a:_) < 2\n    throw 'timl: arity error'\n  endif\n  let [F; args] = a:_\n  let args = args[0:-2] + timl#array#coerce(args[-1])\n  return timl#call(F, args)\nendfunction\n\nfunction! timl#function#identity(x) abort\n  return a:x\nendfunction\n\nfunction! timl#function#invoke_self(...) dict abort\n  return self.__call__(a:000)\nendfunction\n\nfunction! timl#function#hash(fn) abort\n  return timl#hash#string(string(a:fn.__call__))\nendfunction\n\nlet s:def = timl#symbol('def')\nlet s:let = timl#symbol('timl.core/let')\nlet s:fns = timl#symbol('fn*')\nlet s:fn = timl#symbol('timl.core/fn')\nlet s:defn = timl#symbol('timl.core/defn')\nlet s:setq = timl#symbol('set!')\nlet s:dot = timl#symbol('.')\nlet s:form = timl#symbol('&form')\nlet s:env = timl#symbol('&env')\n\nfunction! timl#function#destructure(params, body) abort\n  let lets = []\n  let params = []\n  let _ = {}\n  for _.param in timl#array#coerce(a:params)\n    if timl#symbol#test(_.param)\n      call add(params, _.param)\n    else\n      call add(params, timl#symbol#gen(\"p__\"))\n      call extend(lets, [_.param, params[-1]])\n    endif\n  endfor\n  if empty(lets)\n    return timl#cons#create(timl#vector#claim(params), a:body)\n  else\n    return timl#list(timl#vector#claim(params), timl#cons#create(s:let, timl#cons#create(timl#vector#claim(lets), a:body)))\n  endif\nendfunction\n\nfunction! timl#function#fn(form, env, ...) abort\n  let _ = {}\n  let _.sigs = timl#list#create(a:000)\n  if timl#symbol#test(a:000[0])\n    let name = a:000[0]\n    let _.sigs = timl#coll#next(_.sigs)\n  endif\n  if timl#vector#test(timl#coll#first(_.sigs))\n    let _.sigs = timl#function#destructure(timl#coll#first(_.sigs), timl#coll#next(_.sigs))\n  else\n    let sigs = []\n    while _.sigs isnot# g:timl#nil\n      call add(sigs, timl#function#destructure(timl#coll#ffirst(_.sigs), timl#coll#nfirst(_.sigs)))\n      let _.sigs = timl#coll#next(_.sigs)\n    endwhile\n    let _.sigs = timl#list#create(sigs)\n  endif\n  if exists('name')\n    let _.sigs = timl#cons#create(name, _.sigs)\n  endif\n  return timl#cons#create(s:fns, _.sigs, timl#meta#get(a:form))\nendfunction\n\nfunction! timl#function#defn(form, env, name, ...) abort\n  return timl#list#create([s:def, a:name, timl#meta#with(timl#list#create([s:fn, a:name] + a:000), timl#meta#get(a:form))])\nendfunction\n\nlet s:kmacro = timl#keyword#intern('macro')\nfunction! timl#function#defmacro(form, env, name, params, ...) abort\n  let extra = [s:form, s:env]\n  if timl#vector#test(a:params)\n    let body = [timl#vector#claim(extra + timl#array#coerce(a:params))] + a:000\n  else\n    let _ = {}\n    let body = []\n    for _.list in [a:params] + a:000\n      call add(body, timl#cons#create(timl#vector#claim(extra + timl#array#coerce(timl#coll#first(_.list))), timl#coll#next(_.list)))\n    endfor\n  endif\n  let name = copy(a:name)\n  let name.meta = timl#invoke(g:timl#core.assoc, get(a:name, 'meta', g:timl#nil), s:kmacro, g:timl#true)\n  let fn = timl#symbol#gen('fn')\n  return timl#list#create([s:defn, name] + body)\nendfunction\n"
  },
  {
    "path": "autoload/timl/future.vim",
    "content": "\" Maintainer: Tim Pope <http://tpo.pe>\n\nif exists(\"g:autoloaded_timl_future\")\n  finish\nendif\nlet g:autoloaded_timl_future = 1\n\nif !exists('s:queue')\n  let s:queue = []\nendif\n\nfunction! timl#future#call(fn) abort\n  let future = s:type.__call__([a:fn, g:timl#nil, g:timl#nil])\n  call add(s:queue, future)\n  return future\nendfunction\n\nfunction! timl#future#realize(this) abort\n  if a:this.fn isnot# g:timl#nil\n    try\n      let a:this.val = timl#call(a:this.fn, [])\n    catch /^\\%(Vim:Interrupt\\)\\@!.*/\n      let a:this.exception = timl#exception#build(v:exception, v:throwpoint)\n    endtry\n    let a:this.fn = g:timl#nil\n  endif\n  return a:this\nendfunction\n\nfunction! timl#future#deref(this) abort\n  if a:this.fn isnot# g:timl#nil\n    call timl#future#realize(a:this)\n  endif\n  if a:this.exception is# g:timl#nil\n    return a:this.val\n  endif\n  throw substitute(a:this.exception.exception, '^Vim', 'Tim', '')\nendfunction\n\nfunction! timl#future#realized(this) abort\n  return a:this.fn is# g:timl#nil ? g:timl#true : g:timl#false\nendfunction\n\nfunction! timl#future#process() abort\n  while !empty(s:queue) && !getchar(1)\n    call timl#future#realize(remove(s:queue, 0))\n  endwhile\nendfunction\n\nlet s:type = timl#type#core_define('Future', ['fn', 'val', 'exception'], {\n      \\ 'realized?': 'timl#future#realized',\n      \\ 'deref': 'timl#future#deref'})\n\naugroup timl_future\n  autocmd!\n  autocmd CursorHold * call timl#future#process()\naugroup END\n"
  },
  {
    "path": "autoload/timl/hash.vim",
    "content": "\" Maintainer: Tim Pope <http://tpo.pe/>\n\nif exists('g:autoloaded_timl_hash')\n  finish\nendif\nlet g:autoloaded_timl_hash = 1\n\nfunction! timl#hash#compute(obj) abort\n  if type(a:obj) == type('')\n    let hash = timl#hash#string(a:obj)\n  elseif type(a:obj) == type(0)\n    let hash = a:obj\n  elseif timl#type#canp(a:obj, g:timl#core.hash)\n    let hash = timl#invoke(g:timl#core.hash, a:obj)\n  elseif timl#type#canp(a:obj, g:timl#core.seq)\n    let hash = timl#hash#sequential(a:obj)\n  else\n    let hash = timl#invoke(g:timl#core.hash, a:obj)\n  endif\n  if exists('hash')\n    let hash = hash % 0x40000000\n    if hash < 0\n      let hash += 0x40000000\n    endif\n    return hash\n  endif\nendfunction\n\nfunction! timl#hash#string(str) abort\n  let r = 0\n  let l = len(a:str)\n  let i = 0\n  while i < l\n    let r = 31 * r + char2nr(a:str[i])\n    let i += 1\n  endwhile\n  return r\nendfunction\n\nfunction! timl#hash#str_attribute(obj) abort\n  return timl#hash#string(a:obj.str)\nendfunction\n\nfunction! timl#hash#sequential(s) abort\n  let r = 0\n  let _ = {'seq': timl#coll#seq(a:s)}\n  while _.seq isnot# g:timl#nil\n    let r += timl#hash#compute(timl#coll#first(a:s))\n    let _.seq = timl#coll#next(_.seq)\n  endwhile\n  return r\nendfunction\n\nlet s:idx = '0123456789abcdefghijklmnopqrstuv'\nfunction! s:idx_for(hash, level) abort\n  return s:idx[(a:hash/a:level) % 32]\nendfunction\n\nfunction! timl#hash#find(node, key) abort\n  let hash = timl#hash#compute(a:key)\n  let level = 1\n  let node = a:node\n  let idx = s:idx_for(hash, level)\n  while has_key(node, idx)\n    if type(node[idx]) == type([])\n      for pair in node[idx]\n        if timl#equality#test(a:key, pair[0])\n          return pair\n        endif\n      endfor\n      return g:timl#nil\n    endif\n    let level = level * 32\n    let node = node[idx]\n    let idx = s:idx_for(hash, level)\n  endwhile\n  return g:timl#nil\nendfunction\n\nfunction! timl#hash#items(node) abort\n  let _ = {}\n  let array = []\n  for [k, _.v] in items(a:node)\n    if type(_.v) == type([])\n      call extend(array, _.v)\n    else\n      call extend(array, timl#hash#items(_.v))\n    endif\n  endfor\n  return array\nendfunction\n\nfunction! timl#hash#assoc(node, key, val) abort\n  let hash = timl#hash#compute(a:key)\n  return s:assoc(a:node, hash, a:key, a:val, 1)\nendfunction\n\nfunction! s:assoc(node, hash, key, val, level) abort\n  let idx = s:idx_for(a:hash, a:level)\n  if !has_key(a:node, idx)\n    return [extend({idx : [[a:key, a:val]]}, a:node), 1]\n  elseif type(a:node[idx]) == type([])\n    let hash2 = timl#hash#compute(a:node[idx][0][0])\n    if hash2 == a:hash\n      for i in range(len(a:node[idx]))\n        if timl#equality#test(a:key, a:node[idx][i][0])\n          if a:node[idx][i][1] is# a:val\n            return [a:node, 0]\n          endif\n          let node = extend({idx : copy(a:node[idx])}, a:node, 'keep')\n          let node[idx][i] = [a:key, a:val]\n          return [node, 0]\n        endif\n      endfor\n      let node = copy(a:node)\n      let node[idx] += [[a:key, a:val]]\n      return [node, 1]\n    else\n      let node = extend({idx : {}}, a:node, 'keep')\n      for old in a:node[idx]\n        let [node, _] = s:assoc(node, hash2, old[0], old[1], a:level)\n      endfor\n      return s:assoc(node, a:hash, a:key, a:val, a:level)\n    endif\n  else\n    let [node, c] = s:assoc(a:node[idx], a:hash, a:key, a:val, a:level * 32)\n    if a:node[idx] is# node\n      return [a:node, c]\n    else\n      return [extend({idx : node}, a:node, 'keep'), c]\n    endif\n  endif\nendfunction\n\nfunction! timl#hash#dissoc(node, key) abort\n  let hash = timl#hash#compute(a:key)\n  return s:dissoc(a:node, hash, a:key, 1)\nendfunction\n\nfunction! s:dissoc(node, hash, key, level) abort\n  let idx = s:idx_for(a:hash, a:level)\n  if !has_key(a:node, idx)\n    return [a:node, 0]\n  elseif type(a:node[idx]) == type([])\n    let hash2 = timl#hash#compute(a:node[idx][0][0])\n    if hash2 == a:hash\n      for i in range(len(a:node[idx]))\n        if timl#equality#test(a:key, a:node[idx][i][0])\n          let node = extend({idx : copy(a:node[idx])}, a:node, 'keep')\n          call remove(node[idx], i)\n          return [node, 1]\n        endif\n      endfor\n    endif\n    return [a:node, 0]\n  else\n    let [node, c] = s:dissoc(a:node[idx], a:hash, a:key, a:level * 32)\n    if node is# a:node[idx]\n      return [a:node, c]\n    elseif empty(node)\n      let node2 = copy(node)\n      call remove(node2, idx)\n      return [node2, c]\n    else\n      return [extend({idx : node}, a:node, 'keep'), c]\n    endif\n  endif\nendfunction\n"
  },
  {
    "path": "autoload/timl/indent.tim",
    "content": "(ns timl.indent)\n(require '[timl.plugin-helper :as ph])\n\n(defmacro include-guard [& default]\n  (let [param (or (first default) 'b:did-indent)]\n   `(ph/include-guard ~param)))\n\n(defmacro setlocal [& opts]\n  `(do\n     (execute (str \"setlocal \" ~(ph/build-option-string opts)))\n     (set! b:undo-indent ~(ph/extract-option-restore opts))))\n"
  },
  {
    "path": "autoload/timl/inst.vim",
    "content": "\" Maintainer: Tim Pope <http://tpo.pe/>\n\nif exists('g:autoloaded_timl_inst')\n  finish\nendif\nlet g:autoloaded_timl_inst = 1\n\nfunction! timl#inst#sleep(msec) abort\n  execute 'sleep' a:msec.'m'\n  return g:timl#nil\nendfunction\n\nfunction! timl#inst#create(...) abort\n  if !a:0\n    return timl#inst#now()\n  elseif type(a:1) == type('')\n    return timl#inst#parse(a:1)\n  elseif type(a:1) == type(0)\n    return timl#inst#from_ts(a:1)\n  elseif type(a:1) == 5\n    return timl#inst#from_ts(float2nr(a:1), float2nr(1000000*abs(a:1-trunc(a:1))))\n  elseif type(a:1) == type({}) && get(a:1, '__type__') == s:type\n    return a:1\n  endif\n  throw \"timl: can't create Instant from \".timl#type#string(a:1)\nendfunction\n\n\" In Vim, -4 / 3 == -1.  Let's return -2 instead.\nfunction! s:div(a,b) abort\n  if a:a < 0 && a:b > 0\n    return (a:a-a:b+1)/a:b\n  elseif a:a > 0 && a:b < 0\n    return (a:a-a:b-1)/a:b\n  else\n    return a:a / a:b\n  endif\nendfunction\n\nfunction! timl#inst#jd(year, mon, day) abort\n  let y = a:year + 4800 - (a:mon <= 2)\n  let m = a:mon + (a:mon <= 2 ? 9 : -3)\n  let jul = a:day + (153*m+2)/5 + s:div(1461*y,4) - 32083\n  return jul - s:div(y,100) + s:div(y,400) + 38\nendfunction\n\nlet s:jdepoch = timl#inst#jd(1970, 1, 1)\nfunction! timl#inst#ts(year, mon, day, hour, min, sec) abort\n  return (timl#inst#jd(a:year, a:mon, a:day) - s:jdepoch) * 86400 + a:hour * 3600 + a:min * 60 + a:sec\nendfunction\n\nfunction! timl#inst#parse(str) abort\n  let str = timl#string#coerce(a:str)\n  let results = matchlist(str, '\\c\\v(\\d{4})-(\\d\\d)-(\\d\\d)t(\\d\\d):(\\d\\d):(\\d\\d)%(\\.(\\d+))=%(z|([+-]\\d\\d):(\\d\\d))$')\n  if !empty(results)\n    call remove(results, 0)\n    let results[6] = results[6][0:5] . repeat('0', 6-len(results[6]))\n    call map(results, 'str2nr(v:val)')\n    let t = {}\n    let [t.year, t.mon, t.day, t.hour, t.min, t.sec, t.usec] = results[0:6]\n    let t.offset = results[7] * 60 + results[8]\n    let t.unix = timl#inst#ts(t.year, t.mon, t.day, t.hour, t.min-t.offset, t.sec)\n    return timl#type#bless(s:type, t)\n  endif\n  throw \"timl: invalid date string \".str\nendfunction\n\nfunction! timl#inst#from_ts(sec, ...) abort\n  let t = {'unix': a:sec, 'usec': a:0 ? a:1 : 0}\n  let components = map(split(strftime(\"%Y %m %d %H %M %S\", t.unix), ' '), 'str2nr(v:val)')\n  let t.offset = (call('timl#inst#ts', components) - t.unix)/60\n  let [t.year, t.mon, t.day, t.hour, t.min, t.sec] = components\n  return timl#type#bless(s:type, t)\nendfunction\n\nfunction! timl#inst#now() abort\n  if has('unix')\n    return call('timl#inst#from_ts', reltime())\n  elseif has('ruby')\n    ruby VIM.command('return timl#inst#from_ts(%s, str2nr(\"%s\"[0:5]))' % Time.now.to_f.to_s.split('.'))\n  else\n    return timl#inst#from_ts(localtime())\n  endif\nendfunction\n\nfunction! timl#inst#to_string(t) abort\n  let min_offset = a:t.offset % 60\n  return printf('%04d-%02d-%02dT%02d:%02d:%02d.%06d%+03d:%02d', a:t.year, a:t.mon, a:t.day, a:t.hour, a:t.min, a:t.sec, a:t.usec, a:t.offset/60, (a:t.offset < 0 ? -1 : 1) * a:t.offset % 60)\nendfunction\n\nlet s:type = timl#type#core_define('Instant', ['year', 'mon', 'day', 'hour', 'min', 'sec', 'offset', 'unix'], {\n      \\ 'to-string': 'timl#inst#to_string'})\n"
  },
  {
    "path": "autoload/timl/interactive.vim",
    "content": "\" Maintainer: Tim Pope <http://tpo.pe/>\n\nif exists('g:autoloaded_timl_interactive')\n  finish\nendif\nlet g:autoloaded_timl_interactive = 1\n\nfunction! s:function(name) abort\n  return function(substitute(a:name,'^s:',matchstr(expand('<sfile>'), '.*\\zs<SNR>\\d\\+_'),''))\nendfunction\n\nfunction! s:lencompare(a, b) abort\n  return len(a:a) - len(a:b)\nendfunction\n\nfunction! timl#interactive#ns_for_file(file) abort\n  let file = fnamemodify(a:file, ':p')\n  let candidates = []\n  for glob in split(&runtimepath, ',')\n    let candidates += filter(split(glob(glob), \"\\n\"), 'file[0 : len(v:val)-1] ==# v:val && file[len(v:val)] =~# \"[\\\\/]\"')\n  endfor\n  if empty(candidates)\n    return 'user'\n  endif\n  let dir = sort(candidates, s:function('s:lencompare'))[-1]\n  let path = file[len(dir)+1 : -1]\n  return substitute(tr(fnamemodify(path, ':r:r'), '\\/_', '..-'), '^\\%(autoload\\|plugin\\|test\\).', '', '')\nendfunction\n\nfunction! timl#interactive#ns_for_cursor(...) abort\n  call timl#loader#init()\n  let pattern = '\\c(\\%(in-\\)\\=ns\\s\\+''\\=[[:alpha:]]\\@='\n  let line = 0\n  if !a:0 || a:1\n    let line = search(pattern, 'bcnW')\n  endif\n  if !line\n    let i = 1\n    while i < line('$') && i < 100\n      if getline(i) =~# pattern\n        let line = i\n        break\n      endif\n      let i += 1\n    endwhile\n  endif\n  if line\n    let ns = matchstr(getline(line), pattern.'\\zs[[:alnum:]._-]\\+')\n  else\n    let ns = timl#interactive#ns_for_file(expand('%:p'))\n  endif\n  let nsobj = timl#namespace#find(timl#symbol#intern(ns))\n  if nsobj isnot# g:timl#nil\n    return ns\n  else\n    return 'user'\n  endif\nendfunction\n\nlet s:skip = \"comment\\\\|string\\\\|regex\\\\|character\"\nfunction! s:beginning_of_sexp() abort\n  let open = '[[{(]'\n  let close = '[]})]'\n  let skip = 'synIDattr(synID(line(\".\"),col(\".\"),1),\"name\") =~? s:skip'\n  let pos = searchpairpos(open, '', close, 'bn', skip)\n  if pos[0]\n    if pos[1] > 2 && getline(pos[0])[pos[1]-3 : pos[1]-2] ==# '#*'\n      let pos[1] -= 2\n    endif\n    while pos[1] > 1 && getline(pos[0])[pos[1]-2] =~# '[#''`~@]'\n      let pos[1] -= 1\n    endwhile\n    return [0] + pos + [0]\n  else\n    return [0, line('.'), 1, 0]\n  endif\nendfunction\n\nfunction! timl#interactive#eval_opfunc(type) abort\n  let selection = &selection\n  let clipboard = &clipboard\n  let reg = @@\n  try\n    set selection=inclusive clipboard=\n    if a:type =~# '^\\d\\+$'\n      let open = '[[{(]'\n      let close = '[]})]'\n      let skip = 'synIDattr(synID(line(\".\"),col(\".\"),1),\"name\") =~? s:skip'\n      if searchpair(open, '', close, 'rc', skip)\n        call setpos(\"']\", getpos(\".\"))\n        call setpos(\"'[\", s:beginning_of_sexp())\n      else\n        call setpos(\"'[\", [0, line(\".\"), 1, 0])\n        call setpos(\"']\", [0, line(\".\"), col(\"$\"), 0])\n      endif\n      silent exe \"normal! `[v`]y\"\n    elseif a:type =~# \"[vV\\C-V]\"\n      silent exe \"normal! `<\" . a:type . \"`>y\"\n    elseif a:type ==# 'line'\n      silent exe \"normal! '[V']y\"\n    elseif a:type ==# 'block'\n      silent exe \"normal! `[\\<C-V>`]y\"\n    elseif a:type ==# 'char'\n      silent exe \"normal! `[v`]y\"\n    else\n      return\n    endif\n    let string = repeat(\"\\n\", line(\"'[\")-1) . repeat(\" \", col(\"'[\")-1) . @@\n  finally\n    let &selection = selection\n    let &clipboard = clipboard\n    let @@ = reg\n  endtry\n  let ns = g:timl#core._STAR_ns_STAR_\n  let port = timl#reader#open_string(string, expand('%:p'))\n  try\n    let g:timl#core._STAR_ns_STAR_ = timl#namespace#find(timl#symbol#intern(timl#interactive#ns_for_cursor()))\n    echo timl#printer#string(timl#loader#consume(port))\n    let &syntax = &syntax\n  catch //\n    echohl ErrorMsg\n    echo v:exception\n    echohl NONE\n    unlet! g:timl#core._STAR_e\n    let g:timl#core._STAR_e = timl#exception#build(v:exception, v:throwpoint)\n  finally\n    call timl#reader#close(port)\n    let g:timl#core._STAR_ns_STAR_ = ns\n  endtry\nendfunction\n\nfunction! timl#interactive#return() abort\n  if !empty(getline('.')[col('.')]) || synIDattr(synID(line('.'), col('.')-1, 1), 'name') =~? s:skip || getline('.') =~# '^\\s*\\%(;.*\\)\\=$'\n    return \"\\<CR>\"\n  endif\n  let beg = s:beginning_of_sexp()\n  let end = getpos(\".\")\n  if beg[1] == end[1]\n    let string = getline(beg[1])[beg[2]-1 : end[2]-1]\n  else\n    let string = getline(beg[1])[beg[2]-1 : -1] . \"\\n\"\n          \\ . join(map(getline(beg[1]+1, end[1]-1), 'v:val . \"\\n\"'))\n          \\ . getline(end[1])[0 : end[2]-1]\n  endif\n  let string = repeat(\"\\n\", beg[1]-1) . repeat(\" \", beg[2]-1) . string\n  let ns = g:timl#core._STAR_ns_STAR_\n  let port = timl#reader#open_string(string, expand('%:p'))\n  try\n    let g:timl#core._STAR_ns_STAR_ = timl#namespace#find(timl#symbol#intern(timl#interactive#ns_for_cursor()))\n    let body = \";= \" . timl#printer#string(timl#loader#consume(port))\n    call setloclist(0, [])\n    let &syntax = &syntax\n  catch //\n    unlet! g:timl#core._STAR_e\n    let g:timl#core._STAR_e = timl#exception#build(v:exception, v:throwpoint)\n    call setloclist(0, g:timl#core._STAR_e.qflist)\n    let body = \";! \" . timl#printer#string(g:timl#core._STAR_e)\n  finally\n    call timl#reader#close(port)\n    let g:timl#core._STAR_ns_STAR_ = ns\n  endtry\n  if len(substitute(body.getline('.'), '.', '.', 'g')) < 80\n    return \" \".body.\"\\<CR>\"\n  else\n    return \"\\<CR>\".body.\"\\<CR>\"\n  endif\nendfunction\n\nfunction! timl#interactive#omnicomplete(findstart, base) abort\n  if a:findstart\n    let line = getline('.')[0 : col('.')-2]\n    return col('.') - strlen(matchstr(line, '\\k\\+$')) - 1\n  endif\n  let results = []\n  let ns = timl#interactive#ns_for_cursor()\n  if timl#namespace#find(ns) is g:timl#nil\n    let ns = 'user'\n  endif\n  let results = map(keys(timl#namespace#map(timl#namespace#find(ns))), '{\"word\": v:val}')\n  return filter(results, 'v:val.word[0] !=# \"#\" && (a:base ==# \"\" || a:base ==# v:val.word[0 : strlen(a:base)-1])')\nendfunction\n\nfunction! timl#interactive#input_complete(A, L, P) abort\n  let prefix = matchstr(a:A, '\\%(.* \\|^\\)\\%(#\\=[\\[{('']\\)*')\n  let keyword = a:A[strlen(prefix) : -1]\n  return sort(map(timl#interactive#omnicomplete(0, keyword), 'prefix . v:val.word'))\nendfunction\n\nfunction! timl#interactive#repl(...) abort\n  if a:0\n    let ns = g:timl#core._STAR_ns_STAR_\n    try\n      let g:timl#core._STAR_ns_STAR_ = timl#namespace#create(timl#symbol#intern(a:1))\n      call timl#loader#require(timl#symbol#intern('timl.repl'))\n      call timl#namespace#refer(timl#symbol#intern('timl.repl'))\n      return timl#interactive#repl()\n    finally\n      let g:timl#core._STAR_ns_STAR_ = ns\n    endtry\n  endif\n\n  let cmpl = 'customlist,timl#interactive#input_complete'\n  let more = &more\n  try\n    set nomore\n    call timl#loader#require(timl#symbol#intern('timl.repl'))\n    if timl#namespace#name(g:timl#core._STAR_ns_STAR_).str ==# 'user'\n      call timl#namespace#refer(timl#symbol#intern('timl.repl'))\n    endif\n    let input = input(timl#namespace#name(g:timl#core._STAR_ns_STAR_).str.'=> ', '', cmpl)\n    if input =~# '^:q\\%[uit]'\n      return ''\n    elseif input =~# '^:'\n      return input\n    endif\n    let _ = {}\n    while !empty(input)\n      echo \"\\n\"\n      try\n        while 1\n          try\n            let read = timl#reader#read_string_all(input)\n            break\n          catch /^timl#reader: unexpected EOF/\n            let space = repeat(' ', len(timl#namespace#name(g:timl#core._STAR_ns_STAR_).str)-2)\n            let input .= \"\\n\" . input(space.'#_=> ', '', cmpl)\n            echo \"\\n\"\n          endtry\n        endwhile\n        let _.val = timl#loader#eval(timl#cons#create(timl#symbol#intern('do'), read))\n        call extend(g:, {\n              \\ 'timl#core#_STAR_3': g:timl#core._STAR_2,\n              \\ 'timl#core#_STAR_2': g:timl#core._STAR_1,\n              \\ 'timl#core#_STAR_1': _.val})\n        echo timl#printer#string(_.val)\n      catch /^timl#repl: exit/\n        redraw\n        return v:exception[16:-1]\n      catch /^Vim\\%((\\a\\+)\\)\\=:E168/\n        return ''\n      catch\n        unlet! g:timl#core._STAR_e\n        let g:timl#core._STAR_e = timl#exception#build(v:exception, v:throwpoint)\n        echohl ErrorMSG\n        echo v:exception\n        echohl NONE\n      endtry\n      let input = input(timl#namespace#name(g:timl#core._STAR_ns_STAR_).str.'=> ', '', cmpl)\n    endwhile\n    return input\n  finally\n    let &more = more\n  endtry\nendfunction\n\nfunction! timl#interactive#scratch() abort\n  if exists('s:scratch') && bufnr(s:scratch) !=# -1\n    execute bufnr(s:scratch) . 'sbuffer'\n    return ''\n  elseif !exists('s:scratch')\n    let s:scratch = tempname().'.tim'\n    execute 'silent' (empty(bufname('')) && !&modified ? 'edit' : 'split') s:scratch\n  else\n    execute 'split '.s:scratch\n  endif\n  call setline(1, [\n        \\ \";; This buffer is for notes you don't want to save, and for TimL evaluation.\",\n        \\ \";; Use cpp to evaluate the top level form under the cursor,\",\n        \\ \";; or cp{motion} to evaluate an arbitrary selection.\",\n        \\ \"\"])\n  setlocal bufhidden=hide filetype=timl nomodified\n  let &l:statusline = '#<Namespace %{timl#interactive#ns_for_cursor()}>%='.get(split(&statusline, '%='), 1, '')\n  autocmd BufLeave <buffer> update\n  inoremap <buffer><silent> <CR> <C-r>=timl#interactive#return()<CR>\n  return '$'\nendfunction\n\nfunction! timl#interactive#copen(error) abort\n  if !empty(a:error)\n    call setqflist(a:error.qflist)\n    copen\n    let w:quickfix_title = a:error.exception . \" @ line \" . a:error.line\n  endif\nendfunction\n"
  },
  {
    "path": "autoload/timl/io.vim",
    "content": "\" Maintainer: Tim Pope <http://tpo.pe>\n\nif exists(\"g:autoloaded_timl_io\")\n  finish\nendif\nlet g:autoloaded_timl_io = 1\n\nfunction! timl#io#echon(_) abort\n  echon join(map(copy(a:_), 'timl#string#coerce(v:val)'), ' ')\n  return g:timl#nil\nendfunction\n\nfunction! timl#io#echo(_) abort\n  echo join(map(copy(a:_), 'timl#string#coerce(v:val)'), ' ')\n  return g:timl#nil\nendfunction\n\nfunction! timl#io#echomsg(_) abort\n  echomsg join(map(copy(a:_), 'timl#string#coerce(v:val)'), ' ')\n  return g:timl#nil\nendfunction\n\nfunction! timl#io#println(_) abort\n  echon join(map(copy(a:_), 'timl#string#coerce(v:val)'), ' ').\"\\n\"\n  return g:timl#nil\nendfunction\n\nfunction! timl#io#newline() abort\n  echon \"\\n\"\n  return g:timl#nil\nendfunction\n\nfunction! timl#io#printf(fmt, ...) abort\n  echon call('printf', [timl#string#coerce(a:fmt)] + a:000).\"\\n\"\n  return g:timl#nil\nendfunction\n\nfunction! timl#io#pr(_) abort\n  echon join(map(copy(a:_), 'timl#printer#string(v:val)'), ' ')\n  return g:timl#nil\nendfunction\n\nfunction! timl#io#prn(_) abort\n  echon join(map(copy(a:_), 'timl#printer#string(v:val)'), ' ').\"\\n\"\n  return g:timl#nil\nendfunction\n\nfunction! timl#io#spit(filename, body) abort\n  if type(body) == type([])\n    call writefile(body, a:filename)\n  else\n    call writefile(split(body, \"\\n\"), a:filename, 'b')\nendfunction\n\nfunction! timl#io#slurp(filename) abort\n  return join(readfile(a:filename, 'b'), \"\\n\")\nendfunction\n"
  },
  {
    "path": "autoload/timl/keyword.vim",
    "content": "\" Maintainer: Tim Pope <http://tpo.pe>\n\nif exists(\"g:autoloaded_timl_keyword\")\n  finish\nendif\nlet g:autoloaded_timl_keyword = 1\n\nif !exists('s:keywords')\n  let s:keywords = {}\nendif\n\nfunction! timl#keyword#intern(str) abort\n  if !has_key(s:keywords, a:str)\n    let end = matchend(a:str, '^\\%(&\\=\\w:\\|\\$\\|&\\%($\\|form$\\|env$\\)\\@!\\|[^/]*/\\).\\@=')\n    let keyword = timl#type#bless(s:type, {\n          \\ '0': a:str,\n          \\ 'str': a:str,\n          \\ 'namespace': end == -1 ? '' : a:str[0 : end-(a:str[end-1] ==# '/' ? 2 : 1)],\n          \\ 'name': end == -1 ? a:str : a:str[end : -1]})\n    lockvar 1 keyword\n    let s:keywords[a:str] = keyword\n  endif\n  return s:keywords[a:str]\nendfunction\n\nfunction! timl#keyword#test(keyword) abort\n  return type(a:keyword) == type({}) && get(a:keyword, '__type__') is# s:type\nendfunction\n\nfunction! timl#keyword#cast(keyword) abort\n  if timl#keyword#test(a:keyword)\n    return a:keyword\n  endif\n  throw 'timl: keyword expected but received '.timl#type#string(a:keyword)\nendfunction\n\nfunction! timl#keyword#to_string(this) abort\n  return a:this.str\nendfunction\n\nfunction! timl#keyword#name(this) abort\n  return a:this.name\nendfunction\n\nfunction! timl#keyword#namespace(this) abort\n  return a:this.namespace\nendfunction\n\nfunction! timl#keyword#call(this, _) abort\n  if len(a:_) < 1 || len(a:_) > 2\n    throw 'timl: arity error'\n  endif\n  return call('timl#coll#get', [a:_[0], a:this] + a:_[1:-1])\nendfunction\n\nlet s:type = timl#type#core_create('Keyword')\n"
  },
  {
    "path": "autoload/timl/lazy_seq.vim",
    "content": "\" Maintainer: Tim Pope <http://tpo.pe>\n\nif exists(\"g:autoloaded_timl_lazy_seq\")\n  finish\nendif\nlet g:autoloaded_timl_lazy_seq = 1\n\nlet s:placeholder = {}\nfunction! timl#lazy_seq#create(fn) abort\n  return timl#type#bless(s:type, {'fn': a:fn, 'val': g:timl#nil, 'seq': s:placeholder, 'meta': g:timl#nil})\nendfunction\n\nfunction! timl#lazy_seq#with_meta(this, meta) abort\n  return timl#type#bless(s:type, {'fn': g:timl#nil, 'val': s:val(a:this), 'seq': a:this.seq, 'meta': a:meta})\nendfunction\n\nfunction! s:val(lseq) abort\n  if a:lseq.fn isnot# g:timl#nil\n    let a:lseq.val = timl#call(a:lseq.fn, [])\n    let a:lseq.fn = g:timl#nil\n  endif\n  return a:lseq.val\nendfunction\n\nfunction! timl#lazy_seq#seq(lseq) abort\n  if a:lseq.seq is# s:placeholder\n    let _ = {'seq': a:lseq}\n    let i = 0\n    while timl#type#string(_.seq) ==# s:type.str\n      let i += 1\n      let _.seq = s:val(_.seq)\n    endwhile\n    let a:lseq.seq = timl#invoke(g:timl#core.seq, _.seq)\n  endif\n  return a:lseq.seq\nendfunction\n\nfunction! timl#lazy_seq#car(lseq) abort\n  return timl#coll#first(timl#lazy_seq#seq(a:lseq))\nendfunction\n\nfunction! timl#lazy_seq#cdr(lseq) abort\n  return timl#coll#rest(timl#lazy_seq#seq(a:lseq))\nendfunction\n\nfunction! timl#lazy_seq#realized(lseq) abort\n  return a:lseq.fn is# g:timl#nil ? g:timl#true : g:timl#false\nendfunction\n\nlet s:type = timl#type#core_define('LazySeq', ['fn', 'val', 'seq', 'meta'], {\n      \\ 'get-meta': 'timl#meta#from_attribute',\n      \\ 'with-meta': 'timl#lazy_seq#with_meta',\n      \\ 'seq': 'timl#lazy_seq#seq',\n      \\ 'car': 'timl#lazy_seq#car',\n      \\ 'cdr': 'timl#lazy_seq#cdr',\n      \\ 'equiv': 'timl#equality#seq',\n      \\ 'realized?': 'timl#lazy_seq#realized',\n      \\ 'conj': 'timl#cons#conj',\n      \\ 'empty': 'timl#list#empty'})\n"
  },
  {
    "path": "autoload/timl/list.vim",
    "content": "\" Maintainer: Tim Pope <http://tpo.pe>\n\nif exists(\"g:autoloaded_timl_list\")\n  finish\nendif\nlet g:autoloaded_timl_list = 1\n\nlet s:cons_type = timl#type#core_create('Cons', ['car', 'cdr', 'meta'])\n\nfunction! timl#list#create(array, ...) abort\n  if a:0 && empty(a:array)\n    return timl#type#bless(s:empty_type, {'meta': a:1})\n  endif\n  let _ = {'cdr': s:empty}\n  for i in range(len(a:array)-1, 0, -1)\n    let _.cdr = timl#cons#create(a:array[i], _.cdr)\n  endfor\n  if a:0\n    let _.cdr.meta = a:1\n  endif\n  return _.cdr\nendfunction\n\nfunction! timl#list#with_meta(this, meta) abort\n  if a:this.meta is# a:meta\n    return a:this\n  endif\n  let this = copy(a:this)\n  let this.meta = a:meta\n  lockvar 1 this\n  return this\nendfunction\n\nfunction! timl#list#empty() abort\n  return s:empty\nendfunction\n\nfunction! timl#list#emptyp(obj) abort\n  return type(a:obj) == type({}) && get(a:obj, '__type__') is# s:empty_type\nendfunction\n\nfunction! timl#list#test(obj) abort\n  return type(a:obj) == type({}) && (get(a:obj, '__type__') is# s:cons_type || get(a:obj, '__type__') is# s:empty_type)\nendfunction\n\nlet s:empty_type = timl#type#core_define('EmptyList', ['meta'], {\n      \\ 'get-meta': 'timl#meta#from_attribute',\n      \\ 'with-meta': 'timl#list#with_meta',\n      \\ 'seq': 'timl#nil#identity',\n      \\ 'equiv': 'timl#equality#seq',\n      \\ 'car': 'timl#nil#identity',\n      \\ 'cdr': 'timl#function#identity',\n      \\ 'length': 'timl#nil#length',\n      \\ 'conj': 'timl#cons#conj',\n      \\ 'empty': 'timl#function#identity'})\n\nif !exists('s:empty')\n  let s:empty = timl#type#bless(s:empty_type, {'meta': g:timl#nil})\n  lockvar 1 s:empty\nendif\n"
  },
  {
    "path": "autoload/timl/loader.vim",
    "content": "\" Maintainer: Tim Pope <http://tpo.pe/>\n\nif exists('g:autoloaded_timl_loader')\n  finish\nendif\nlet g:autoloaded_timl_loader = 1\n\nfunction! timl#loader#eval(x) abort\n  return timl#compiler#build(a:x).call()\nendfunction\n\nfunction! timl#loader#consume(port) abort\n  let _ = {'result': g:timl#nil}\n  let eof = []\n  let _.read = timl#reader#read(a:port, eof)\n  while _.read isnot# eof\n    let _.result = timl#compiler#build(_.read, get(a:port, 'filename', 'NO_SOURCE_PATH')).call()\n    let _.read = timl#reader#read(a:port, eof)\n  endwhile\n  return _.result\nendfunction\n\nlet s:dir = (has('win32') ? '$APPCACHE/Vim' :\n      \\ match(system('uname'), \"Darwin\") > -1 ? '~/Library/Vim' :\n      \\ empty($XDG_CACHE_HOME) ? '~/.cache/vim' : '$XDG_CACHE_HOME/vim').'/timl'\n\nfunction! s:cache_filename(path) abort\n  let base = expand(s:dir)\n  if !isdirectory(base)\n    call mkdir(base, 'p')\n  endif\n  let filename = tr(substitute(fnamemodify(a:path, ':~'), '^\\~.', '', ''), '\\/:', '%%%') . '.vim'\n  return base . '/' . filename\nendfunction\n\nlet s:myftime = getftime(expand('<sfile>'))\n\nif !exists('g:timl_functions')\n  let g:timl_functions = {}\nendif\n\nfunction! timl#loader#source(filename) abort\n  let path = fnamemodify(a:filename, ':p')\n  let old_ns = g:timl#core._STAR_ns_STAR_\n  let cache = s:cache_filename(path)\n  try\n    let g:timl#core._STAR_ns_STAR_ = timl#namespace#find(timl#symbol#intern('user'))\n    let ftime = getftime(cache)\n    if !exists('$TIML_EXPIRE_CACHE') && ftime > getftime(path) && ftime > s:myftime\n      try\n        execute 'source '.fnameescape(cache)\n      catch\n        let error = v:exception\n      endtry\n      if !exists('error')\n        return\n      endif\n    endif\n    let file = timl#reader#open(path)\n    let strs = [\"let s:d = {}\"]\n    let _ = {}\n    let _.read = g:timl#nil\n    let eof = []\n    while _.read isnot# eof\n      let _.read = timl#reader#read(file, eof)\n      let obj = timl#compiler#build(_.read, path)\n      call obj.call()\n      call add(strs, \"function! s:d.f() abort\\nlet locals = {}\\n\".obj.body.\"endfunction\\n\")\n      let meta = timl#compiler#location_meta(path, _.read)\n      if !empty(meta)\n        let strs[-1] .= 'let g:timl_functions[join([s:d.f])] = '.string(meta).\"\\n\"\n      endif\n      let strs[-1] .= \"call s:d.f()\\n\"\n    endwhile\n    call add(strs, 'unlet s:d')\n    call writefile(split(join(strs, \"\\n\"), \"\\n\"), cache)\n  catch /^Vim\\%((\\a\\+)\\)\\=:E168/\n  finally\n    let g:timl#core._STAR_ns_STAR_ = old_ns\n    if exists('file')\n      call timl#reader#close(file)\n    endif\n  endtry\nendfunction\n\nfunction! timl#loader#relative(path) abort\n  if !empty(findfile('autoload/'.a:path.'.vim', &rtp))\n    execute 'runtime! autoload/'.a:path.'.vim'\n    return g:timl#nil\n  endif\n  for file in findfile('autoload/'.a:path.'.tim', &rtp, -1)\n    call timl#loader#source(file)\n    return g:timl#nil\n  endfor\n  throw 'timl: could not load '.a:path\nendfunction\n\nfunction! timl#loader#all_relative(paths) abort\n  for path in timl#array#coerce(a:paths)\n    if path[0] ==# '/'\n      let path = path[1:-1]\n    else\n      let path = substitute(tr(timl#namespace#name(g:timl#core._STAR_ns_STAR_).str, '.-', '/_'), '[^/]*$', '', '') . path\n    endif\n    call timl#loader#relative(path)\n  endfor\n  return g:timl#nil\nendfunction\n\nif !exists('g:timl_requires')\n  let g:timl_requires = {}\nendif\n\nfunction! timl#loader#require(ns, ...) abort\n  let ns = timl#symbol#cast(a:ns).name\n  if !has_key(g:timl_requires, ns) || a:0 && a:1\n    call timl#loader#relative(tr(ns, '.-', '/_'))\n    let g:timl_requires[ns] = 1\n  endif\nendfunction\n\nlet s:k_reload = timl#keyword#intern('reload')\nlet s:k_as = timl#keyword#intern('as')\nlet s:k_refer = timl#keyword#intern('refer')\nlet s:k_all = timl#keyword#intern('all')\nlet s:k_only = timl#keyword#intern('only')\nfunction! timl#loader#require_all(_) abort\n  let _ = {}\n  let reload = 0\n  for option in filter(copy(a:_), 'timl#keyword#test(v:val)')\n    if option is# s:k_reload\n      let reload = 1\n    else\n      throw 'timl#loader: unsupported require option :'.option[0]\n    endif\n  endfor\n  for _.spec in a:_\n    if timl#symbol#test(_.spec)\n      call timl#loader#require(_.spec, reload)\n    elseif timl#vector#test(_.spec)\n      let _.lib = timl#coll#first(_.spec)\n      call timl#loader#require(_.lib, reload)\n      if timl#coll#fnext(_.spec) is# s:k_as\n        call timl#namespace#alias(timl#coll#first(timl#coll#nnext(_.spec)), _.lib)\n      elseif timl#coll#fnext(_.spec) is# s:k_refer\n        let _.qualifier = timl#coll#first(timl#coll#nnext(_.spec))\n        if _.qualifier is# s:k_all\n          call timl#namespace#refer(_.lib)\n        else\n          call timl#namespace#refer(_.lib, s:k_only, _.qualifier)\n        endif\n      endif\n    elseif !timl#keyword#test(_.spec)\n      throw 'timl#loader: invalid loading spec type '.timl#type#string(_.spec)\n    endif\n  endfor\n  return g:timl#nil\nendfunction\n\nfunction! timl#loader#use_all(_) abort\n  let _ = {}\n  for _.spec in a:_\n    call timl#loader#require(_.spec)\n    return timl#namespace#refer(_.spec)\n  endfor\nendfunction\n\nfunction! timl#loader#init() abort\nendfunction\n\nif !exists('g:autoloaded_timl_bootstrap')\n  runtime! autoload/timl/bootstrap.vim\nendif\n\nlet s:core = timl#namespace#create(timl#symbol#intern('timl.core'))\nlet s:user = timl#namespace#create(timl#symbol#intern('user'))\ncall timl#namespace#intern(s:core, timl#symbol#intern('*ns*'), s:user)\nlet s:user.__mappings__['in-ns'] = s:core.__mappings__['in-ns']\ncall timl#loader#require(timl#symbol#intern('timl.core'))\ncall timl#namespace#refer(timl#symbol#intern('timl.core'))\n\n\" vim:set et sw=2:\n"
  },
  {
    "path": "autoload/timl/map.vim",
    "content": "\" Maintainer: Tim Pope <http://tpo.pe>\n\nif exists(\"g:autoloaded_timl_map\")\n  finish\nendif\nlet g:autoloaded_timl_map = 1\n\nfunction! timl#map#test(coll) abort\n  return timl#type#canp(a:coll, g:timl#core.dissoc)\nendfunction\n\nlet s:type = timl#type#core_create('HashMap')\nfunction! timl#map#create(_) abort\n  let keyvals = len(a:_) == 1 ? a:_[0] : a:_\n  let map = s:empty\n  for i in range(0, len(keyvals)-1, 16)\n    let map = call('timl#map#assoc', [map] + keyvals[i : i+15])\n  endfor\n  lockvar 1 map\n  return map\nendfunction\n\nfunction! timl#map#zip(keys, vals) abort\n  let _ = {}\n  let args = []\n  let [_.keys, _.vals] = [timl#coll#seq(a:keys), timl#coll#seq(a:vals)]\n  while _.keys isnot# g:timl#nil && _.vals isnot# g:timl#nil\n    call extend(args, [timl#coll#first(_.keys), timl#coll#first(_.vals)])\n    let [_.keys, _.vals] = [timl#coll#next(_.keys), timl#coll#next(_.vals)]\n  endwhile\n  return timl#map#create(args)\nendfunction\n\nfunction! timl#map#soft_coerce(coll) abort\n  if timl#coll#sequentialp(a:coll)\n    return timl#map#create(timl#array#coerce(a:coll))\n  else\n    return a:coll\n  endif\nendfunction\n\nfunction! timl#map#to_array(this) abort\n  return map(filter(items(a:this), 'v:val[0][0:1] !=# \"__\"'), '[timl#keyword#intern(v:val[0]), v:val[1]]') + timl#hash#items(a:this.__root)\nendfunction\n\nfunction! timl#map#length(this) abort\n  return a:this.__length\nendfunction\n\nfunction! timl#map#equal(this, that) abort\n  if a:this is# a:that\n    return g:timl#true\n  elseif !timl#map#test(a:that)\n    return g:timl#false\n  endif\n  if timl#coll#count(a:this) !=# timl#coll#count(a:that)\n    return g:timl#false\n  endif\n  let _ = {'seq': timl#coll#seq(a:this)}\n  while _.seq isnot# g:timl#nil\n    let _.other = timl#coll#get(a:that, timl#coll#ffirst(_.seq), _)\n    if _.other is# _ || !timl#equality#test(timl#coll#first(timl#coll#nfirst(_.seq)), _.other)\n      return g:timl#false\n    endif\n    let _.seq = timl#coll#next(_.seq)\n  endwhile\n  return g:timl#true\nendfunction\n\nfunction! timl#map#seq(this) abort\n  let items = timl#map#to_array(a:this)\n  return empty(items) ? g:timl#nil : timl#array_seq#create(items)\nendfunction\n\nfunction! timl#map#lookup(this, key, ...) abort\n  if timl#keyword#test(a:key) && a:key.str !~# '^__'\n    return get(a:this, a:key.str, a:0 ? a:1 : g:timl#nil)\n  else\n    return get(timl#hash#find(a:this.__root, a:key), 1, a:0 ? a:1 : g:timl#nil)\n  endif\nendfunction\n\nif !exists('s:empty')\n  let s:empty = timl#type#bless(s:type, {'__root': {}, '__length': 0})\n  lockvar s:empty\nendif\nfunction! timl#map#empty(this) abort\n  return s:empty\nendfunction\n\nfunction! timl#map#conj(this, ...) abort\n  let _ = {}\n  let this = a:this\n  for _.e in a:000\n    let this = timl#map#assoc(this, timl#coll#first(_.e), timl#coll#fnext(_.e))\n  endfor\n  return this\nendfunction\n\nfunction! timl#map#assoc(this, ...) abort\n  let this = copy(a:this)\n  for i in range(0, len(a:000)-2, 2)\n    if timl#keyword#test(a:000[i]) && a:000[i].str !~# '^__'\n      if !has_key(this, a:000[i].str)\n        let this.__length += 1\n      endif\n      let this[a:000[i].str] = a:000[i+1]\n    else\n      let [this.__root, c] = timl#hash#assoc(this.__root, a:000[i], a:000[i+1])\n      let this.__length += c\n    endif\n  endfor\n  lockvar 1 this\n  return this\nendfunction\n\nfunction! timl#map#dissoc(this, ...) abort\n  let _ = {}\n  let this = copy(a:this)\n  for _.x in a:000\n    if timl#keyword#test(_.x) && _.x.str !~# '^__'\n      if has_key(this, _.x.str)\n        call remove(this, _.x.str)\n        let this.__length -= 1\n      endif\n    else\n      let [this.__root, c] = timl#hash#dissoc(this.__root, _.x)\n      let this.__length -= c\n    endif\n  endfor\n  lockvar 1 this\n  return this\nendfunction\n\nfunction! timl#map#call(this, _) abort\n  return call('timl#map#lookup', [a:this] + a:_)\nendfunction\n"
  },
  {
    "path": "autoload/timl/meta.vim",
    "content": "\" Maintainer: Tim Pope <http://tpo.pe/>\n\nif exists('g:autoloaded_timl_meta')\n  finish\nendif\nlet g:autoloaded_timl_meta = 1\n\nfunction! timl#meta#get(obj) abort\n  if !timl#type#canp(a:obj, g:timl#core.get_meta)\n    return g:timl#nil\n  endif\n  return timl#invoke(g:timl#core.get_meta, a:obj)\nendfunction\n\nfunction! timl#meta#with(obj, meta) abort\n  return timl#invoke(g:timl#core.with_meta, a:obj, a:meta)\nendfunction\n\nfunction! timl#meta#vary(obj, fn, ...) abort\n  return timl#meta#with(a:obj, timl#call(a:fn, [timl#meta#get(a:obj)] + a:000))\nendfunction\n\nfunction! timl#meta#alter(obj, fn, ...) abort\n  return timl#call(g:timl#core.reset_meta_BANG_, [a:obj, timl#call(a:fn, [timl#meta#get(a:obj)] + a:000)])\nendfunction\n\nfunction! timl#meta#from_attribute(obj) abort\n  return get(a:obj, 'meta', g:timl#nil)\nendfunction\n\nfunction! timl#meta#copy_assign_lock(obj, meta) abort\n  if a:obj.meta isnot# a:meta\n    let obj = copy(a:obj)\n    let obj.meta = a:meta\n    lockvar 1 obj\n    return obj\n  endif\n  return a:obj\nendfunction\n\nfunction! timl#meta#copy_assign(obj, meta) abort\n  if a:obj.meta isnot# a:meta\n    let obj = copy(a:obj)\n    let obj.meta = a:meta\n    return obj\n  endif\n  return a:obj\nendfunction\n"
  },
  {
    "path": "autoload/timl/namespace.vim",
    "content": "\" Maintainer: Tim Pope <http://tpo.pe>\n\nif exists(\"g:autoloaded_timl_namespace\")\n  finish\nendif\nlet g:autoloaded_timl_namespace = 1\n\nif !exists('g:timl#namespaces')\n  let g:timl#namespaces = {}\nendif\n\nfunction! timl#namespace#munge(str) abort\n  return tr(a:str, '-.', '_#')\nendfunction\n\nfunction! timl#namespace#create(name) abort\n  let name = timl#symbol#cast(a:name)\n  if !has_key(g:timl#namespaces, name[0])\n    let ns = timl#type#bless(s:type, {'__name__': name, '__aliases__': {}, '__mappings__': {}})\n    let g:timl#namespaces[name[0]] = ns\n    let g:{timl#namespace#munge(name[0])} = ns\n  endif\n  return g:timl#namespaces[name[0]]\nendfunction\n\nfunction! timl#namespace#name(ns) abort\n  return timl#namespace#the(a:ns).__name__\nendfunction\n\nfunction! timl#namespace#map(ns) abort\n  return timl#namespace#the(a:ns).__mappings__\nendfunction\n\nfunction! timl#namespace#aliases(ns) abort\n  return timl#namespace#the(a:ns).__aliases__\nendfunction\n\nfunction! timl#namespace#select(name) abort\n  let g:timl#core._STAR_ns_STAR_ = timl#namespace#create(a:name)\n  return g:timl#core._STAR_ns_STAR_\nendfunction\n\nfunction! timl#namespace#refer(name, ...) abort\n  let me = g:timl#core._STAR_ns_STAR_\n  let sym = timl#symbol#cast(a:name)\n  let ns = timl#namespace#find(sym)\n  let i = 0\n  let only = keys(ns.__mappings__)\n  let exclude = []\n  if !exists('s:k_only')\n    let s:k_only = timl#keyword#intern('only')\n    let s:k_exclude = timl#keyword#intern('exclude')\n  endif\n  while i < a:0\n    if a:000[i] is# s:k_only\n      let only = map(copy(timl#array#coerce(get(a:000, i+1, []))), 'timl#symbol#cast(v:val).name')\n      let i += 2\n    elseif a:000[i] is# s:k_exclude\n      let exclude = map(copy(timl#array#coerce(get(a:000, i+1, []))), 'timl#symbol#cast(v:val).name')\n      let i += 2\n    elseif timl#keyword#test(a:000[i])\n      throw 'timl#namespace: invalid option :'.a:000[i][0]\n    else\n      throw 'timl#namespace: invalid option type '.timl#type#string(a:000[i][0])\n    endif\n  endwhile\n  let _ = {}\n  for name in only\n    if !has_key(ns.__mappings__, name)\n      throw 'timl#namespace: no such mapping '.name\n    endif\n    let var = ns.__mappings__[name]\n    let _.private = get(var.meta, 'private', g:timl#nil)\n    if var.ns is# ns && (_.private is# g:timl#false || _.private is# g:timl#nil) && index(exclude, name) == -1\n      let me.__mappings__[name] = var\n    endif\n  endfor\n  return g:timl#nil\nendfunction\n\nfunction! timl#namespace#alias(alias, name) abort\n  let me = g:timl#core._STAR_ns_STAR_\n  let me.__aliases__[timl#symbol#cast(a:alias).name] = a:name\n  return g:timl#nil\nendfunction\n\nfunction! timl#namespace#find(name) abort\n  return get(g:timl#namespaces, type(a:name) == type('') ? a:name : a:name.name, g:timl#nil)\nendfunction\n\nfunction! timl#namespace#the(name) abort\n  if timl#type#string(a:name) ==# s:type.str\n    return a:name\n  endif\n  let name = type(a:name) == type('') ? a:name : a:name.name\n  if has_key(g:timl#namespaces, name)\n    return g:timl#namespaces[name]\n  endif\n  throw 'timl: no such namespace '.name\nendfunction\n\nfunction! timl#namespace#maybe_resolve(ns, sym, ...) abort\n  let ns = timl#namespace#the(a:ns)\n  let sym = timl#symbol#cast(a:sym)\n  if has_key(ns.__mappings__, sym.str)\n    return ns.__mappings__[sym.str]\n  endif\n  if !empty(sym.namespace)\n    if has_key(ns.__aliases__, sym.namespace)\n      let aliasns = timl#namespace#the(ns.__aliases__[sym.namespace])\n      if has_key(aliasns.__mappings__, sym.name)\n        return aliasns.__mappings__[sym.name]\n      endif\n    endif\n    if has_key(g:timl#namespaces, sym.namespace) && has_key(g:timl#namespaces[sym.namespace].__mappings__, sym.name)\n      return g:timl#namespaces[sym.namespace].__mappings__[sym.name]\n    endif\n  endif\n  return a:0 ? a:1 : g:timl#nil\nendfunction\n\nfunction! timl#namespace#all() abort\n  return timl#coll#seq(values(g:timl#namespaces))\nendfunction\n\nfunction! timl#namespace#intern(ns, name, ...) abort\n  let ns = timl#namespace#the(a:ns)\n  let nsname = timl#namespace#name(ns).str\n  let str = nsname.'/'.timl#symbol#cast(a:name).str\n  let nsglobal = timl#namespace#munge(nsname)\n  let key = timl#var#munge(a:name.str)\n  let meta = copy(a:name.meta is# g:timl#nil ? timl#map#create([]) : a:name.meta)\n  let meta.name = a:name\n  let meta.ns = ns\n  lockvar 1 meta\n  if has_key(ns.__mappings__, a:name[0]) && ns.__mappings__[a:name[0]].ns is# ns\n    let var = ns.__mappings__[a:name[0]]\n    let var.meta = meta\n  else\n    let var = timl#type#bless(s:var_type, {'ns': ns, 'str': str, 'funcname': nsglobal.'#'.key, 'location': 'g:'.nsglobal.'.'.key, 'meta': meta})\n  endif\n  if a:0\n    let ns[key] = a:1\n  elseif !has_key(ns, key)\n    let ns[key] = g:timl#nil\n  endif\n  let ns.__mappings__[a:name[0]] = var\n  return var\nendfunction\n\nlet s:type = timl#type#core_create('Namespace')\nlet s:var_type = timl#type#core_create('Var')\n\ncall timl#type#core_define('Type', g:timl#nil, {})\ncall timl#type#core_define('Namespace', g:timl#nil, {})\ncall timl#type#core_define('Var', g:timl#nil, {\n      \\ 'hash': 'timl#hash#str_attribute',\n      \\ 'get-meta': 'timl#meta#from_attribute',\n      \\ 'reset-meta!': 'timl#var#reset_meta',\n      \\ 'call': 'timl#var#call',\n      \\ 'funcref': 'timl#var#funcref',\n      \\ 'deref': 'timl#var#get'})\ncall timl#type#core_define('Symbol', g:timl#nil, {\n      \\ 'get-meta': 'timl#meta#from_attribute',\n      \\ 'with-meta': 'timl#meta#copy_assign_lock',\n      \\ 'equiv': 'timl#symbol#equal',\n      \\ 'hash': 'timl#hash#str_attribute',\n      \\ 'to-string': 'timl#keyword#to_string',\n      \\ 'name': 'timl#keyword#name',\n      \\ 'namespace': 'timl#keyword#namespace',\n      \\ 'call': 'timl#keyword#call'})\ncall timl#type#core_define('Keyword', g:timl#nil, {\n      \\ 'to-string': 'timl#keyword#to_string',\n      \\ 'hash': 'timl#hash#str_attribute',\n      \\ 'name': 'timl#keyword#name',\n      \\ 'namespace': 'timl#keyword#namespace',\n      \\ 'call': 'timl#keyword#call'})\n"
  },
  {
    "path": "autoload/timl/nil.vim",
    "content": "\" Maintainer: Tim Pope <http://tpo.pe>\n\nif exists(\"g:autoloaded_timl_nil\")\n  finish\nendif\nlet g:autoloaded_timl_nil = 1\n\nfunction! s:freeze(...) abort\n  return a:000\nendfunction\n\nif !exists('g:timl#nil')\n  let g:timl#nil = s:freeze()\n  lockvar 1 g:timl#nil\nendif\n\nfunction! timl#nil#identity(...) abort\n  return g:timl#nil\nendfunction\n\nfunction! timl#nil#length(...) abort\n  return 0\nendfunction\n\nfunction! timl#nil#to_string(...) abort\n  return ''\nendfunction\n\nfunction! timl#nil#test(this) abort\n  return a:this is# g:timl#nil\nendfunction\n\nfunction! timl#nil#lookup(this, key, default) abort\n  return a:default\nendfunction\n\nfunction! timl#nil#cons(this, ...) abort\n  return call('timl#cons#conj', [timl#list#empty()] + a:000)\nendfunction\n\nfunction! timl#nil#assoc(this, ...) abort\n  return timl#map#create(a:000)\nendfunction\n\ncall timl#type#core_define('Nil', g:timl#nil, {\n      \\ 'seq': 'timl#nil#identity',\n      \\ 'to-string': 'timl#nil#to_string',\n      \\ 'empty': 'timl#nil#identity',\n      \\ 'car': 'timl#nil#identity',\n      \\ 'cdr': 'timl#list#empty',\n      \\ 'conj': 'timl#nil#cons',\n      \\ 'assoc': 'timl#nil#assoc',\n      \\ 'length': 'timl#nil#length',\n      \\ 'hash': 'timl#nil#length',\n      \\ 'lookup': 'timl#nil#lookup'})\n"
  },
  {
    "path": "autoload/timl/number.vim",
    "content": "\" Maintainer: Tim Pope <http://tpo.pe>\n\nif exists(\"g:autoloaded_timl_number\")\n  finish\nendif\nlet g:autoloaded_timl_number = 1\n\nlet s:int = type(0)\nlet s:float = 5\n\nfunction! timl#number#coerce(obj) abort\n  if type(a:obj) == s:int || type(a:obj) == s:float\n    return a:obj\n  endif\n  throw \"timl: not a number\"\nendfunction\n\nfunction! timl#number#int(obj) abort\n  if type(a:obj) == s:int\n    return a:obj\n  elseif type(a:obj) == s:float\n    return float2nr(a:obj)\n  endif\n  throw \"timl: not a number\"\nendfunction\n\nfunction! timl#number#float(obj) abort\n  if type(a:obj) == s:tfloat\n    return a:obj\n  elseif type(a:obj) == s:tint\n    return 0.0 + a:obj\n  endif\n  throw \"timl: not a float\"\nendfunction\n\nfunction! timl#number#test(obj) abort\n  return type(a:obj) == s:int || type(a:obj) == s:float\nendfunction\n\nfunction! timl#number#integerp(obj) abort\n  return type(a:obj) == s:int\nendfunction\n\nfunction! timl#number#floatp(obj) abort\n  return type(a:obj) == s:float\nendfunction\n\nfunction! timl#number#sum(_) abort\n  let acc = 0\n  for elem in a:_\n    let acc += elem\n  endfor\n  return acc\nendfunction\n\nfunction! timl#number#product(_) abort\n  let acc = 1\n  for elem in a:_\n    let acc = acc * elem\n  endfor\n  return acc\nendfunction\n\nfunction! timl#number#minus(_) abort\n  if len(a:_) ==# 1\n    return 0 - a:_[0]\n  elseif len(a:_)\n    let acc = timl#number#coerce(a:_[0])\n    for elem in a:_[1:-1]\n      let acc -= elem\n    endfor\n    return acc\n  endif\n  throw 'timl: arity error'\nendfunction\n\nfunction! timl#number#solidus(_) abort\n  if len(a:_) ==# 1\n    return 1 / a:_[0]\n  elseif len(a:_)\n    let acc = timl#number#coerce(a:_[0])\n    for elem in a:_[1:-1]\n      let acc = acc / elem\n    endfor\n    return acc\n  endif\n  throw 'timl: arity error'\nendfunction\n\nfunction! timl#number#gt(_) abort\n  if empty(a:_)\n    throw 'timl: arity error'\n  endif\n  let x = timl#number#coerce(a:_[0])\n  for y in map(a:_[1:-1], 'timl#number#coerce(v:val)')\n    if !(x > y)\n      return g:timl#false\n    endif\n    let x = y\n  endfor\n  return g:timl#true\nendfunction\n\nfunction! timl#number#lt(_) abort\n  if empty(a:_)\n    throw 'timl: arity error'\n  endif\n  let x = timl#number#coerce(a:_[0])\n  for y in map(a:_[1:-1], 'timl#number#coerce(v:val)')\n    if !(x < y)\n      return g:timl#false\n    endif\n    let x = y\n  endfor\n  return g:timl#true\nendfunction\n\nfunction! timl#number#gteq(_) abort\n  if empty(a:_)\n    throw 'timl: arity error'\n  endif\n  let x = timl#number#coerce(a:_[0])\n  for y in map(a:_[1:-1], 'timl#number#coerce(v:val)')\n    if !(x >= y)\n      return g:timl#false\n    endif\n    let x = y\n  endfor\n  return g:timl#true\nendfunction\n\nfunction! timl#number#lteq(_) abort\n  if empty(a:_)\n    throw 'timl: arity error'\n  endif\n  let x = timl#number#coerce(a:_[0])\n  for y in map(a:_[1:-1], 'timl#number#coerce(v:val)')\n    if !(x <= y)\n      return g:timl#false\n    endif\n    let x = y\n  endfor\n  return g:timl#true\nendfunction\n\nfunction! timl#number#equiv(_) abort\n  if empty(a:_)\n    throw 'timl: arity error'\n  endif\n  let x = timl#number#coerce(a:_[0])\n  for y in map(a:_[1:-1], 'timl#number#coerce(v:val)')\n    if x != y\n      return g:timl#false\n    endif\n  endfor\n  return g:timl#true\nendfunction\n\nfunction! timl#number#inc(x) abort\n  return timl#number#coerce(a:x) + 1\nendfunction\n\nfunction! timl#number#dec(x) abort\n  return timl#number#coerce(a:x) - 1\nendfunction\n\nfunction! timl#number#rem(x, y) abort\n  return timl#number#coerce(a:x) % a:y\nendfunction\n\nfunction! timl#number#quot(x, y) abort\n  return type(a:x) == 5 || type(a:y) == 5 ? trunc(a:x/a:y) : timl#number#coerce(a:x)/a:y\nendfunction\n\nfunction! timl#number#mod(x, y) abort\n  if (timl#number#coerce(a:x) < 0 && timl#number#coerce(a:y) > 0 || timl#number#coerce(a:x) > 0 && timl#number#coerce(a:y) < 0) && a:x % a:y != 0\n    return (a:x % a:y) + a:y\n  else\n    return a:x % a:y\n  endif\nendfunction\n\nfunction! timl#number#bit_not(x) abort\n  return invert(a:x)\nendfunction\n\nfunction! timl#number#bit_or(_) abort\n  let acc = 0\n  for i in map(copy(a:_), 'timl#number#int(v:val)')\n    let acc = or(acc, i)\n  endfor\n  return acc\nendfunction\n\nfunction! timl#number#bit_xor(_) abort\n  let acc = 0\n  for i in map(copy(a:_), 'timl#number#int(v:val)')\n    let acc = xor(acc, i)\n  endfor\n  return acc\nendfunction\n\nfunction! timl#number#bit_and(_) abort\n  let acc = -1\n  for i in map(copy(a:_), 'timl#number#int(v:val)')\n    let acc = and(acc, i)\n  endfor\n  return acc\nendfunction\n\nfunction! timl#number#bit_and_not(_) abort\n  let acc = timl#number#int(a:_[0])\n  for i in map(a:_[1:-1], 'timl#number#int(v:val)')\n    let acc = and(acc, invert(i))\n  endfor\n  return acc\nendfunction\n\nfunction! timl#number#bit_shift_left(x, n) abort\n  let x = timl#number#int(a:x)\n  for i in range(timl#number#int(a:n))\n    let x = x * 2\n  endfor\n  return x\nendfunction\n\nfunction! timl#number#bit_shift_right(x, n) abort\n  let x = timl#number#int(a:x)\n  for i in range(timl#number#int(a:n))\n    let x = x / 2\n  endfor\n  return x\nendfunction\n\nfunction! timl#number#bit_flip(x, n) abort\n  return xor(a:x, g:timl#core.bit_shift_left.call(1, a:n))\nendfunction\n\nfunction! timl#number#bit_set(x, n) abort\n  return or(a:x, g:timl#core.bit_shift_left.call(1, a:n))\nendfunction\n\nfunction! timl#number#bit_clear(x, n) abort\n  return and(a:x, invert(g:timl#core.bit_shift_left.call(1, a:n)))\nendfunction\n\nfunction! timl#number#bit_test(x, n) abort\n  return and(a:x, g:timl#core.bit_shift_left.call(1, a:n))\nendfunction\n\nfunction! timl#number#not_negative(x) abort\n  return timl#number#coerce(a:x) < 0 ? g:timl#nil : a:x\nendfunction\n\nfunction! timl#number#zerop(x) abort\n  return timl#number#coerce(a:x) == 0\nendfunction\n\nfunction! timl#number#nonzerop(x) abort\n  return timl#number#coerce(a:x) != 0\nendfunction\n\nfunction! timl#number#posp(x) abort\n  return timl#number#coerce(a:x) > 0\nendfunction\n\nfunction! timl#number#negp(x) abort\n  return timl#number#coerce(a:x) < 0\nendfunction\n\nfunction! timl#number#oddp(x) abort\n  return timl#number#coerce(a:x) % 2\nendfunction\n\nfunction! timl#number#evenp(x) abort\n  return timl#number#coerce(a:x) % 2 == 0\nendfunction\n"
  },
  {
    "path": "autoload/timl/plugin_helper.tim",
    "content": "(ns timl.plugin-helper)\n\n(defmacro include-guard [var]\n  (let [string (munge (str var))]\n   `(if (exists? ~string)\n     (execute \"finish\")\n     (set! ~var 1))))\n\n(defn build-option-string [args]\n  (subs\n    (loop [s \"\"\n           x (first args)\n           more (rest args)]\n      (if (nil? x)\n        s\n        (recur\n          (if (symbol? x) (str s \" \" x) (str s (#*fnameescape (str x))))\n          (first more) (rest more))\n        )) 1))\n\n(defn extract-option-names [args]\n  (map (fn [x] (#*matchstr (str x) #\"%(inv|no)?\\zs\\w+\")) (filter symbol? args)))\n\n(defn extract-option-restore [args]\n  (if-let [options (extract-option-names args)]\n    (str \"setlocal \" (join \"< \" (map str options)) \"<\")))\n\n(defmacro setlocal [& opts]\n  `(execute (str \"setlocal \" ~(build-option-string opts))))\n\n(defmacro setglobal [& opts]\n  `(execute (str \"setlocal \" ~(build-option-string opts))))\n"
  },
  {
    "path": "autoload/timl/printer.vim",
    "content": "\" Maintainer:   Tim Pope <http://tpo.pe/>\n\nif exists(\"g:autoloaded_timl_printer\")\n  finish\nendif\nlet g:autoloaded_timl_printer = 1\n\nlet s:escapes = {\n      \\ \"\\n\": '\\n',\n      \\ \"\\r\": '\\r',\n      \\ \"\\t\": '\\t',\n      \\ \"\\\"\": '\\\"',\n      \\ \"\\\\\": '\\\\'}\n\nfunction! timl#printer#string(x) abort\n  \" TODO: guard against recursion\n  let type = timl#type#string(a:x)\n  if type ==# 'timl.lang/Symbol'\n    return a:x[0]\n\n  elseif type ==# 'timl.lang/Keyword'\n    return ':'.a:x[0]\n\n  elseif type ==# 'timl.lang/Nil'\n    return 'nil'\n\n  elseif type ==# 'timl.lang/Boolean'\n    return get(a:x, 'val') ? 'true' : 'false'\n\n  elseif type ==# 'timl.lang/Function'\n    return '#<'\n          \\ . get(a:x, 'ns', {'name': ['...']}).__name__[0] . '/'\n          \\ . (get(a:x, 'name', g:timl#nil) is g:timl#nil ? '...' : a:x.name.name)\n          \\ . ' #*'.join([get(a:x, '__call__', '???')]).'>'\n\n  elseif type ==# 'timl.lang/MultiFn'\n    return '#<'\n          \\ . get(a:x, 'ns', {'__name__': ['...']}).__name__[0] . '/'\n          \\ . (get(a:x, 'name', g:timl#nil) is g:timl#nil ? '...' : a:x.name.name)\n          \\ . ' multi>'\n\n  elseif type ==# 'timl.lang/Namespace'\n    return '#<Namespace '.get(a:x, '__name__', '')[0].'>'\n\n  elseif type ==# 'timl.lang/Var'\n    return \"#'\".a:x.str\n\n  elseif type ==# 'timl.lang/Exception'\n    return '#<Exception '.a:x.exception.' @ '.a:x.throwpoint.'>'\n\n  elseif type(a:x) == type('')\n    return '\"'.substitute(a:x, \"[\\n\\r\\t\\\"\\\\\\\\]\", '\\=get(s:escapes, submatch(0))', 'g').'\"'\n\n  elseif type(a:x) == type([])\n    return '#*['.join(map(a:x[:], 'timl#printer#string(v:val)'), ' ') . ']'\n\n  elseif type == 'vim/Dictionary'\n    let acc = []\n    for [k, V] in items(a:x)\n      call add(acc, timl#printer#string(k) . ' ' . timl#printer#string(V))\n      unlet! V\n    endfor\n    return '#*{' . join(acc, ' ') . '}'\n\n  elseif type == 'timl.lang/Type'\n    return a:x.str\n\n  elseif timl#vector#test(a:x)\n    return '['.join(map(timl#array#coerce(a:x), 'timl#printer#string(v:val)'), ' ') . ']'\n\n  elseif timl#map#test(a:x)\n    let acc = []\n    let _ = {'seq': timl#coll#seq(a:x)}\n    while _.seq isnot# g:timl#nil\n      call add(acc, timl#printer#string(timl#coll#first(_.seq))[3:-2])\n      let _.seq = timl#coll#next(_.seq)\n    endwhile\n    return '{' . join(acc, ', ') . '}'\n\n  elseif timl#set#test(a:x)\n    let acc = []\n    let _ = {'seq': timl#coll#seq(a:x)}\n    while _.seq isnot# g:timl#nil\n      call add(acc, timl#printer#string(timl#coll#first(_.seq)))\n      let _.seq = timl#coll#next(_.seq)\n    endwhile\n    return '#{' . join(acc, ' ') . '}'\n\n  elseif timl#coll#seqp(a:x)\n    let _ = {'seq': timl#coll#seq(a:x)}\n    let output = []\n    while _.seq isnot# g:timl#nil\n      call add(output, timl#printer#string(timl#coll#first(_.seq)))\n      let _.seq = timl#coll#next(_.seq)\n    endwhile\n    return '('.join(output, ' ').')'\n\n  elseif type(a:x) == type(function('tr'))\n    return '#*'.substitute(join([a:x]), '[{}]', '', 'g')\n\n  elseif type ==# 'timl.lang/Instant'\n    return '#inst \"'.timl#inst#to_string(a:x).'\"'\n\n  elseif type ==# 'vim/Float' && string(a:x) =~# 'n'\n    if string(a:x) ==# 'inf'\n      return 'Infinity'\n    elseif string(a:x) ==# '-inf'\n      return '-Infinity'\n    else\n      return 'NaN'\n    endif\n\n  elseif type =~# '^vim/'\n    return string(a:x)\n\n  else\n    let acc = []\n    for [k, V] in items(a:x)\n      if k !~# '^__'\n        call add(acc, k . '=' . timl#printer#string(V))\n      endif\n      unlet! V\n    endfor\n    return '#<'.type.' ' . join(acc, ', ') . '>'\n\n  endif\nendfunction\n\n\" Section: Tests {{{1\n\nif !$TIML_TEST\n  finish\nendif\n\ncommand! -nargs=1 TimLPAssert\n      \\ try |\n      \\ if !eval(<q-args>) |\n      \\ echomsg \"Failed: \".<q-args> |\n      \\   endif |\n      \\ catch /.*/ |\n      \\  echomsg \"Error:  \".<q-args>.\" (\".v:exception.\")\" |\n      \\ endtry\n\nTimLPAssert timl#printer#string('foo') ==# '\"foo\"'\nTimLPAssert timl#printer#string(timl#symbol('foo')) ==# 'foo'\nTimLPAssert timl#printer#string(timl#vector#claim([1,2])) ==# '[1 2]'\nTimLPAssert timl#printer#string({\"a\": 1, \"b\": 2}) ==# '#*{\"a\" 1 \"b\" 2}'\n\ndelcommand TimLPAssert\n\n\" }}}1\n\n\" vim:set et sw=2:\n"
  },
  {
    "path": "autoload/timl/reader.vim",
    "content": "\" Maintainer:   Tim Pope <http://tpo.pe/>\n\nif exists(\"g:autoloaded_timl_reader\")\n  finish\nendif\nlet g:autoloaded_timl_reader = 1\n\nlet s:iskeyword = '[[:alnum:]_=?!#$%&*+|./<>:-]'\n\nfunction! s:read_token(port) abort\n  let pat = '^\\%(#\"\\%(\\\\\\@<!\\%(\\\\\\\\\\)*\\\\\"\\|[^\"]\\)*\"\\|\"\\%(\\\\.\\|[^\"]\\)*\"\\|[[:space:],]\\+\\|\\%(;\\|#!\\)[^'.\"\\n\".']*\\|\\~@\\|#[[:punct:]]\\|'.s:iskeyword.'\\+\\|\\\\\\%(space\\|tab\\|newline\\|return\\|.\\)\\|.\\)'\n  let match = ' '\n  while match =~# '^[[:space:],]'\n    let [pos, line] = [a:port.pos, a:port.line]\n    let match = matchstr(a:port.str, pat, a:port.pos)\n    let a:port.pos += len(match)\n    let a:port.line += len(substitute(match, \"[^\\n]\", '', 'g'))\n  endwhile\n  return [match, pos, line]\nendfunction\n\nfunction! timl#reader#eofp(port) abort\n  return a:port.pos >= len(a:port.str)\nendfunction\n\nlet g:timl#reader#eof = []\n\nfunction! timl#reader#read(port, ...) abort\n  let error = 'timl#reader: unexpected EOF'\n  try\n    let val = s:read(a:port)\n    if val isnot# g:timl#reader#eof\n      return val\n    elseif a:0\n      return a:1\n    endif\n  catch /^timl.*/\n    let error = v:exception\n  endtry\n  throw error\nendfunction\n\nlet s:found = {}\nfunction! s:read_until(port, char) abort\n  let list = []\n  let _ = {}\n  let _.read = s:read(a:port, a:char)\n  while _.read isnot# s:found && _.read isnot# g:timl#reader#eof\n    call add(list, _.read)\n    let _.read = s:read(a:port, a:char)\n  endwhile\n  if _.read is# s:found\n    lockvar 1 list\n    return list\n  endif\n  throw 'timl#reader: unexpected EOF'\nendfunction\n\nlet s:constants = {\n      \\ '\\space': \" \",\n      \\ '\\tab': \"\\t\",\n      \\ '\\newline': \"\\n\",\n      \\ '\\return': \"\\r\",\n      \\ '\\formfeed': \"\\f\",\n      \\ '\\backspace': \"\\b\"}\n\nfunction! s:add_meta(data, meta) abort\n  let _ = {}\n  let _.meta = timl#meta#get(a:data)\n  if _.meta is g:timl#nil\n    let _.meta = a:meta\n  else\n    let _.meta = timl#coll#into(_.meta, a:meta)\n  endif\n  return timl#meta#with(a:data, _.meta)\nendfunction\n\nlet s:map_type = timl#type#core_create('HashMap')\nfunction! s:read(port, ...) abort\n  let port = a:port\n  let [token, pos, line] = s:read_token(a:port)\n  let wanted = a:0 ? a:1 : ''\n  if token ==# '('\n    let meta = timl#type#bless(s:map_type, {'line': line, '__length': 1, '__root': {}})\n    return timl#list#create(s:read_until(port, ')'), meta)\n  elseif token == '['\n    return timl#vector#claim(s:read_until(port, ']'))\n  elseif token == '{'\n    let list = s:read_until(port, '}')\n    if len(list) % 2 != 0\n      let error = 'timl#reader: invalid hash map literal'\n    else\n      return timl#map#create(list)\n    endif\n  elseif token == '#{'\n    return timl#set#coerce(s:read_until(port, '}'))\n  elseif has_key(s:constants, token)\n    return s:constants[token]\n  elseif token ==# 'nil'\n    return g:timl#nil\n  elseif token ==# 'false'\n    return g:timl#false\n  elseif token ==# 'true'\n    return g:timl#true\n  elseif token ==# 'Infinity' || token ==# '+Infinity'\n    return 1/(0.0)\n  elseif token ==# '-Infinity'\n    return -1/(0.0)\n  elseif token ==# 'NaN'\n    return 0/(0.0)\n  elseif token =~# '^\\d\\+e\\d\\+$'\n    return eval(substitute(token, 'e', '.0e', ''))\n  elseif token =~# '^\\.\\d'\n    return eval('0'.token)\n  elseif token =~# '^\"\\|^[+-]\\=\\d\\%(.*\\d\\)\\=$'\n    return eval(token)\n  elseif token =~# '^#\"'\n    return '\\C\\v'.substitute(token[2:-2], '\\\\\\@<!\\(\\%(\\\\\\\\\\)*\\)\\\\\"', '\\1\"', 'g')\n  elseif token[0] ==# '\\'\n    return token[1]\n  elseif token ==# \"'\"\n    return timl#list(timl#symbol('quote'), s:read_bang(port))\n  elseif token ==# '`'\n    return timl#reader#syntax_quote(s:read_bang(port), {})\n  elseif token ==# '~'\n    return timl#list(s:unquote, s:read_bang(port))\n  elseif token ==# '~@'\n    return timl#list(s:unquote_splicing, s:read_bang(port))\n  elseif token ==# \"#'\"\n    return timl#list(timl#symbol('var'), s:read_bang(port))\n  elseif token ==# '#*'\n    let next = s:read_bang(port)\n    if timl#map#test(next)\n      return timl#dictionary#create([next])\n    elseif timl#vector#test(next)\n      return timl#array#coerce(next)\n    else\n      return timl#list(timl#symbol('function'), next)\n    endif\n  elseif token[0] ==# ';' || token =~# '^#!'\n    return s:read(port, wanted)\n  elseif token ==# '#_'\n    call s:read(port)\n    return s:read(port, wanted)\n  elseif token ==# '#('\n    if has_key(port, 'argsyms')\n      throw \"timl#reader: can't nest #()\"\n    endif\n    try\n      let port.argsyms = {}\n      let list = s:read_until(port, ')')\n      let rest = has_key(port.argsyms, '%&')\n      let args = map(range(1, len(port.argsyms) - rest), 'port.argsyms[\"%\".v:val]')\n      if rest\n        call add(args, a:port.argsyms['%&'])\n      endif\n      return timl#list(timl#symbol('fn*'), args, timl#list#create(list))\n    finally\n      unlet! a:port.argsyms\n    endtry\n  elseif token =~# '^%\\d*$\\|^%&$' && has_key(port, 'argsyms')\n    let token = (token ==# '%' ? '%1' : token)\n    if !has_key(port.argsyms, token)\n      let port.argsyms[token] = timl#symbol#gen('p1__')\n    endif\n    return port.argsyms[token]\n\n  elseif token ==# '#uuid'\n    return tolower(s:read(port))\n\n  elseif token ==# '#inst'\n    return timl#inst#parse(s:read(port))\n\n  elseif token =~# '^#\\a'\n    let next = s:read(port)\n    unlockvar 1 next\n    let token = token[1:-1]\n    if token !~# '[/.]'\n      let token = 'timl.lang/'.token\n    endif\n    let munged = timl#var#munge(token)\n    if timl#map#test(next) && exists(\"g:\".substitute(munged, '.*\\zs#', '#map__GT_', ''))\n      return timl#invoke(g:{substitute(munged, '.*\\zs#', '#map__GT_', '')}, next)\n    elseif timl#vector#test(next) && exists(\"g:\".substitute(munged, '.*\\zs#', '#__GT_', ''))\n      return timl#call(g:{substitute(munged, '.*\\zs#', '#__GT_', '')}, timl#array#coerce(next))\n    else\n      throw 'timl#reader: invalid tag ' . token . ' on ' . timl#type#string(next)\n    endif\n  elseif token =~# '^::.\\+/.'\n    let alias = matchstr(token[2:-1], '.*\\ze/.')\n    let ns = get(timl#namespace#aliases(g:timl#core._STAR_ns_STAR_), alias, {})\n    if empty(ns)\n      let error = 'timl#reader: unknown ns alias '.alias.' in keyword'\n    else\n      return timl#keyword#intern(timl#namespace#the(ns).name[0].matchstr(token, '.*\\zs/.\\+'))\n    endif\n  elseif token =~# '^::.'\n    return timl#keyword#intern(timl#namespace#name(g:timl#core._STAR_ns_STAR_).str.'/'.token[2:-1])\n  elseif token =~# '^:.'\n    return timl#keyword#intern(token[1:-1])\n  elseif token =~# '^'.s:iskeyword\n    return timl#symbol(token)\n  elseif token ==# '^'\n    let _meta = s:read(port)\n    let data = s:read(port)\n    if timl#keyword#test(_meta)\n      let meta = timl#map#create([_meta, g:timl#true])\n    elseif timl#symbol#test(_meta) || type(_meta) == type('')\n      let meta = timl#map#create([timl#keyword#intern('tag'), _meta])\n    elseif timl#map#test(_meta)\n      let meta = _meta\n    else\n      throw 'timl#reader: metadata must be symbol, string, keyword, or map'\n    endif\n    if timl#type#objectp(data)\n      return s:add_meta(data, meta)\n    endif\n    return data\n    let error = 'timl#reader: cannot attach metadata to a '.timl#type#string(data)\n  elseif token ==# '@'\n    return timl#list(timl#symbol('timl.core/deref'), s:read_bang(port))\n  elseif empty(token)\n    return g:timl#reader#eof\n  elseif token ==# wanted\n    return s:found\n  else\n    let error = 'timl#reader: unexpected token '.string(token)\n  endif\n  throw error . ' on line ' . line\nendfunction\n\nfunction! s:read_bang(port) abort\n  let val = s:read(a:port)\n  if val isnot# g:timl#reader#eof\n    return val\n  endif\n  throw 'timl#reader: unexpected EOF'\nendfunction\n\nlet s:quote = timl#symbol('quote')\nlet s:unquote = timl#symbol('unquote')\nlet s:unquote_splicing = timl#symbol('unquote-splicing')\nlet s:function = timl#symbol('function')\nlet s:list = timl#symbol('timl.core/list')\nlet s:concat = timl#symbol('timl.core/concat')\nlet s:seq = timl#symbol('timl.core/seq')\nlet s:vec = timl#symbol('timl.core/vec')\nlet s:set = timl#symbol('timl.core/set')\nlet s:hash_map = timl#symbol('timl.core/hash-map')\nfunction! timl#reader#syntax_quote(form, gensyms) abort\n  if timl#symbol#test(a:form)\n    if a:form[0] =~# '^[^/]\\+#$'\n      if !has_key(a:gensyms, a:form[0])\n        let a:gensyms[a:form[0]] = timl#symbol(timl#symbol#gen(a:form[0][0:-2].'__')[0].'__auto__')\n      endif\n      let quote = s:quote\n      let x = timl#list(s:quote, a:gensyms[a:form[0]])\n      return timl#list(s:quote, a:gensyms[a:form[0]])\n    elseif !timl#compiler#specialp(a:form[0]) && a:form[0] !~# ':\\|^[&$]'\n      return timl#list(s:quote, timl#symbol(timl#namespace#maybe_resolve(\n            \\ g:timl#core._STAR_ns_STAR_,\n            \\ a:form,\n            \\ {'str': (a:form[0] =~# '/.' ? '' : timl#namespace#name(g:timl#core._STAR_ns_STAR_).str.'/').a:form[0]}).str))\n    else\n      return timl#list(s:quote, a:form)\n    endif\n  elseif timl#vector#test(a:form)\n    return timl#list(s:vec, timl#cons#create(s:concat, s:sqexpandlist(a:form, a:gensyms)))\n  elseif timl#set#test(a:form)\n    return timl#list(s:set, timl#cons#create(s:concat, s:sqexpandlist(a:form, a:gensyms)))\n  elseif timl#map#test(a:form)\n    let _ = {'seq': timl#coll#seq(a:form)}\n    let keyvals = []\n    while _.seq isnot# g:timl#nil\n      call extend(keyvals, timl#array#coerce(timl#coll#first(_.seq)))\n      let _.seq = timl#coll#next(_.seq)\n    endwhile\n    return timl#list(s:hash_map, timl#cons#create(s:concat, s:sqexpandlist(keyvals, a:gensyms)))\n\n  elseif timl#coll#test(a:form)\n    let first = timl#coll#first(a:form)\n    if first is# s:unquote\n      return timl#coll#first(timl#coll#rest(a:form))\n    elseif first is# s:unquote_splicing\n      throw 'timl#reader: unquote-splicing used outside of list'\n    elseif first is# s:function\n      return a:form\n    else\n      return timl#list(s:seq, timl#cons#create(s:concat, s:sqexpandlist(a:form, a:gensyms)))\n    endif\n  else\n    return a:form\n  endif\nendfunction\n\nfunction! s:sqexpandlist(seq, gensyms) abort\n  let result = []\n  let _ = {'seq': timl#coll#seq(a:seq)}\n  while _.seq isnot# g:timl#nil\n    let _.this = timl#coll#first(_.seq)\n    if timl#coll#seqp(_.this)\n      if timl#coll#first(_.this) is# s:unquote\n        call add(result, timl#list(s:list, timl#coll#first(timl#coll#rest(_.this))))\n      elseif timl#coll#first(_.this) is# s:unquote_splicing\n        call add(result, timl#coll#first(timl#coll#rest(_.this)))\n      else\n        call add(result, timl#list(s:list, timl#reader#syntax_quote(_.this, a:gensyms)))\n      endif\n    else\n      call add(result, timl#list(s:list, timl#reader#syntax_quote(_.this, a:gensyms)))\n    endif\n    let _.seq = timl#coll#next(_.seq)\n  endwhile\n  return result\nendfunction\n\nfunction! timl#reader#open(filename) abort\n  let str = join(readfile(a:filename), \"\\n\")\n  return {'str': str, 'filename': fnamemodify(a:filename, ':p'), 'pos': 0, 'line': 1}\nendfunction\n\nfunction! timl#reader#open_string(string, ...) abort\n  let port = {'str': a:string, 'pos': 0, 'line': a:0 > 1 ? a:2 : 1}\n  if a:0\n    let port.filename = a:1\n  endif\n  return port\nendfunction\n\nfunction! timl#reader#close(port) abort\n  return a:port\nendfunction\n\nfunction! timl#reader#read_all(port) abort\n  let all = []\n  let _ = {}\n  try\n    while 1\n      let _.form = s:read(a:port)\n      if _.form is# g:timl#reader#eof\n        return all\n      endif\n      call add(all, _.form)\n    endwhile\n  catch /^timl.*/\n    let error = v:exception\n  endtry\n  throw error\nendfunction\n\nfunction! timl#reader#read_string_all(str) abort\n  return timl#reader#read_all({'str': a:str, 'pos': 0, 'line': 1})\nendfunction\n\nfunction! timl#reader#read_string(str) abort\n  return timl#reader#read({'str': a:str, 'pos': 0, 'line': 1})\nendfunction\n\n\" Section: Tests {{{1\n\nif !$TIML_TEST\n  finish\nendif\n\ncommand! -nargs=1 TimLRAssert\n      \\ try |\n      \\ if !eval(<q-args>) |\n      \\ echomsg \"Failed: \".<q-args> |\n      \\   endif |\n      \\ catch /.*/ |\n      \\  echomsg \"Error:  \".<q-args>.\" (\".v:exception.\")\" |\n      \\ endtry\n\nTimLRAssert timl#equality#test(timl#reader#read_string('foo'), timl#symbol('foo'))\nTimLRAssert timl#equality#test(timl#reader#read_string('\":)\"'), ':)')\nTimLRAssert timl#equality#test(timl#reader#read_string('#\"\\(a\\\\\\)\"'), '\\C\\v\\(a\\\\\\)')\nTimLRAssert timl#equality#test(timl#reader#read_string('#\"\\\"\"'), '\\C\\v\"')\nTimLRAssert timl#equality#test(timl#reader#read_string('(first [1 2])'), timl#list(timl#symbol('first'), timl#vector#claim([1, 2])))\nTimLRAssert timl#equality#test(timl#reader#read_string('#*{\"a\" 1 \"b\" 2}'), {\"a\": 1, \"b\": 2})\nTimLRAssert timl#equality#test(timl#reader#read_string('{\"a\" 1 :b 2 3 \"c\"}'), timl#map#create([\"a\", 1, timl#keyword#intern('b'), 2, 3, \"c\"]))\nTimLRAssert timl#equality#test(timl#reader#read_string(\"[1]\\n; hi\\n\"), timl#vector#claim([1]))\nTimLRAssert timl#equality#test(timl#reader#read_string(\"'[1 2 3]\"), timl#list(timl#symbol('quote'), timl#vector#claim([1, 2, 3])))\nTimLRAssert timl#equality#test(timl#reader#read_string(\"#*tr\"), timl#list(timl#symbol('function'), timl#symbol('tr')))\nTimLRAssert timl#equality#test(timl#reader#read_string(\"(1 #_2 3)\"), timl#list(1, 3))\nTimLRAssert timl#equality#test(timl#reader#read_string(\"^:foo ()\"),\n      \\ timl#meta#with(g:timl#empty_list, timl#map#create([timl#keyword#intern('foo'), g:timl#true])))\n\nTimLRAssert timl#equality#test(timl#reader#read_string(\"~foo\"), timl#list(s:unquote, timl#symbol('foo')))\nTimLRAssert timl#coll#first(timl#coll#rest(timl#reader#read_string(\"`foo#\")))[0] =~# '^foo__\\d\\+__auto__'\n\ndelcommand TimLRAssert\n\n\" }}}1\n\n\" vim:set et sw=2:\n"
  },
  {
    "path": "autoload/timl/repl.tim",
    "content": "(ns timl.repl)\n\n(defn qf\n  ([] (qf *e))\n  ([e]\n   (#*timl#interactive#copen e)\n   (throw \"timl#repl: exit\")))\n\n(defn breakpoint-fn [env]\n  (let [str (#*input (format \"%s=>> \" (str (ns-name *ns*))))]\n    (when (#*len str)\n      (newline)\n      (try\n        (prn (#*timl#loader#eval (read-string str) (ns-name *ns*) env))\n        (catch \"\" e (set! *e e) (println (. e exception))))\n      (recur env))))\n\n(defmacro breakpoint []\n  `(timl.repl/breakpoint-fn ~(list #*eval \"locals\")))\n\n(defmacro breakadd []\n  `(execute \"execute 'breakadd func '.(1+expand('<slnum>')).' '.matchstr(expand('<sfile>'), '.*\\\\.\\\\zs.*')\"))\n(defn breakme []\n  (breakadd)\n  (+ 1 (* 2 3)))\n\n(defn compile [body]\n  (print (. (#*timl#compiler#build body) body)))\n\n(defn help-topic [sym]\n  (if (special-symbol? sym)\n    (str \"timl-\" sym)\n    (if-let [v (resolve sym)]\n      (:help (meta v) (. v location))\n      (str sym))))\n\n(defmacro help [sym]\n  `(throw (str \"timl#repl: exit help \" ~(help-topic sym))))\n\n(defmacro edit [sym]\n  `(let [m (meta (var ~sym))]\n     (if (not= (:file m \"NO_SOURCE_PATH\") \"NO_SOURCE_PATH\")\n       (throw (str \"timl#repl: exit edit +\" (:line m) \" \" (#*fnameescape (:file m)))))))\n"
  },
  {
    "path": "autoload/timl/set.vim",
    "content": "\" Maintainer: Tim Pope <http://tpo.pe>\n\nif exists(\"g:autoloaded_timl_set\")\n  finish\nendif\nlet g:autoloaded_timl_set = 1\n\nfunction! timl#set#test(coll) abort\n  return timl#type#canp(a:coll, g:timl#core.disj)\nendfunction\n\nfunction! timl#set#key(key) abort\n  if type(a:key) == type(0)\n    return string(a:key)\n  elseif timl#keyword#test(a:key) && a:key[0][0:1] !=# '__'\n    return a:key[0]\n  elseif timl#symbol#test(a:key)\n    return \"'\".a:key[0]\n  elseif type(a:key) == type('')\n    return '\"'.a:key[0]\n  elseif a:key is# g:timl#nil\n    return ' '\n  else\n    return ''\n  endif\nendfunction\n\nfunction! timl#set#coerce(seq) abort\n  if timl#set#test(a:seq)\n    return a:seq\n  endif\n  let _ = {}\n  let dict = timl#type#bless(s:transient_type, {'__extra': []})\n  if type(a:seq) == type([])\n    for _.val in a:seq\n      call timl#set#conjb(dict, _.val)\n    endfor\n  else\n    let _.seq = timl#coll#seq(a:seq)\n    while _.seq isnot# g:timl#nil\n      call timl#set#conjb(dict, timl#coll#first(_.seq))\n      let _.seq = timl#coll#next(_.seq)\n    endwhile\n  endif\n  return timl#set#persistentb(dict)\nendfunction\n\nfunction! timl#set#to_array(this) abort\n  return extend(map(filter(items(a:this), 'v:val[0][0:1] !=# \"__\"'), 'v:val[1]'), a:this.__extra)\nendfunction\n\nfunction! timl#set#length(this) abort\n  return len(timl#set#to_array(a:this))\nendfunction\n\nfunction! timl#set#seq(this) abort\n  let items = timl#set#to_array(a:this)\n  return empty(items) ? g:timl#nil : timl#array_seq#create(items)\nendfunction\n\nfunction! timl#set#equal(this, that) abort\n  if a:this is# a:that\n    return g:timl#true\n  elseif !timl#set#test(a:that)\n    return g:timl#false\n  endif\n  if timl#coll#count(a:this) !=# timl#coll#count(a:that)\n    return g:timl#false\n  endif\n  let _ = {'seq': timl#coll#seq(a:this)}\n  while _.seq isnot# g:timl#nil\n    if timl#coll#get(a:that, timl#coll#first(_.seq), _) is# _\n      return g:timl#false\n    endif\n    let _.seq = timl#coll#next(_.seq)\n  endwhile\n  return g:timl#true\nendfunction\n\nfunction! timl#set#lookup(this, key, ...) abort\n  let _ = {}\n  let key = timl#set#key(a:key)\n  if empty(key)\n    for _.v in a:this.__extra\n      if timl#equality#test(_.v, a:key)\n        return _.v\n      endif\n    endfor\n    return a:0 ? a:1 g:timl#nil\n  else\n    return get(a:this, key, a:0 ? a:1 : g:timl#nil)\n  endif\nendfunction\n\nfunction! timl#set#empty(this) abort\n  return s:empty\nendfunction\n\nfunction! timl#set#conj(this, ...) abort\n  return timl#set#persistentb(call('timl#set#conjb', [timl#set#transient(a:this)] + a:000))\nendfunction\n\nfunction! timl#set#conjb(this, ...) abort\n  let _ = {}\n  for _.e in a:000\n    let key = timl#set#key(_.e)\n    if empty(key)\n      let found = 0\n      for i in range(len(a:this.__extra))\n        if timl#equality#test(a:this.__extra[i], _.e)\n          let a:this.__extra[i] = _.e\n          let found = 1\n          break\n        endif\n      endfor\n      if !found\n        call add(a:this.__extra, _.e)\n      endif\n    else\n      let a:this[key] = _.e\n    endif\n  endfor\n  return a:this\nendfunction\n\nfunction! timl#set#disj(this, ...) abort\n  return timl#set#persistentb(call('timl#set#disjb', [timl#set#transient(a:this)] + a:000))\nendfunction\n\nfunction! timl#set#disjb(this, ...) abort\n  let _ = {}\n  for _.e in a:000\n    let key = timl#set#key(_.e)\n    if empty(key)\n      for i in range(len(a:this.__extra))\n        if timl#equality#test(a:this.__extra[i], _.e)\n          call remove(a:this.__extra, i)\n          break\n        endif\n      endfor\n    elseif has_key(a:this, key)\n      call remove(a:this, key)\n    endif\n  endfor\n  return a:this\nendfunction\n\nfunction! timl#set#transient(this) abort\n  let that = copy(a:this)\n  let that.__extra = copy(a:this.__extra)\n  return timl#type#bless(s:transient_type, that)\nendfunction\n\nfunction! timl#set#persistentb(this) abort\n  let this = timl#type#bless(s:type, a:this)\n  lockvar 1 a:this.__extra\n  lockvar 1 a:this\n  return a:this\nendfunction\n\nfunction! timl#set#call(this, _) abort\n  return call('timl#set#lookup', [a:this] + a:_)\nendfunction\n\nlet s:type = timl#type#core_define('HashSet', g:timl#nil, {\n      \\ 'seq': 'timl#set#seq',\n      \\ 'lookup': 'timl#set#lookup',\n      \\ 'empty': 'timl#set#empty',\n      \\ 'conj': 'timl#set#conj',\n      \\ 'length': 'timl#set#length',\n      \\ 'equiv': 'timl#set#equal',\n      \\ 'disj': 'timl#set#disj',\n      \\ 'transient': 'timl#set#transient',\n      \\ 'call': 'timl#set#call'})\n\nlet s:transient_type = timl#type#core_define('TransientHashSet', g:timl#nil, {\n      \\ 'length': 'timl#set#length',\n      \\ 'lookup': 'timl#set#lookup',\n      \\ 'conj!': 'timl#set#conjb',\n      \\ 'disj!': 'timl#set#disjb',\n      \\ 'persistent!': 'timl#set#persistentb'})\n\nif !exists('s:empty')\n  let s:empty = timl#type#bless(s:type, {'__extra': []})\n  lockvar 1 s:empty.__extra\n  lockvar 1 s:empty\nendif\n"
  },
  {
    "path": "autoload/timl/string.vim",
    "content": "\" Maintainer: Tim Pope <http://tpo.pe/>\n\nif exists('g:autoloaded_timl_string')\n  finish\nendif\nlet g:autoloaded_timl_string = 1\n\nlet s:type = type('')\nfunction! timl#string#test(str) abort\n  return type(a:str) == s:type\nendfunction\n\nfunction! timl#string#coerce(val) abort\n  if type(a:val) == type('')\n    return a:val\n  elseif type(a:val) == type(0) || type(a:val) == 5\n    return ''.a:val\n  elseif timl#symbol#test(a:val) || timl#keyword#test(a:val)\n    return a:val.str\n  elseif timl#type#canp(a:val, g:timl#core.to_string)\n    return timl#invoke(g:timl#core.to_string, a:val)\n  else\n    return '#<'.timl#type#string(a:val).'>'\n  endif\nendfunction\n\n\" Characters, not bytes\nfunction! timl#string#lookup(this, idx, default) abort\n  if type(a:idx) == type(0)\n    let ch = matchstr(a:this, repeat('.', a:idx).'\\zs.')\n    return empty(ch) ? (a:0 ? a:1 : g:timl#nil) : ch\n  endif\n  return a:default\nendfunction\n\nfunction! timl#string#length(this) abort\n  return exists('*strchars') ? strchars(a:this) : len(substitute(a:this, '.', '.', 'g'))\nendfunction\n\nfunction! timl#string#seq(this) abort\n  return timl#array_seq#create(split(a:this, '\\zs'))\nendfunction\n\nfunction! timl#string#join(sep_or_coll, ...) abort\n  return join(\n        \\ map(copy(timl#array#coerce(a:0 ? a:1 : a:sep_or_coll)), 'timl#string#coerce(v:val)'),\n        \\ a:0 ? timl#string#coerce(a:sep_or_coll) : '')\nendfunction\n\nfunction! timl#string#split(s, re) abort\n  return timl#vector#claim(split(a:s, '\\C'.a:re))\nendfunction\n\nfunction! timl#string#replace(s, re, repl) abort\n  return substitute(a:s, '\\C'.a:re, a:repl, 'g')\nendfunction\n\nfunction! timl#string#replace_one(s, re, repl) abort\n  return substitute(a:s, '\\C'.a:re, a:repl, '')\nendfunction\n\nfunction! timl#string#re_quote_replacement(re) abort\n  return escape(a:re, '\\~&')\nendfunction\n\nfunction! timl#string#re_find(re, s) abort\n  let result = matchlist(a:s, '\\C'.a:re)\n  return empty(result) ? g:timl#nil : timl#vector#claim(result)\nendfunction\n\nfunction! timl#string#sub(str, start, ...) abort\n  if a:0 && a:1 <= a:start\n    return ''\n  elseif a:0\n    return matchstr(a:str, '.\\{,'.(a:1-a:start).'\\}', byteidx(a:str, a:start))\n  else\n    return a:str[byteidx(a:str, a:start) :]\n  endif\nendfunction\n\nfunction! timl#string#pr(_) abort\n  return join(map(copy(a:_), 'timl#printer#string(v:val)'), ' ')\nendfunction\n\nfunction! timl#string#prn(_) abort\n  return join(map(copy(a:_), 'timl#printer#string(v:val)'), ' ').\"\\n\"\nendfunction\n\nfunction! timl#string#print(_) abort\n  return join(map(copy(a:_), 'timl#string#coerce(v:val)'), ' ')\nendfunction\n\nfunction! timl#string#println(_) abort\n  return join(map(copy(a:_), 'timl#string#coerce(v:val)'), ' ').\"\\n\"\nendfunction\n"
  },
  {
    "path": "autoload/timl/symbol.vim",
    "content": "\" Maintainer: Tim Pope <http://tpo.pe>\n\nif exists(\"g:autoloaded_timl_symbol\")\n  finish\nendif\nlet g:autoloaded_timl_symbol = 1\n\nif !exists('s:symbols')\n  let s:symbols = {}\nendif\n\nfunction! timl#symbol#intern(str) abort\n  if !has_key(s:symbols, a:str)\n    let end = matchend(a:str, '^\\%(&\\=\\w:\\|\\$\\|&\\%($\\|form$\\|env$\\)\\@!\\|[^/]*/\\).\\@=')\n    let symbol = timl#type#bless(s:type, {\n          \\ '0': a:str,\n          \\ 'str': a:str,\n          \\ 'meta': g:timl#nil,\n          \\ 'namespace': end == -1 ? '' : a:str[0 : end-(a:str[end-1] ==# '/' ? 2 : 1)],\n          \\ 'name': end == -1 ? a:str : a:str[end : -1]})\n    lockvar 1 symbol\n    let s:symbols[a:str] = symbol\n  endif\n  return s:symbols[a:str]\nendfunction\n\nfunction! timl#symbol#intern_with_meta(str, meta) abort\n  let sym = copy(timl#symbol#intern(a:str))\n  let sym.meta = a:meta\n  return sym\nendfunction\n\nfunction! timl#symbol#test(symbol) abort\n  return type(a:symbol) == type({}) &&\n        \\ get(a:symbol, '__type__') is# s:type\nendfunction\n\nfunction! timl#symbol#is(symbol, ...) abort\n  return type(a:symbol) == type({}) &&\n        \\ get(a:symbol, '__type__') is# s:type &&\n        \\ (a:0 ? a:symbol[0] ==# a:1 : 1)\nendfunction\n\nfunction! timl#symbol#cast(symbol) abort\n  if !timl#symbol#test(a:symbol)\n    throw 'timl: symbol expected but received '.timl#type#string(a:symbol)\n  endif\n  return a:symbol\nendfunction\n\nfunction! timl#symbol#equal(this, that) abort\n  return timl#symbol#test(a:that) && a:this[0] ==# a:that[0] ? g:timl#true : g:timl#false\nendfunction\n\nfunction! timl#symbol#gen(...) abort\n  let s:id = get(s:, 'id', 0) + 1\n  return timl#symbol((a:0 ? a:1 : 'G__').s:id)\nendfunction\n\nlet s:type = timl#type#core_create('Symbol')\n"
  },
  {
    "path": "autoload/timl/test.tim",
    "content": "(ns timl.test)\n\n(defmacro assert [form]\n  `(try\n     (if ~form\n       true\n       (echo \"Failed: \" (pr-str '~form)))\n     (catch \"\" e# (echo \"Error on \" (pr-str '~form) \": \" v:exception))))\n"
  },
  {
    "path": "autoload/timl/true.vim",
    "content": "\" Maintainer: Tim Pope <http://tpo.pe/>\n\nif exists(\"g:autoloaded_timl_true\")\n  finish\nendif\nlet g:autoloaded_timl_true = 1\n\nif !exists('g:timl#true')\n  let g:timl#true = timl#type#bless(timl#type#core_create('Boolean'), {'val': 1})\n  lockvar 1 g:timl#true\nendif\n\nfunction! timl#true#identity() abort\n  return g:timl#true\nendfunction\n\nfunction! timl#true#test(val) abort\n  return a:val is# g:timl#true\nendfunction\n"
  },
  {
    "path": "autoload/timl/type.vim",
    "content": "\" Maintainer: Tim Pope <http://tpo.pe>\n\nif exists(\"g:autoloaded_timl_type\")\n  finish\nendif\nlet g:autoloaded_timl_type = 1\n\nfunction! s:freeze(...) abort\n  return a:000\nendfunction\n\nif !exists('g:timl#nil')\n  let g:timl#nil = s:freeze()\n  lockvar 1 g:timl#nil\nendif\n\n\" Section: Blessing\n\nif !exists('g:timl_tag_sentinel')\n  let g:timl_tag_sentinel = s:freeze('blessed object')\n  lockvar 1 g:timl_tag_sentinel\nendif\n\nif !exists('s:types')\n  let s:types = {}\nendif\n\nfunction! timl#type#find(name) abort\n  return get(s:types, timl#string#coerce(a:name), g:timl#nil)\nendfunction\n\nfunction! timl#type#create(name, ...) abort\n  let munged = tr(a:name, '-./', '_##')\n  if !has_key(s:types, a:name)\n    let s:types[a:name] = timl#type#bless(s:type_type, {\n          \\ 'str': a:name,\n          \\ 'location': 'g:'.munged,\n          \\ 'slots': g:timl#nil,\n          \\ '__call__': function('timl#type#constructor')})\n  endif\n  let s:types[a:name].slots = a:0 ? a:1 : g:timl#nil\n  let g:{munged} = s:types[a:name]\n  return s:types[a:name]\nendfunction\n\nfunction! timl#type#core_create(name, ...) abort\n  return timl#type#create('timl.lang/'.a:name, a:0 ? a:1 : g:timl#nil)\nendfunction\n\nfunction! timl#type#core_define(name, slots, methods) abort\n  let ns = timl#namespace#create(timl#symbol#intern('timl.core'))\n  let type = timl#type#core_create(a:name, a:slots)\n  for [k, v] in items(a:methods)\n    call timl#type#define_method(ns, timl#symbol#intern(k), type, function(v))\n  endfor\n  return type\nendfunction\n\nfunction! timl#type#constructor(_) dict abort\n  if get(self, 'slots') is# g:timl#nil\n    throw 'timl: constructor not implemented'\n  endif\n  if len(a:_) != len(self.slots)\n    throw 'timl: arity error'\n  endif\n  let object = {}\n  for i in range(len(a:_))\n    let object[self.slots[i]] = a:_[i]\n  endfor\n  return timl#type#bless(self, object)\nendfunction\n\nif !has_key(s:types, 'timl.lang/Type')\n  let s:types['timl.lang/Type'] = {\n        \\ 'str': 'timl.lang/Type',\n        \\ 'location': 'g:timl#lang#Type',\n        \\ 'slots': g:timl#nil,\n        \\ '__call__': function('timl#type#constructor')}\nendif\nlet s:type_type = s:types['timl.lang/Type']\nfunction! timl#type#define(ns, var, slots) abort\n  let str = timl#namespace#name(a:ns).name . '/' . timl#symbol#cast(a:var).name\n  let type = timl#type#create(str)\n  if a:slots isnot# g:timl#nil\n    let type.slots = map(timl#array#coerce(a:slots), 'timl#symbol#cast(v:val).name')\n  endif\n  return timl#namespace#intern(a:ns, a:var, type)\nendfunction\n\nlet s:builtins = {\n      \\ 0: 'vim/Number',\n      \\ 1: 'vim/String',\n      \\ 2: 'vim/Funcref',\n      \\ 3: 'vim/List',\n      \\ 4: 'vim/Dictionary',\n      \\ 5: 'vim/Float'}\n\nfunction! timl#type#objectp(obj) abort\n  return type(a:obj) == type({}) && get(a:obj, '__flag__') is g:timl_tag_sentinel\nendfunction\n\nfunction! timl#type#string(val) abort\n  let type = get(s:builtins, type(a:val), 'vim/Unknown')\n  if a:val is# g:timl#nil\n    return 'timl.lang/Nil'\n  elseif type ==# 'vim/Dictionary'\n    if get(a:val, '__flag__') is g:timl_tag_sentinel\n      return a:val.__type__.str\n    endif\n  endif\n  return type\nendfunction\n\nlet s:proto = {\n      \\ '__call__': function('timl#type#dispatch_call'),\n      \\ '__flag__': g:timl_tag_sentinel}\nfunction! timl#type#bless(type, ...) abort\n  let obj = a:0 ? a:1 : {}\n  call extend(obj, s:proto, 'keep')\n  let obj.__type__ = a:type\n  return obj\nendfunction\n\nfunction! timl#type#dispatch_call(_) dict\n  return g:timl#core.call.__call__([self, a:_])\nendfunction\n\ncall timl#type#bless(s:type_type, s:type_type)\n\n\" Section: Hierarchy\n\" Cribbed from clojure.core\n\nfunction! timl#type#parents(key) abort\n  return timl#set#coerce(values(get(g:timl_hierarchy.parents, timl#string#coerce(a:key), {})))\nendfunction\n\nfunction! timl#type#ancestors(key) abort\n  return timl#set#coerce(values(get(g:timl_hierarchy.ancestors, timl#string#coerce(a:key), {})))\nendfunction\n\nfunction! timl#type#descendants(key) abort\n  return timl#set#coerce(values(get(g:timl_hierarchy.descendants, timl#string#coerce(a:key), {})))\nendfunction\n\nfunction! s:tf(m, source, sources, target, targets) abort\n  for k in [a:source] + values(get(a:sources, a:source[0], {}))\n    if !has_key(a:targets, k[0])\n      let a:targets[k[0]] = {}\n    endif\n    let a:targets[k[0]][a:target[0]] = a:target\n    for j in values(get(a:targets, a:target[0], {}))\n      let a:targets[k[0]][j[0]] = j\n    endfor\n  endfor\nendfunction\n\nfunction! s:isap(tag, parent) abort\n  return a:tag ==# a:parent || has_key(get(g:timl_hierarchy.ancestors, a:tag, {}), a:parent)\nendfunction\n\nfunction! timl#type#isap(tag, parent) abort\n  return timl#keyword#cast(a:tag) is# timl#keyword#cast(a:parent)\n        \\ || has_key(get(g:timl_hierarchy.ancestors, a:tag[0], {}), a:parent[0])\nendfunction\n\nfunction! timl#type#derive(tag, parent) abort\n  let tp = g:timl_hierarchy.parents\n  let td = g:timl_hierarchy.descendants\n  let ta = g:timl_hierarchy.ancestors\n  let tag = timl#keyword#cast(a:tag)\n  let parent = timl#keyword#cast(a:parent)\n  if !has_key(tp, tag[0])\n    let tp[tag[0]] = {}\n  endif\n  if !has_key(tp[tag[0]], parent[0])\n    if has_key(get(ta, tag[0], {}), parent[0])\n      throw \"timl#type: :\".tag[0].\" already has :\".parent[0].\" as ancestor\"\n    endif\n    if has_key(get(ta, parent[0], {}), tag[0])\n      throw \"timl#type: :\".parent[0].\" has :\".tag[0].\" as ancestor\"\n    endif\n    let tp[tag[0]][parent[0]] = parent\n    call s:tf(ta, tag, td, parent, ta)\n    call s:tf(td, parent, ta, tag, td)\n  endif\n  let g:timl_hierarchy = copy(g:timl_hierarchy) \" expire caches\n  return g:timl_hierarchy\nendfunction\n\n\" Section: Dispatch\n\nfunction! timl#type#canp(obj, this) abort\n  return s:get_method(a:this, timl#type#string(a:obj)) isnot# g:timl#nil\nendfunction\n\nfunction! s:get_method(this, type) abort\n  if a:this.hierarchy isnot# g:timl_hierarchy\n    let a:this.cache = {}\n    let a:this.hierarchy = g:timl_hierarchy\n  endif\n  if !has_key(a:this.cache, a:type)\n    let _ = {'preferred': g:timl#nil}\n    for [_.type, _.fn] in items(a:this.methods)\n      if s:isap(a:type, _.type)\n        if _.preferred is g:timl#nil || s:isap(_.type, _.preferred[0])\n          let _.preferred = [_.type, _.fn]\n        elseif !s:isap(_.preferred[0], _.type)\n          throw 'timl#type: ambiguous'\n        endif\n      endif\n    endfor\n    if _.preferred is# g:timl#nil\n      let a:this.cache[a:type] = get(a:this.methods, ' ', g:timl#nil)\n    else\n      let a:this.cache[a:type] = _.preferred[1]\n    endif\n  endif\n  return get(a:this.cache, a:type, g:timl#nil)\nendfunction\n\nlet s:t_function = type(function('tr'))\nlet s:t_dict = type({})\nfunction! timl#type#apply(_) dict abort\n  let type = timl#type#string(a:_[0])\n  if self.hierarchy isnot# g:timl_hierarchy\n    let self.cache = {}\n    let self.hierarchy = g:timl_hierarchy\n  endif\n  let Dispatch = has_key(self.cache, type) ? self.cache[type] : s:get_method(self, type)\n  let t = type(Dispatch)\n  if t == s:t_function\n    return call(Dispatch, a:_)\n  elseif t == s:t_dict\n    return Dispatch.__call__(a:_)\n  endif\n  throw 'timl#type: no '.self.ns.__name__[0].'/'.self.name[0].' dispatch for '.type\nendfunction\n\nfunction! timl#type#dispatch(this, _) abort\n  return call('timl#type#apply', [a:_], a:this)\nendfunction\n\n\" Section: Method Creation\n\nfunction! timl#type#define_method(ns, name, type, fn) abort\n  let var = timl#namespace#maybe_resolve(a:ns, timl#symbol#cast(a:name))\n  if var is# g:timl#nil || timl#type#string(timl#var#get(var)) isnot# 'timl.lang/MultiFn'\n    unlet var\n    if !empty(a:name.namespace)\n      throw \"timl: no such method \".a:name.str\n    endif\n    let fn = timl#type#bless(s:multifn_type, {\n          \\ '__call__': function('timl#type#apply'),\n          \\ 'ns': a:ns,\n          \\ 'name': a:name,\n          \\ 'cache': {},\n          \\ 'hierarchy': g:timl_hierarchy,\n          \\ 'methods': {}})\n    let var = timl#namespace#intern(a:ns, a:name, fn)\n  endif\n  let multi = timl#var#get(var)\n  let multi.methods[a:type is# g:timl#nil ? ' ' : a:type.str] = a:fn\n  let multi.cache = {}\n  return var\nendfunction\nlet s:multifn_type = timl#type#core_create('MultiFn')\n\n\" Section: Initialization\n\nif !exists('g:timl_hierarchy')\n  let g:timl_hierarchy = {'parents': {}, 'descendants': {}, 'ancestors': {}}\nendif\n\n\" vim:set et sw=2:\n"
  },
  {
    "path": "autoload/timl/var.vim",
    "content": "\" Maintainer: Tim Pope <http://tpo.pe/>\n\nif exists('g:autoloaded_timl_var')\n  finish\nendif\nlet g:autoloaded_timl_var = 1\n\nfunction! timl#var#get(var) abort\n  return eval(a:var.location)\nendfunction\n\nfunction! timl#var#call(var, _) abort\n  return timl#call(eval(a:var.location), a:_)\nendfunction\n\nfunction! timl#var#test(this) abort\n  return timl#type#string(a:this) ==# 'timl.lang/Var'\nendfunction\n\nfunction! timl#var#find(sym) abort\n  let sym = timl#symbol#cast(a:sym)\n  let ns = empty(sym.namespace) ? timl#namespace#name(g:timl#core._STAR_ns_STAR_).str : sym.namespace\n  return get(timl#namespace#find(ns).__mappings__, sym.name, g:timl#nil)\nendfunction\n\nfunction! timl#var#funcref(var) abort\n  return function(a:var.munged)\nendfunction\n\nfunction! timl#var#reset_meta(var, meta) abort\n  let a:var.meta = a:meta\n  return a:var\nendfunction\n\n\" Section: Munging\n\n\" From clojure/lang/Compiler.java\nlet s:munge = {\n      \\ '.': \"#\",\n      \\ ',': \"_COMMA_\",\n      \\ ':': \"_COLON_\",\n      \\ '+': \"_PLUS_\",\n      \\ '>': \"_GT_\",\n      \\ '<': \"_LT_\",\n      \\ '=': \"_EQ_\",\n      \\ '~': \"_TILDE_\",\n      \\ '!': \"_BANG_\",\n      \\ '@': \"_CIRCA_\",\n      \\ \"'\": \"_SINGLEQUOTE_\",\n      \\ '\"': \"_DOUBLEQUOTE_\",\n      \\ '%': \"_PERCENT_\",\n      \\ '^': \"_CARET_\",\n      \\ '&': \"_AMPERSAND_\",\n      \\ '*': \"_STAR_\",\n      \\ '|': \"_BAR_\",\n      \\ '{': \"_LBRACE_\",\n      \\ '}': \"_RBRACE_\",\n      \\ '[': \"_LBRACK_\",\n      \\ ']': \"_RBRACK_\",\n      \\ '/': \"_SLASH_\",\n      \\ '\\\\': \"_BSLASH_\",\n      \\ '?': \"_QMARK_\"}\n\nlet s:demunge = {}\nfor s:key in keys(s:munge)\n  let s:demunge[s:munge[s:key]] = s:key\nendfor\nunlet! s:key\n\nfunction! timl#var#munge(var) abort\n  let var = type(a:var) == type('') ? a:var : a:var[0]\n  return tr(substitute(substitute(var, '[^[:alnum:]:#_-]', '\\=get(s:munge,submatch(0), submatch(0))', 'g'), '_SLASH_\\ze.', '.', ''), '-', '_')\nendfunction\n\nfunction! timl#var#demunge(var) abort\n  let var = type(a:var) == type('') ? a:var : a:var[0]\n  return tr(substitute(var, '_\\(\\u\\+\\)_', '\\=get(s:demunge, submatch(0), submatch(0))', 'g'), '_', '-')\nendfunction\n"
  },
  {
    "path": "autoload/timl/vector.vim",
    "content": "\" Maintainer: Tim Pope <http://tpo.pe/>\n\nif exists('g:autoloaded_timl_vector')\n  finish\nendif\nlet g:autoloaded_timl_vector = 1\n\nfunction! timl#vector#test(obj) abort\n  return timl#type#canp(a:obj, g:timl#core.nth)\nendfunction\n\nlet s:type = timl#type#core_create('Vector')\nfunction! timl#vector#claim(array) abort\n  lockvar 1 a:array\n  let vector = timl#type#bless(s:type, {'array': a:array})\n  lockvar 1 vector\n  return vector\nendfunction\n\nfunction! timl#vector#coerce(seq) abort\n  if a:seq is# g:timl#nil\n    return s:empty\n  elseif type(a:seq) ==# type([])\n    return timl#vector#claim(copy(a:seq))\n  elseif timl#type#string(a:seq) ==# s:type.str\n    return a:seq\n  endif\n  let array = []\n  let _ = {'seq': timl#coll#seq(a:seq)}\n  while _.seq isnot# g:timl#nil\n    call add(array, timl#coll#first(_.seq))\n    let _.seq = timl#coll#next(_.seq)\n  endwhile\n  return timl#vector#claim(array)\nendfunction\n\nfunction! timl#vector#seq(this) abort\n  return timl#array#seq(a:this.array)\nendfunction\n\nfunction! timl#vector#length(this) abort\n  return len(a:this.array)\nendfunction\n\nfunction! timl#vector#car(this) abort\n  return get(a:this.array, 0, g:timl#nil)\nendfunction\n\nfunction! timl#vector#cdr(this) abort\n  return len(a:this.array) <= 1 ? g:timl#empty_list : timl#array_seq#create(a:this.array, 1)\nendfunction\n\nfunction! timl#vector#lookup(this, idx, ...) abort\n  if type(a:idx) == type(0) && a:idx >= 0\n    return get(a:this.array, a:idx, a:0 ? a:1 : g:timl#nil)\n  endif\n  return a:0 ? a:1 : g:timl#nil\nendfunction\n\nfunction! timl#vector#nth(this, idx, ...) abort\n  let idx = timl#number#int(a:idx)\n  if a:0\n    return get(a:this.array, idx, a:1)\n  else\n    return a:this.array[idx]\n  endif\nendfunction\n\nfunction! timl#vector#conj(this, ...) abort\n  return timl#vector#claim(a:this.array + a:000)\nendfunction\n\nlet s:empty = timl#vector#claim([])\nfunction! timl#vector#empty(this) abort\n  return s:empty\nendfunction\n\nfunction! timl#vector#transient(this) abort\n  return copy(a:this.array)\nendfunction\n\nfunction! timl#vector#sub(this, start, ...) abort\n  let array = timl#vector#coerce(a:this).array\n  if a:0 && a:1 == 0\n    return s:empty\n  elseif a:0\n    return timl#vector#claim(array[a:start : (a:1 < 0 ? a:1 : a:1-1)])\n  else\n    return timl#vector#claim(array[a:start :])\n  endif\nendfunction\n\nfunction! timl#vector#call(this, _) abort\n  return call('timl#vector#lookup', [a:this] + a:_)\nendfunction\n"
  },
  {
    "path": "autoload/timl.vim",
    "content": "\" Maintainer:   Tim Pope <http://tpo.pe/>\n\nif exists(\"g:autoloaded_timl\")\n  finish\nendif\nlet g:autoloaded_timl = 1\n\n\" Section: Util {{{1\n\nfunction! timl#truth(val) abort\n  return a:val isnot# g:timl#nil && a:val isnot# g:timl#false\nendfunction\n\nfunction! timl#keyword(str) abort\n  return timl#keyword#intern(a:str)\nendfunction\n\nfunction! timl#symbol(str) abort\n  return timl#symbol#intern(a:str)\nendfunction\n\n\" }}}1\n\" Section: Lists {{{1\n\nfunction! timl#seq(coll) abort\n  return timl#coll#seq(a:coll)\nendfunction\n\nfunction! timl#first(coll) abort\n  return timl#coll#first(a:coll)\nendfunction\n\nfunction! timl#rest(coll) abort\n  return timl#coll#rest(a:coll)\nendfunction\n\nfunction! timl#next(coll) abort\n  return timl#coll#seq(timl#coll#rest(rest))\nendfunction\n\nfunction! timl#list(...) abort\n  return timl#list#create(a:000)\nendfunction\n\n\" }}}1\n\" Section: Invocation {{{1\n\nfunction! timl#call(Func, args, ...) abort\n  if type(a:Func) == type(function('tr'))\n    return call(a:Func, a:args, a:0 ? a:1 : {})\n  else\n    return a:Func.__call__(a:args)\n  endif\nendfunction\n\nfunction! timl#invoke(Func, ...) abort\n  if type(a:Func) == type(function('tr'))\n    return call(a:Func, a:000, {})\n  else\n    return a:Func.__call__(a:000)\n  endif\nendfunction\n\n\" }}}1\n\" Section: Evaluation {{{1\n\nfunction! timl#eval(x) abort\n  return timl#loader#eval(a:x)\nendfunction\n\nfunction! timl#re(str) abort\n  return timl#eval(timl#reader#read_string(a:str))\nendfunction\n\nfunction! timl#rep(str) abort\n  return timl#printer#string(timl#re(a:str))\nendfunction\n\n\" }}}1\n\nruntime! autoload/timl/bootstrap.vim\n\n\" vim:set et sw=2:\n"
  },
  {
    "path": "doc/timl.txt",
    "content": "*timl.txt*  TimL\n\nAuthor:  Tim Pope <http://tpo.pe/>\nRepo:    https://github.com/tpope/timl\nLicense: EPL (http://opensource.org/licenses/eclipse-1.0.php)\n\nUSAGE                                           *timl*\n\nTimL files have an extension of \".tim\" and a |filetype| of \"timl\".  If they\nare placed in \"autoload/\" in 'runtimepath', Vim's |autoload| will load them\njust the same as \".vim\" files.\n\n                                                *:TLrepl*\n:TLrepl [ns]            Start a REPL.\n\n:source {file}          Load a TimL file.\n\n:Wepl                   In a TimL file, write, source, and start a REPL in\n                        that namespace.\n\nSYNTAX                                          *timl-syntax*\n\nIt's Lisp.  TimL files are just sequences of forms.  Evaluation essentially\nentails replacing symbols with their values and lists with the result of\ncalling the first element as function with the remaining elements as\narguments.  An informal summary of the various forms follows:\n\nNotation    Description ~\n;           linewise comment\n#!          linewise comment (for shebangs)\n#_          skip next form\nnil         |timl-nil|\nfalse       |timl-boolean|\ntrue        |timl-boolean|\n\\d...       |timl-number| (see |expr-number|)\n\\k...       |timl-symbol|\n:...        |timl-keyword|\n\"...\"       |timl-string| (see double quoted strings under |expr-string|)\n#\"...\"      |timl-regexp|\n(...)       |timl-list|\n[...]       |timl-vector|\n{...}       |timl-map|\n#{...}      |timl-set|\n#(...)      |timl-fn|\n#*symbol    |timl-funcref|\n#*[...]     |timl-array|\n#*{...}     |timl-dictionary|\n^...        |timl-metadata|\n'           |timl-quote|\n`           |timl-syntax-quote|\n~           |timl-unquote|\n~@          |timl-unquote-splicing|\n@           |g:timl#core.deref|\n\nTYPES                                           *timl-types*\n\n                                                *timl-number*\nNumbers ~\nSame as Vim. See |expr-number|.\n\n                                                *timl-strings*\nStrings ~\nSame as strings in Vim.  The literal syntax is the same as the double quoted\nstrings under |expr-string|.\n\n                                                *timl-regexps*\nRegular Expressions ~\nThere's not a proper regexp type, but #\"...\" compiles down to a string of a\nvery magic |/\\v| case sensitive |\\/C| regexp string.  Unlike with regular\nstring literals, you don't need to double your backslashes.\n\n                                                *timl-arrays*\nArrays ~\nTimL arrays are actually Vim |Lists|.  They have been rebranded arrays to\navoid confusion with the core Lisp data structure of a singly linked list.\nArrays participate in the expected collection abstractions, but be aware they\nmutate, and thus are best avoided except when dealing with interop.\n\nArrays are shown as #*[...] when printed.  The reader respects this syntax,\nbut it is preferrable to use |g:timl#core.array| to create a array.\n\n                                *timl-dictionary* *timl-dictionaries*\nDictionaries ~\nTimL dictionaries are Vim |Dictionaries|.  TimL uses dictionaries in the\nimplementation of its type system, so \"TimL dictionary\" refers to a dictionary\nthat has not been blessed as any particular type.  Dictionaries can be treated\nas maps with forced string keys.\n\nDictionaries are shown as #*{...} when printed.  The reader respects this\nsyntax, but it is preferrable to use |g:timl#core.dict| to create a\ndictionary.\n\n                                                *timl-funcrefs*\nFuncrefs ~\nTimL provides a special #*symbol syntax for creating a Vim |Funcref|.\nFuncrefs can be called like any other function: (#*bufnr \"%\").  Vim imposes\ncertain restrictions on assigning funcrefs to variables, so beware of using\nthem with |timl-set!| and |timl-def|.\n\n                                                *timl-nil*\nNil ~\nVimL has no concept of nil, so this is actually just a special singleton\nobject.  The literal form is \"nil\".\n\n                                                *timl-booleans*\nBooleans ~\nBooleans are the canonical truth values.  There's a literal for each: \"true\"\nand \"false\".  Nil and false are the only false values in TimL.  Note that in\nVimL, zero is false, and built-in Vim functions return that as their false\nvalue.  Compose with |g:timl#core.nonzero_QMARK_| if you want to use the\nresult of a built-in Vim function in a conditional.\n\n                                                *timl-symbols*\nSymbols ~\nAny sequence of identifier characters that doesn't start with a number.\nIdentifier characters include alphanumerics and the special characters\n\"-_?!*+/<>\".  \":\" and \"#\" are reserved for internal use and can be used to\nrefer to Vim variables (|b:var,| |w:var|, |t:var|, |g:var|, |v:var|).\n\nSince symbols evaluate, you'll need to |timl-quote| one if you want it as a\nvalue: 'symbol.\n\n                                                *timl-keywords*\nKeywords ~\nKeywords look like symbols preceded by a colon.  Unlike symbols, they evaluate\nto themselves, making them good |timl-map| keys.  Calling a keyword as a\nfunction tries to retrieve it from the given collection using\n|g:timl#core.get|.\n\n                                                *timl-lists*\nLists ~\nLists are linked lists under the hood, and have a syntax literal of zero or more forms enclosed in parentheses ().  Lists evaluate to a function\ncall of the first element with the remaining elements as args.  To create a\nlist value, |timl-quote| it (also prevents evaluation of elements) or use\n|g:timl#core.list|.\n\n                                                *timl-vectors*\nVectors ~\nAn ordered, indexed collection intended for random access.  Created literally\nby enclosing zero or more forms in brackets.  Evaluates to a new vector of the\nevaluation of the contained elements.\n\n                                                *timl-maps*\nMaps ~\nMaps are associative, unordered collections.  The syntax literal is {...}.\nThe definining method of a map is |g:timl#core.dissoc|.\n\n                                                *timl-sets*\nSets ~\nA set is an unordered collection of values, and can be thought of as a map\nwhere the keys and values are the same.  The syntax literal is #{...}.  The\ndefining method of a set is |g:timl#core.disj|.\n\nEVALUATION                                      *timl-evaluation*\n\nIt's Lisp.\n\nSymbols evaluate to their value in lexical scope (from let or fn) or the\ncurrent namespace.  Symbols evaluating to special forms are handled as\nexplained under |timl-special-forms|.\n\nLists evaluate to a function call.  Dictionaries evaluate their\nvalues.  Everything else evaluates to itself.\n\nSPECIAL FORMS                                   *timl-special-forms*\n\n                                                *timl-if*\n(if {cond} {then} {else}?) ~\nIf {cond} is true, evaluate {then}, else evaluate {else}.\n\n                                                *timl-do*\n(do {form} ...) ~\nEvaluate a series of forms and return the result of the last one.\n\n                                                *timl-let*\n(let [{symbol} {value} ...] {body} ...) ~\nBind the given symbols lexically for the scope of the given body.\n\n                                                *timl-fn*\n(fn {name}? [{param} ...] {body} ...) ~\n#(... % %2 %3 ... %&) ~\nCreate an anonymous function.\n\n                                                *timl-recur*\nIn tail position, re-calls the current function or |timl#core#loop| construct\nwith the given parameters.  See Clojure's documentation at\nhttp://clojure.org/special_forms#recur .\n\n                                                *timl-def*\n(def {var} {value}) ~\nDefine a variable or function.\n\n                                                *timl-set!*\n(set! {var} {value}) ~\nSet a Vim variable, in a manner similar to |:let|.  |g:var|, |b:var|, |w:var|,\n|t:var|, |v:var|, |expr-option|, and variables in the current namespace are\nsupported. >\n        (set! b:did_ftplugin 1)\n        (set! &shiftwidth 2)\n        (set! *ns* (the-ns 'user))\n<\n                                                *timl-quote*\n(quote {form}) ~\n'{form} ~\nReturn {form} unevaluated.\n\n                                                *timl-function*\n(function {form}) ~\n#*{form} ~\nReturn a |Funcref| for a built-in or user defined Vim function.  Can be called\nlike any other function.\n\n                                        *timl-try* *timl-catch* *timl-finally*\n(try {body} ... (catch {pattern} {e} {body} ...) ... (finally {body} ...) ...) ~\nWrap a set of forms in a |:try| block.  The {pattern} is a regexp to match\nthe string exception as explained under |:catch|, or can also be a Vim error\nnumber.  You can access |v:exception| and |v:throwpoint| for information about\nthe exception, or look in dictionary {e}.\n\n                                                *timl-throw*\n(throw {string}) ~\nPass the given {string} to |:throw|.\n\n                                                *timl-execute*\n(execute {string}) ~\nRun the given string with |:execute|.\n\n                                                *timl-.* *timl-dot*\n(. {dict} -{key}) ~\nRetrieve the given key of the given dict.\n\nNAMESPACES                                      *timl-namespaces* *timl-ns*\n\nNamespaces take the Clojure model and adapt it to fit the VimL |autoload|\nfeature.\n>\n        (ns foo.bar)\n        (def baz 1)\n        (in-ns 'user)\n        foo.bar/baz            ; evaluates to 1\n        (alias 'quux 'foo.bar)\n        quux/baz               ; evaluates to 1\n        (refer 'foo.bar)\n        baz                    ; evaluates to 1\n<\nYou can also use the ns macro from Clojure.\n>\n        (ns my.ns\n          (:refer-timl :exclude [+])\n          (:use timl.repl)\n          (:require [timl.file :as file]))\n<\nTimL files placed in the |autoload| directory will automatically be loaded in\nthe correct namespace.\n\n vim:tw=78:et:ft=help:norl:\n"
  },
  {
    "path": "doc/timl_core.txt",
    "content": "                                                *g:timl#core.array*\n(timl.core/array & elems)       Create a |timl-array| containing elems.\n\n                                                *g:timl#core.dict*\n(timl.core/dict map)            Convert a map to a |timl-dictionary|.\n(timl.core/dict keyvals)        Create a |timl-dictionary| from keyvals.\n(timl.core/dict & keyvals)      Create a |timl-dictionary| from keyvals.\n\n vim:tw=78:sw=8:et:ft=help:norl:\n"
  },
  {
    "path": "epl-v10.html",
    "content": "<?xml version=\"1.0\" encoding=\"ISO-8859-1\" ?>\n<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">\n<html xmlns=\"http://www.w3.org/1999/xhtml\">\n\n<head>\n<meta http-equiv=\"Content-Type\" content=\"text/html; charset=ISO-8859-1\" />\n<title>Eclipse Public License - Version 1.0</title>\n<style type=\"text/css\">\n  body {\n    size: 8.5in 11.0in;\n    margin: 0.25in 0.5in 0.25in 0.5in;\n    tab-interval: 0.5in;\n    }\n  p {\n    margin-left: auto;\n    margin-top:  0.5em;\n    margin-bottom: 0.5em;\n    }\n  p.list {\n    margin-left: 0.5in;\n    margin-top:  0.05em;\n    margin-bottom: 0.05em;\n    }\n  </style>\n\n</head>\n\n<body lang=\"EN-US\">\n\n<p align=center><b>Eclipse Public License - v 1.0</b></p>\n\n<p>THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF THIS ECLIPSE\nPUBLIC LICENSE (&quot;AGREEMENT&quot;). ANY USE, REPRODUCTION OR\nDISTRIBUTION OF THE PROGRAM CONSTITUTES RECIPIENT'S ACCEPTANCE OF THIS\nAGREEMENT.</p>\n\n<p><b>1. DEFINITIONS</b></p>\n\n<p>&quot;Contribution&quot; means:</p>\n\n<p class=\"list\">a) in the case of the initial Contributor, the initial\ncode and documentation distributed under this Agreement, and</p>\n<p class=\"list\">b) in the case of each subsequent Contributor:</p>\n<p class=\"list\">i) changes to the Program, and</p>\n<p class=\"list\">ii) additions to the Program;</p>\n<p class=\"list\">where such changes and/or additions to the Program\noriginate from and are distributed by that particular Contributor. A\nContribution 'originates' from a Contributor if it was added to the\nProgram by such Contributor itself or anyone acting on such\nContributor's behalf. Contributions do not include additions to the\nProgram which: (i) are separate modules of software distributed in\nconjunction with the Program under their own license agreement, and (ii)\nare not derivative works of the Program.</p>\n\n<p>&quot;Contributor&quot; means any person or entity that distributes\nthe Program.</p>\n\n<p>&quot;Licensed Patents&quot; mean patent claims licensable by a\nContributor which are necessarily infringed by the use or sale of its\nContribution alone or when combined with the Program.</p>\n\n<p>&quot;Program&quot; means the Contributions distributed in accordance\nwith this Agreement.</p>\n\n<p>&quot;Recipient&quot; means anyone who receives the Program under\nthis Agreement, including all Contributors.</p>\n\n<p><b>2. GRANT OF RIGHTS</b></p>\n\n<p class=\"list\">a) Subject to the terms of this Agreement, each\nContributor hereby grants Recipient a non-exclusive, worldwide,\nroyalty-free copyright license to reproduce, prepare derivative works\nof, publicly display, publicly perform, distribute and sublicense the\nContribution of such Contributor, if any, and such derivative works, in\nsource code and object code form.</p>\n\n<p class=\"list\">b) Subject to the terms of this Agreement, each\nContributor hereby grants Recipient a non-exclusive, worldwide,\nroyalty-free patent license under Licensed Patents to make, use, sell,\noffer to sell, import and otherwise transfer the Contribution of such\nContributor, if any, in source code and object code form. This patent\nlicense shall apply to the combination of the Contribution and the\nProgram if, at the time the Contribution is added by the Contributor,\nsuch addition of the Contribution causes such combination to be covered\nby the Licensed Patents. The patent license shall not apply to any other\ncombinations which include the Contribution. No hardware per se is\nlicensed hereunder.</p>\n\n<p class=\"list\">c) Recipient understands that although each Contributor\ngrants the licenses to its Contributions set forth herein, no assurances\nare provided by any Contributor that the Program does not infringe the\npatent or other intellectual property rights of any other entity. Each\nContributor disclaims any liability to Recipient for claims brought by\nany other entity based on infringement of intellectual property rights\nor otherwise. As a condition to exercising the rights and licenses\ngranted hereunder, each Recipient hereby assumes sole responsibility to\nsecure any other intellectual property rights needed, if any. For\nexample, if a third party patent license is required to allow Recipient\nto distribute the Program, it is Recipient's responsibility to acquire\nthat license before distributing the Program.</p>\n\n<p class=\"list\">d) Each Contributor represents that to its knowledge it\nhas sufficient copyright rights in its Contribution, if any, to grant\nthe copyright license set forth in this Agreement.</p>\n\n<p><b>3. REQUIREMENTS</b></p>\n\n<p>A Contributor may choose to distribute the Program in object code\nform under its own license agreement, provided that:</p>\n\n<p class=\"list\">a) it complies with the terms and conditions of this\nAgreement; and</p>\n\n<p class=\"list\">b) its license agreement:</p>\n\n<p class=\"list\">i) effectively disclaims on behalf of all Contributors\nall warranties and conditions, express and implied, including warranties\nor conditions of title and non-infringement, and implied warranties or\nconditions of merchantability and fitness for a particular purpose;</p>\n\n<p class=\"list\">ii) effectively excludes on behalf of all Contributors\nall liability for damages, including direct, indirect, special,\nincidental and consequential damages, such as lost profits;</p>\n\n<p class=\"list\">iii) states that any provisions which differ from this\nAgreement are offered by that Contributor alone and not by any other\nparty; and</p>\n\n<p class=\"list\">iv) states that source code for the Program is available\nfrom such Contributor, and informs licensees how to obtain it in a\nreasonable manner on or through a medium customarily used for software\nexchange.</p>\n\n<p>When the Program is made available in source code form:</p>\n\n<p class=\"list\">a) it must be made available under this Agreement; and</p>\n\n<p class=\"list\">b) a copy of this Agreement must be included with each\ncopy of the Program.</p>\n\n<p>Contributors may not remove or alter any copyright notices contained\nwithin the Program.</p>\n\n<p>Each Contributor must identify itself as the originator of its\nContribution, if any, in a manner that reasonably allows subsequent\nRecipients to identify the originator of the Contribution.</p>\n\n<p><b>4. COMMERCIAL DISTRIBUTION</b></p>\n\n<p>Commercial distributors of software may accept certain\nresponsibilities with respect to end users, business partners and the\nlike. While this license is intended to facilitate the commercial use of\nthe Program, the Contributor who includes the Program in a commercial\nproduct offering should do so in a manner which does not create\npotential liability for other Contributors. Therefore, if a Contributor\nincludes the Program in a commercial product offering, such Contributor\n(&quot;Commercial Contributor&quot;) hereby agrees to defend and\nindemnify every other Contributor (&quot;Indemnified Contributor&quot;)\nagainst any losses, damages and costs (collectively &quot;Losses&quot;)\narising from claims, lawsuits and other legal actions brought by a third\nparty against the Indemnified Contributor to the extent caused by the\nacts or omissions of such Commercial Contributor in connection with its\ndistribution of the Program in a commercial product offering. The\nobligations in this section do not apply to any claims or Losses\nrelating to any actual or alleged intellectual property infringement. In\norder to qualify, an Indemnified Contributor must: a) promptly notify\nthe Commercial Contributor in writing of such claim, and b) allow the\nCommercial Contributor to control, and cooperate with the Commercial\nContributor in, the defense and any related settlement negotiations. The\nIndemnified Contributor may participate in any such claim at its own\nexpense.</p>\n\n<p>For example, a Contributor might include the Program in a commercial\nproduct offering, Product X. That Contributor is then a Commercial\nContributor. If that Commercial Contributor then makes performance\nclaims, or offers warranties related to Product X, those performance\nclaims and warranties are such Commercial Contributor's responsibility\nalone. Under this section, the Commercial Contributor would have to\ndefend claims against the other Contributors related to those\nperformance claims and warranties, and if a court requires any other\nContributor to pay any damages as a result, the Commercial Contributor\nmust pay those damages.</p>\n\n<p><b>5. NO WARRANTY</b></p>\n\n<p>EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, THE PROGRAM IS\nPROVIDED ON AN &quot;AS IS&quot; BASIS, WITHOUT WARRANTIES OR CONDITIONS\nOF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION,\nANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY\nOR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is solely\nresponsible for determining the appropriateness of using and\ndistributing the Program and assumes all risks associated with its\nexercise of rights under this Agreement , including but not limited to\nthe risks and costs of program errors, compliance with applicable laws,\ndamage to or loss of data, programs or equipment, and unavailability or\ninterruption of operations.</p>\n\n<p><b>6. DISCLAIMER OF LIABILITY</b></p>\n\n<p>EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, NEITHER RECIPIENT\nNOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY DIRECT, INDIRECT,\nINCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING\nWITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND ON ANY THEORY OF\nLIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING\nNEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OR\nDISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED\nHEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.</p>\n\n<p><b>7. GENERAL</b></p>\n\n<p>If any provision of this Agreement is invalid or unenforceable under\napplicable law, it shall not affect the validity or enforceability of\nthe remainder of the terms of this Agreement, and without further action\nby the parties hereto, such provision shall be reformed to the minimum\nextent necessary to make such provision valid and enforceable.</p>\n\n<p>If Recipient institutes patent litigation against any entity\n(including a cross-claim or counterclaim in a lawsuit) alleging that the\nProgram itself (excluding combinations of the Program with other\nsoftware or hardware) infringes such Recipient's patent(s), then such\nRecipient's rights granted under Section 2(b) shall terminate as of the\ndate such litigation is filed.</p>\n\n<p>All Recipient's rights under this Agreement shall terminate if it\nfails to comply with any of the material terms or conditions of this\nAgreement and does not cure such failure in a reasonable period of time\nafter becoming aware of such noncompliance. If all Recipient's rights\nunder this Agreement terminate, Recipient agrees to cease use and\ndistribution of the Program as soon as reasonably practicable. However,\nRecipient's obligations under this Agreement and any licenses granted by\nRecipient relating to the Program shall continue and survive.</p>\n\n<p>Everyone is permitted to copy and distribute copies of this\nAgreement, but in order to avoid inconsistency the Agreement is\ncopyrighted and may only be modified in the following manner. The\nAgreement Steward reserves the right to publish new versions (including\nrevisions) of this Agreement from time to time. No one other than the\nAgreement Steward has the right to modify this Agreement. The Eclipse\nFoundation is the initial Agreement Steward. The Eclipse Foundation may\nassign the responsibility to serve as the Agreement Steward to a\nsuitable separate entity. Each new version of the Agreement will be\ngiven a distinguishing version number. The Program (including\nContributions) may always be distributed subject to the version of the\nAgreement under which it was received. In addition, after a new version\nof the Agreement is published, Contributor may elect to distribute the\nProgram (including its Contributions) under the new version. Except as\nexpressly stated in Sections 2(a) and 2(b) above, Recipient receives no\nrights or licenses to the intellectual property of any Contributor under\nthis Agreement, whether expressly, by implication, estoppel or\notherwise. All rights in the Program not expressly granted under this\nAgreement are reserved.</p>\n\n<p>This Agreement is governed by the laws of the State of New York and\nthe intellectual property laws of the United States of America. No party\nto this Agreement will bring a legal action under this Agreement more\nthan one year after the cause of action arose. Each party waives its\nrights to a jury trial in any resulting litigation.</p>\n\n</body>\n\n</html>\n"
  },
  {
    "path": "ftplugin/timl.tim",
    "content": "(ns ftplugin.timl)\n(use 'timl.ftplugin)\n(include-guard)\n\n(setlocal comments=\":; ,:;;; ,:;; \" commentstring=\"; %s\")\n(setlocal define=\"^\\\\s*(def\\\\k*\")\n(setlocal formatoptions+=cql)\n(setlocal omnifunc=timl#interactive#omnicomplete)\n\n(execute \"nnoremap <silent><buffer> cp :set opfunc=timl#interactive#eval_opfunc<CR>g@\")\n(execute \"nnoremap <silent><buffer> cpp :<C-U>call timl#interactive#eval_opfunc(v:count)<CR>\")\n(execute \"nnoremap <buffer> K :execute 'help' ftplugin#timl#cursor_keyword()<CR>\")\n(defn cursor-keyword []\n  (let [kw (#*expand \"<cword>\")\n        ns (the-ns (symbol (#*timl#interactive#ns_for_cursor)))]\n    (cond\n      (re-find \"^#\\\\*\" kw) (str (subs kw 2) \"()\")\n      (re-find \"^&\" kw)    (str \"'\" (subs kw 1) \"'\")\n      (special-symbol?     (symbol kw)) (str \"timl-\" kw)\n      (ns-resolve ns (symbol kw)) (. (ns-resolve ns (symbol kw)) munged)\n      :else                kw)))\n"
  },
  {
    "path": "indent/timl.tim",
    "content": "(ns indent.timl)\n(execute \"runtime! indent/clojure.vim\")\n"
  },
  {
    "path": "plugin/timl.vim",
    "content": "\" timl.vim - TimL\n\" Maintainer:   Tim Pope <code@tpope.net>\n\nif exists(\"g:loaded_timl\") || v:version < 700 || &cp\n  finish\nendif\nlet g:loaded_timl = 1\n\nif &maxfuncdepth == 100\n  set maxfuncdepth=200\nendif\n\naugroup timl\n  autocmd!\n  autocmd BufNewFile,BufReadPost *.tim set filetype=timl\n  autocmd BufNewFile,BufReadPost *\n        \\ if getline(1) =~# '^#!' && getline(2) =~# ';.*\\<TL' |\n        \\   set filetype=timl |\n        \\ endif\n  autocmd FileType timl command! -buffer -bar Wepl\n        \\ update |\n        \\ execute 'TLsource %' |\n        \\ set filetype=timl |\n        \\ redraw! |\n        \\ call timl#interactive#repl(timl#interactive#ns_for_cursor())\n  autocmd FileType * call s:load_filetype(expand('<amatch>'))\n  autocmd SourceCmd *.tim call timl#loader#source(expand(\"<amatch>\"))\n  autocmd FuncUndefined *#* call s:autoload(expand('<amatch>'))\n  autocmd VimEnter * nested\n        \\ if exists('s:source') |\n        \\   redraw! |\n        \\   execute 'TLsource '.s:source |\n        \\   unlet! s:source |\n        \\ endif\naugroup END\n\ncommand! -bar -nargs=?                    TLrepl :execute timl#interactive#repl(<f-args>)\ncommand! -bar                          TLscratch :execute timl#interactive#scratch()\ncommand! -nargs=1 -complete=expression TLinspect :echo timl#printer#string(<args>)\ncommand! -nargs=1 -complete=customlist,timl#interactive#input_complete TLeval\n      \\ try |\n      \\    echo timl#rep(<q-args>) |\n      \\ catch |\n      \\    unlet! g:timl#core._STAR_e |\n      \\    let g:timl#core._STAR_e = timl#exception#build(v:exception, v:throwpoint) |\n      \\    echoerr v:exception |\n      \\ endtry\ncommand! -bar TLcopen :call timl#interactive#copen(get(g:, 'timl#core#_STAR_e', []))\ncommand! -bang -nargs=? -complete=file TLsource\n      \\ if has('vim_starting') |\n      \\   let s:source = <q-args> |\n      \\ else |\n      \\   call timl#loader#source(expand(empty(<q-args>) ? '%' : <q-args>)) |\n      \\ endif\n\nfunction! s:load_filetype(ft) abort\n  if empty(a:ft)\n    return ''\n  endif\n  let ft = split(a:ft)[0]\n  for kind in ['ftplugin', 'indent']\n    for file in findfile(kind.'/'.ft.'.tim', &rtp, -1)\n      try\n        call timl#loader#source(file)\n      catch\n        unlet! g:timl#core._STAR_e\n        let g:timl#core._STAR_e = timl#exception#build(v:exception, v:throwpoint) |\n        echohl WarningMSG\n        echomsg v:exception\n        echohl NONE\n      endtry\n    endfor\n  endfor\nendfunction\n\nif !exists('g:timl_requires')\n  let g:timl_requires = {}\nendif\n\nfunction! s:file4ns(ns) abort\n  if !exists('s:tempdir')\n    let s:tempdir = tempname()\n  endif\n  let file = s:tempdir . '/' . a:ns . '.vim'\n  if !isdirectory(fnamemodify(file, ':h'))\n    call mkdir(fnamemodify(file, ':h'), 'p')\n  endif\n  return file\nendfunction\n\nfunction! s:autoload(function) abort\n  let var = matchstr(a:function, '.*\\ze#')\n  let ns = tr(var, '#_', '.-')\n  let base = tr(ns, '.-', '/_')\n\n  if !has_key(g:timl_requires, ns)\n    if !empty(findfile('autoload/'.base.'.vim'))\n      let g:timl_requires[ns] = 1\n    else\n      for file in findfile('autoload/'.base.'.tim', &rtp, -1)\n        call timl#loader#source(file)\n        let g:timl_requires[ns] = 1\n        break\n      endfor\n    endif\n  endif\n\n  let key = matchstr(a:function, '.*#\\zs.*')\n  if has_key(g:, var) && has_key(g:{var}, key) && timl#type#canp(g:{var}[key], g:timl#core.call)\n    let body = [\"function \".a:function.\"(...)\",\n          \\ \"  return timl#call(g:\".var.\".\".key.\", a:000)\",\n          \\ \"endfunction\"]\n    let file = s:file4ns(base)\n    call writefile(body, file)\n    exe 'source '.file\n  endif\nendfunction\n"
  },
  {
    "path": "syntax/timl.vim",
    "content": "\" Vim syntax file\n\" Language:     TimL\n\" Maintainer:   Tim Pope <code@tpope.net>\n\" Filenames:    *.timl\n\nif exists(\"b:current_syntax\")\n  finish\nendif\n\nsyntax sync minlines=100\n\nif !exists('s:functions')\n  let s:file = readfile(findfile('syntax/vim.vim', &rtp))\n  let s:options = split(join(map(filter(copy(s:file), 'v:val =~# \"^syn keyword vimOption contained\\t[^in]\"'), 'substitute(v:val, \"^.*\\t\", \"\", \"g\")'), ' '), '\\s\\+')\n  let s:functions = split(join(map(filter(copy(s:file), 'v:val =~# \"^syn keyword vimFuncName contained\\t[^in]\"'), 'substitute(v:val, \"^.*\\t\", \"\", \"g\")'), ' '), ' ')\nendif\n\nsetl iskeyword+=?,!,#,$,%,&,*,+,.,/,<,>,:,=,45\nlet b:syntax_ns_str = timl#interactive#ns_for_cursor(0)\nlet b:syntax_vars = keys(timl#namespace#map(timl#namespace#find(b:syntax_ns_str)))\n\nlet b:current_syntax = \"timl\"\n\nfunction! s:syn_keyword(group, keywords) abort\n  if !empty(a:keywords)\n    exe 'syntax keyword '.a:group.' '.join(a:keywords, ' ')\n  endif\nendfunction\ncall s:syn_keyword('timlSymbol', b:syntax_vars)\ncall s:syn_keyword('timlDefine', filter(copy(b:syntax_vars), 'v:val =~# \"^def\\\\%(ault\\\\)\\\\@!\"'))\nsyntax keyword timlSpecialParam & &form &env\n\nsyntax keyword timlConditional if\nsyntax keyword timlDefine def deftype* set! declare\nsyntax keyword timlRepeat loop recur\nsyntax keyword timlStatement do let fn . execute\nsyntax keyword timlSpecial let* fn* var function\nsyntax keyword timlException try catch finally throw\n\nsyntax keyword timlConstant nil\nsyntax keyword timlBoolean false true\nsyntax match timlKeyword \":\\k\\+\"\nsyntax match timlCharacter \"\\\\\\%(space\\|tab\\|newline\\|return\\|formfeed\\|backspace\\|.\\)\"\nsyntax match timlNumber \"\\<[-+]\\=0\\o\\+\\>\"\nsyntax match timlNumber \"\\<[-+]\\=0x\\x\\+\\>\"\nsyntax match timlNumber \"\\<[-+]\\=\\%([1-9]\\d*\\|0\\)\\%(\\.\\d\\+\\)\\=\\%([Ee]\\d\\+\\)\\=\\>\"\nsyntax keyword timlNumber Infinity -Infinity +Infinity NaN\nsyntax region timlString start=/\"/ skip=/\\\\\\\\\\|\\\\\"/ end=/\"/ contains=timlStringEscape,@Spell\nsyntax match timlStringEscape \"\\v\\\\%([uU]\\x{4}|[0-3]\\o{2}|\\o\\{1,2}|[xX]\\x{1,2}|[befnrt\\\\\"]|\\<[[:alnum:]-]+\\>)\" contained\nsyntax region timlRegexp start=/#\"/ skip=/\\\\\\\\\\|\\\\\"/ end=/\"/ contains=timlRegexpSpecial\n\nsyntax match timlFuncref \"\\<#\\*\" nextgroup=timlVimFunction\nsyntax match timlVarref \"\\<#'\" nextgroup=timlSymbol\nsyntax match timlQuote \"'\"\nsyntax match timlSyntaxQuote \"`\"\nsyntax match timlUnquote \"\\~@\\=\"\nsyntax match timlDeref \"@\"\nsyntax match timlMeta \"\\^\"\n\nsyntax region timlList matchgroup=timlGroup start=\"(\" end=\")\" contains=TOP,@Spell\nsyntax region timlVector matchgroup=timlGroup start=\"\\[\" end=\"]\" contains=TOP,@Spell\nsyntax region timlMap matchgroup=timlGroup start=\"{\" end=\"}\" contains=TOP,@Spell\nsyntax region timlSet matchgroup=timlGroup start=\"#{\" end=\"}\" contains=TOP,@Spell\nsyntax region timlFn matchgroup=timlGroup start=\"#(\" end=\")\" contains=TOP,@Spell\nsyntax match timlSymbol '\\<%[1-9]\\d*\\>'\nsyntax match timlSymbol '\\<%&\\=\\>'\n\nsyntax match timlComment \"\\<#_\"\nsyntax match timlComment \";.*$\"\nsyntax match timlComment \";= \"\nsyntax match timlComment \";! \" nextgroup=timlError\nsyntax match timlError \".*$\" contained\nsyntax match timlComment \"#!.*$\"\nsyntax match timlComment \";;.*$\" contains=@Spell\n\ncall s:syn_keyword('timlVimOption', map(copy(s:options), \"'&'.v:val\"))\ncall s:syn_keyword('timlVimOption', map(copy(s:options), \"'&l:'.v:val\"))\ncall s:syn_keyword('timlVimOption', map(copy(s:options), \"'&g:'.v:val\"))\nexe 'syn match timlVimFunction contained \"\\%('.join(s:functions, '\\|').'\\)\\>\"'\nsyntax match timlVar '\\<[glabwtv]:\\k\\+\\>'\n\nhi def link timlDefine Define\nhi def link timlSymbol Identifier\nhi def link timlSpecialParam Special\nhi def link timlConditional Conditional\nhi def link timlRepeat Repeat\nhi def link timlStatement Statement\nhi def link timlException Exception\nhi def link timlBoolean Boolean\nhi def link timlConstant Constant\nhi def link timlKeyword Constant\nhi def link timlCharacter Character\nhi def link timlString String\nhi def link timlRegexp String\nhi def link timlStringEscape Special\nhi def link timlRegexpSpecial Special\nhi def link timlNumber Number\nhi def link timlSpecial Special\nhi def link timlFuncref Special\nhi def link timlVarref Special\nhi def link timlQuote Special\nhi def link timlSyntaxQuote Special\nhi def link timlUnquote Special\nhi def link timlDeref Special\nhi def link timlMeta Special\nhi def link timlGroup Special\nhi def link timlComment Comment\nhi def link timlError WarningMsg\n\nhi def link timlVimFunction Function\nhi def link timlVimOption Type\n\n\" vim:set et sw=2:\n"
  },
  {
    "path": "test/timl/core_coll_test.tim",
    "content": "(ns timl.core-coll-test)\n(use 'timl.test)\n\n(assert (= 3 (count (list 1 2 3))))\n(assert (= 1 (count (dict \"a\" \"b\"))))\n\n(assert (= (list) (empty (list 1 2 3))))\n(assert (= (dict) (empty (dict \"a\" \"b\"))))\n(assert (= \"\" (empty \"string\")))\n(assert (nil? (empty 'symbol)))\n(assert (nil? (empty 0)))\n\n(assert (= (list 2 3 4) (map (partial + 1) (list 1 2 3))))\n(assert (= (list \"a\") (map first (dict \"a\" \"b\"))))\n\n(assert (= 6 (reduce + (list 1 2 3))))\n"
  },
  {
    "path": "test/timl/core_test.tim",
    "content": "(ns timl.core-test)\n(use 'timl.test)\n\n(let [sentinel (dict)]\n  (assert (identical? sentinel ((constantly sentinel)))))\n\n(assert (= \"42\\n\" (with-out-str (println 42))))\n"
  },
  {
    "path": "test/timl/number_test.tim",
    "content": "(ns timl.number-test)\n(use 'timl.test)\n\n(assert (number? 3))\n(assert (number? 3.0))\n(assert (not (number? \"\")))\n(assert (integer? 3))\n(assert (not (integer? 3.0)))\n(assert (not (integer? \"\")))\n(assert (not (float? 3)))\n(assert (float? 3.0))\n(assert (not (integer? \"\")))\n\n(assert (= 0 (+)))\n(assert (= 1 (+ 1)))\n(assert (= 3 (+ 1 2)))\n(assert (= 6 (+ 1 2 3)))\n(assert (= 4 (inc 3)))\n\n(assert (= -1 (- 1)))\n(assert (= 0 (- 3 1 2)))\n(assert (= 2 (dec 3)))\n\n(assert (= 1 (*)))\n(assert (= 6 (* 1 2 3)))\n\n(assert (= 0 (/ 2)))\n(assert (= 0.5 (/ 2.0)))\n(assert (= 0.5 (/ 1 2.0)))\n(assert (= 0.25 (/ 1 2.0 2.0)))\n\n(assert (= 1 (rem 4 3)))\n(assert (= -1 (rem -4 3)))\n(assert (= 1 (mod 4 3)))\n(assert (= 2 (mod -4 3)))\n(assert (= 0 (mod 0 3)))\n(assert (= -2 (mod 4 -3)))\n(assert (= 1.0 (quot 3.0 2)))\n\n(assert (= 7 (max 3 7 2 4)))\n(assert (= 2 (min 3 7 2 4)))\n\n(assert (= -1 (bit-not 0)))\n(assert (= 5 (bit-xor 7 3 1)))\n(assert (= 4 (bit-and 7 6 5)))\n(assert (= 7 (bit-or 1 2 4)))\n(assert (= 6 (bit-and-not 7 1 8)))\n(assert (= 8 (bit-shift-left 1 3)))\n(assert (= 1 (bit-shift-right 8 3)))\n(assert (= 3 (bit-flip 1 1)))\n(assert (= 3 (bit-set 1 1)))\n(assert (= 1 (bit-clear 3 1)))\n(assert (bit-test 3 1))\n(assert (not (bit-test 5 1)))\n\n(assert (= nil (not-negative -1)))\n(assert (= 0 (not-negative 0)))\n(assert (zero? 0))\n(assert (not (zero? 1)))\n(assert (nonzero? 1))\n(assert (not (nonzero? 0)))\n(assert (even? 2))\n(assert (not (even? 3)))\n(assert (odd? 3))\n(assert (not (odd? 2)))\n\n(assert (> 3 2 1))\n(assert (not (> 3 2 2)))\n(assert (< 1 2 3))\n(assert (not (< 1 2 2)))\n(assert (>= 3 2 2))\n(assert (not (>= 3 1 2)))\n(assert (<= 1 2 2))\n(assert (not (< 1 3 2)))\n(assert (== 0 0.0 0))\n(assert (not (== 0 0.0 1)))\n\n(defn fact [x]\n  (loop [n x\n         f 1]\n    (if (<= n 1) f (recur (dec n) (* f n)))))\n\n(defn fib [n]\n  (first\n    (loop [xs [1 0]]\n      (if (< (count xs) n)\n        (recur (cons (+ (first xs) (second xs)) xs))\n        xs))))\n\n(assert (= 120 (fact 5)))\n"
  }
]