Commits

Meikel Brandmeyer committed 75e9069

Split into subprojects for future extensions

Comments (0)

Files changed (137)

Makefile

-# This Makefile has only been tested on linux.  It uses
-# MinGW32 to cross-compile for windows.  To install and
-# configure MinGW32 on linux, see
-# http://www.mingw.org/MinGWiki/index.php/BuildMingwCross
-#
-# Marty Lamb
-
-CC=gcc
-CFLAGS=-Wall -pedantic -s -O3
-
-# Special library requirements
-# Default:
-LIBS=
-
-# OpenSolaris 2009.06
-#LIBS=-lsocket -lnsl
-
-# Windows
-#LIBS=-lwsock32
-
-ng: ngclient/ng.c
-	@echo "Building ng client.  To build a Windows binary, type 'make ng.exe'"
-	${CC} ${CFLAGS} ${LIBS} -o ng ngclient/ng.c
-
-clean:
-	@echo "If you have a Windows binary, 'make clean' won't delete it."
-	@echo "You must remove this manually.  Most users won't have MinGW"
-	@echo "installed - so I'd rather not delete something they can't rebuild."
-	rm ng
-#	rm ng.exe
 * For Gradle (with Clojuresque):
   
       dependencies {
-          development 'vimclojure:vimclojure:<version>'
+          development 'vimclojure:server:<version>'
       }
   
 * For Leiningen:
   
       (defproject …
         :dev-dependencies […
-                           [vimclojure "<version>"]
+                           [vimclojure/server "<version>"]
                            …])
   
 * For Ivy:
   
-      <dependency org="vimclojure" name="vimclojure" rev="<version>"/>
+      <dependency org="vimclojure" name="server" rev="<version>"/>
   
 * For Maven:
   
         <dependency>
           <groupId>vimclojure</groupId>
-          <artifactId>vimclojure</artifactId>
+          <artifactId>server</artifactId>
           <version><version></version>
         </dependency>
   
 
 For manual download:
-http://clojars.org/repo/vimclojure/vimclojure/<version>/vimclojure-<version>.jar
+http://clojars.org/repo/vimclojure/server/<version>/server-<version>.jar
 
 There are also launcher scripts included in the vimclojure/bin subdirectory
 based on Stephen C. Gilardi's clj-env-dir launcher. See information on how

autoload/vimclojure.vim

-" Part of Vim filetype plugin for Clojure
-" Language:     Clojure
-" Maintainer:   Meikel Brandmeyer <mb@kotka.de>
-
-let s:save_cpo = &cpo
-set cpo&vim
-
-function! vimclojure#WarnDeprecated(old, new)
-	echohl WarningMsg
-	echomsg a:old . " is deprecated! Use " . a:new . "!"
-	echomsg "eg. let " . a:new . " = <desired value here>"
-	echohl None
-endfunction
-
-" Configuration
-if !exists("g:vimclojure#HighlightBuiltins")
-	if exists("g:clj_highlight_builtins")
-		call vimclojure#WarnDeprecated("g:clj_highlight_builtins",
-					\ "vimclojure#HighlightBuiltins")
-		let vimclojure#HighlightBuiltins = g:clj_highlight_builtins
-	else
-		let vimclojure#HighlightBuiltins = 1
-	endif
-endif
-
-if exists("g:clj_highlight_contrib")
-	echohl WarningMsg
-	echomsg "clj_highlight_contrib is deprecated! It's removed without replacement!"
-	echohl None
-endif
-
-if !exists("g:vimclojure#DynamicHighlighting")
-	if exists("g:clj_dynamic_highlighting")
-		call vimclojure#WarnDeprecated("g:clj_dynamic_highlighting",
-					\ "vimclojure#DynamicHighlighting")
-		let vimclojure#DynamicHighlighting = g:clj_dynamic_highlighting
-	else
-		let vimclojure#DynamicHighlighting = 0
-	endif
-endif
-
-if !exists("g:vimclojure#ParenRainbow")
-	if exists("g:clj_paren_rainbow")
-		call vimclojure#WarnDeprecated("g:clj_paren_rainbow",
-					\ "vimclojure#ParenRainbow")
-		let vimclojure#ParenRainbow = g:clj_paren_rainbow
-	else
-		let vimclojure#ParenRainbow = 0
-	endif
-endif
-
-if !exists("g:vimclojure#WantNailgun")
-	if exists("g:clj_want_gorilla")
-		call vimclojure#WarnDeprecated("g:clj_want_gorilla",
-					\ "vimclojure#WantNailgun")
-		let vimclojure#WantNailgun = g:clj_want_gorilla
-	else
-		let vimclojure#WantNailgun = 0
-	endif
-endif
-
-if !exists("g:vimclojure#UseErrorBuffer")
-	let vimclojure#UseErrorBuffer = 1
-endif
-
-function! vimclojure#ReportError(msg)
-	if g:vimclojure#UseErrorBuffer
-		let buf = g:vimclojure#ResultBuffer.New()
-		call buf.showText(a:msg)
-		wincmd p
-	else
-		echoerr substitute(a:msg, '\n\(\t\?\)', ' ', 'g')
-	endif
-endfunction
-
-function! vimclojure#SynIdName()
-	return synIDattr(synID(line("."), col("."), 0), "name")
-endfunction
-
-function! vimclojure#WithSaved(closure)
-	let v = a:closure.get(a:closure.tosafe)
-	try
-		let r = a:closure.f()
-	finally
-		call a:closure.set(a:closure.tosafe, v)
-	endtry
-	return r
-endfunction
-
-function! vimclojure#WithSavedPosition(closure)
-	let a:closure['tosafe'] = "."
-	let a:closure['get'] = function("getpos")
-	let a:closure['set'] = function("setpos")
-	return vimclojure#WithSaved(a:closure)
-endfunction
-
-function! vimclojure#WithSavedRegister(closure)
-	let a:closure['get'] = function("getreg")
-	let a:closure['set'] = function("setreg")
-	return vimclojure#WithSaved(a:closure)
-endfunction
-
-function! vimclojure#WithSavedOption(closure)
-	function a:closure.get(option)
-		execute "let val = &" . a:option
-		return val
-	endfunction
-
-	function a:closure.set(option, value)
-		execute "let &" . a:option . " = a:value"
-	endfunction
-
-	return vimclojure#WithSaved(a:closure)
-endfunction
-
-function! vimclojure#Yank(r, how)
-	let closure = {'tosafe': a:r, 'yank': a:how}
-
-	function closure.f() dict
-		silent execute self.yank
-		return getreg(self.tosafe)
-	endfunction
-
-	return vimclojure#WithSavedRegister(closure)
-endfunction
-
-function! vimclojure#EscapePathForOption(path)
-	let path = fnameescape(a:path)
-
-	" Hardcore escapeing of whitespace...
-	let path = substitute(path, '\', '\\\\', 'g')
-	let path = substitute(path, '\ ', '\\ ', 'g')
-
-	return path
-endfunction
-
-function! vimclojure#AddPathToOption(path, option)
-	let path = vimclojure#EscapePathForOption(a:path)
-	execute "setlocal " . a:option . "+=" . path
-endfunction
-
-function! vimclojure#AddCompletions(ns)
-	let completions = split(globpath(&rtp, "ftplugin/clojure/completions-" . a:ns . ".txt"), '\n')
-	if completions != []
-		call vimclojure#AddPathToOption('k' . completions[0], 'complete')
-	endif
-endfunction
-
-" Nailgun part:
-function! vimclojure#ExtractSexpr(toplevel)
-	let closure = { "flag" : (a:toplevel ? "r" : "") }
-
-	function closure.f() dict
-		if searchpairpos('(', '', ')', 'bW' . self.flag,
-					\ 'vimclojure#SynIdName() !~ "clojureParen\\d"') != [0, 0]
-			return vimclojure#Yank('l', 'normal! "ly%')
-		end
-		return ""
-	endfunction
-
-	return vimclojure#WithSavedPosition(closure)
-endfunction
-
-function! vimclojure#BufferName()
-	let file = expand("%")
-	if file == ""
-		let file = "UNNAMED"
-	endif
-	return file
-endfunction
-
-" Key mappings and Plugs
-function! vimclojure#MakePlug(mode, plug, f, args)
-	execute a:mode . "noremap <Plug>Clojure" . a:plug
-				\ . " :call " . a:f . "(" . a:args . ")<CR>"
-endfunction
-
-function! vimclojure#MakeProtectedPlug(mode, plug, f, args)
-	execute a:mode . "noremap <Plug>Clojure" . a:plug
-				\ . " :call vimclojure#ProtectedPlug(function(\""
-				\ . a:f . "\"), [ " . a:args . " ])<CR>"
-endfunction
-
-function! vimclojure#MapPlug(mode, keys, plug)
-	if !hasmapto("<Plug>Clojure" . a:plug)
-		execute a:mode . "map <buffer> <unique> <silent> <LocalLeader>" . a:keys
-					\ . " <Plug>Clojure" . a:plug
-	endif
-endfunction
-
-function! vimclojure#MapCommandPlug(mode, keys, plug)
-	if exists("b:vimclojure_namespace")
-		call vimclojure#MapPlug(a:mode, a:keys, a:plug)
-	elseif g:vimclojure#WantNailgun == 1
-		let msg = ':call vimclojure#ReportError("VimClojure could not initialise the server connection.\n'
-					\ . 'That means you will not be able to use the interactive features.\n'
-					\ . 'Reasons might be that the server is not running or that there is\n'
-					\ . 'some trouble with the classpath.\n\n'
-					\ . 'VimClojure will *not* start the server for you or handle the classpath.\n'
-					\ . 'There is a plethora of tools like ivy, maven, gradle and leiningen,\n'
-					\ . 'which do this better than VimClojure could ever do it.")'
-		execute a:mode . "map <buffer> <silent> <LocalLeader>" . a:keys
-					\ . " " . msg . "<CR>"
-	endif
-endfunction
-
-if !exists("*vimclojure#ProtectedPlug")
-	function vimclojure#ProtectedPlug(f, args)
-		try
-			return call(a:f, a:args)
-		catch /.*/
-			call vimclojure#ReportError(v:exception)
-		endtry
-	endfunction
-endif
-
-" A Buffer...
-if !exists("g:vimclojure#SplitPos")
-	let vimclojure#SplitPos = "top"
-endif
-
-if !exists("g:vimclojure#SplitSize")
-	let vimclojure#SplitSize = ""
-endif
-
-let vimclojure#Buffer = {}
-
-function! vimclojure#Buffer.New() dict
-	let instance = copy(self)
-
-	call self.MakeBuffer()
-	call self.Init(instance)
-
-	return instance
-endfunction
-
-function! vimclojure#Buffer.MakeBuffer()
-	if g:vimclojure#SplitPos == "left" || g:vimclojure#SplitPos == "right"
-		let o_sr = &splitright
-		if g:vimclojure#SplitPos == "left"
-			set nosplitright
-		else
-			set splitright
-		end
-		execute printf("%svnew", g:vimclojure#SplitSize)
-		let &splitright = o_sr
-	else
-		let o_sb = &splitbelow
-		if g:vimclojure#SplitPos == "bottom"
-			set splitbelow
-		else
-			set nosplitbelow
-		end
-		execute printf("%snew", g:vimclojure#SplitSize)
-		let &splitbelow = o_sb
-	endif
-endfunction
-
-function! vimclojure#Buffer.Init(instance)
-	let a:instance._buffer = bufnr("%")
-endfunction
-
-function! vimclojure#Buffer.goHere() dict
-	execute "buffer! " . self._buffer
-endfunction
-
-function! vimclojure#Buffer.goHereWindow() dict
-	execute "sbuffer! " . self._buffer
-endfunction
-
-function! vimclojure#Buffer.resize() dict
-	call self.goHere()
-	let size = line("$")
-	if size < 3
-		let size = 3
-	endif
-	execute "resize " . size
-endfunction
-
-function! vimclojure#Buffer.showText(text) dict
-	call self.goHere()
-	if type(a:text) == type("")
-		let text = split(a:text, '\n')
-	else
-		let text = a:text
-	endif
-	call append(line("$"), text)
-endfunction
-
-function! vimclojure#Buffer.showOutput(output) dict
-	call self.goHere()
-	if a:output.value == 0
-		if a:output.stdout != ""
-			call self.showText(a:output.stdout)
-		endif
-		if a:output.stderr != ""
-			call self.showText(a:output.stderr)
-		endif
-	else
-		call self.showText(a:output.value)
-	endif
-endfunction
-
-function! vimclojure#Buffer.clear() dict
-	1
-	normal! "_dG
-endfunction
-
-function! vimclojure#Buffer.close() dict
-	execute "bdelete! " . self._buffer
-endfunction
-
-" The transient buffer, used to display results.
-let vimclojure#ResultBuffer = copy(vimclojure#Buffer)
-let vimclojure#ResultBuffer["__superBufferInit"] = vimclojure#ResultBuffer["Init"]
-let vimclojure#ResultBuffer.__instance = []
-
-function! vimclojure#ResultBuffer.New() dict
-	if g:vimclojure#ResultBuffer.__instance != []
-		let closure = {
-					\ 'instance' : g:vimclojure#ResultBuffer.__instance[0],
-					\ 'tosafe'   : 'switchbuf',
-					\ 'class'    : self
-					\ }
-		function closure.f() dict
-			set switchbuf=useopen
-			call self.instance.goHereWindow()
-			call self.instance.clear()
-			return self.class.Init(self.instance)
-		endfunction
-
-		return vimclojure#WithSavedOption(closure)
-	endif
-
-	let instance = copy(self)
-	let g:vimclojure#ResultBuffer.__instance = [ instance ]
-
-	call g:vimclojure#Buffer.MakeBuffer()
-	call self.__superBufferInit(instance)
-	call self.Init(instance)
-
-	return instance
-endfunction
-
-function! vimclojure#ResultBuffer.Init(instance) dict
-	setlocal noswapfile
-	setlocal buftype=nofile
-	setlocal bufhidden=wipe
-
-	call vimclojure#MapPlug("n", "p", "CloseResultBuffer")
-
-	call a:instance.clear()
-	let leader = exists("g:maplocalleader") ? g:maplocalleader : "\\"
-	call append(0, "; Use " . leader . "p to close this buffer!")
-
-	return a:instance
-endfunction
-
-function! vimclojure#ResultBuffer.CloseBuffer() dict
-	if g:vimclojure#ResultBuffer.__instance != []
-		let instance = g:vimclojure#ResultBuffer.__instance[0]
-		let g:vimclojure#ResultBuffer.__instance = []
-		call instance.close()
-	endif
-endfunction
-
-" A special result buffer for clojure output.
-let vimclojure#ClojureResultBuffer = copy(vimclojure#ResultBuffer)
-let vimclojure#ClojureResultBuffer["__superResultBufferInit"] =
-			\ vimclojure#ResultBuffer["Init"]
-let vimclojure#ClojureResultBuffer["__superResultBufferShowOutput"] =
-			\ vimclojure#ResultBuffer["showOutput"]
-
-function! vimclojure#ClojureResultBuffer.Init(instance) dict
-	call self.__superResultBufferInit(a:instance)
-	setfiletype clojure
-
-	return a:instance
-endfunction
-
-function! vimclojure#ClojureResultBuffer.showOutput(text) dict
-	call self.__superResultBufferShowOutput(a:text)
-	normal G
-endfunction
-
-" Nails
-if !exists("vimclojure#NailgunClient")
-	let vimclojure#NailgunClient = "ng"
-endif
-
-function! vimclojure#ShellEscapeArguments(vals)
-	let closure = { 'vals': a:vals, 'tosafe': 'shellslash' }
-
-	function closure.f() dict
-		set noshellslash
-		return map(copy(self.vals), 'shellescape(v:val)')
-	endfunction
-
-	return vimclojure#WithSavedOption(closure)
-endfunction
-
-function! vimclojure#ExecuteNailWithInput(nail, input, ...)
-	if type(a:input) == type("")
-		let input = split(a:input, '\n', 1)
-	else
-		let input = a:input
-	endif
-
-	let inputfile = tempname()
-	try
-		call writefile(input, inputfile)
-
-		let cmdline = vimclojure#ShellEscapeArguments(
-					\ [g:vimclojure#NailgunClient, "vimclojure.Nail", a:nail]
-					\ + a:000)
-		let cmd = join(cmdline, " ") . " <" . inputfile
-
-		let output = system(cmd)
-
-		if v:shell_error
-			throw "Couldn't execute Nail!\n" . output
-		endif
-	finally
-		call delete(inputfile)
-	endtry
-
-	execute "let result = " . substitute(output, '\n$', '', '')
-	return result
-endfunction
-
-function! vimclojure#ExecuteNail(nail, ...)
-	return call(function("vimclojure#ExecuteNailWithInput"), [a:nail, ""] + a:000)
-endfunction
-
-function! vimclojure#FilterNail(nail, rngStart, rngEnd, ...)
-	let cmdline = [g:vimclojure#NailgunClient,
-				\ "vimclojure.Nail", a:nail]
-				\ + vimclojure#ShellEscapeArguments(a:000)
-	let cmd = a:rngStart . "," . a:rngEnd . "!" . join(cmdline, " ")
-
-	silent execute cmd
-endfunction
-
-function! vimclojure#DocLookup(word)
-	if a:word == ""
-		return
-	endif
-
-	let doc = vimclojure#ExecuteNailWithInput("DocLookup", a:word,
-				\ "-n", b:vimclojure_namespace)
-	let buf = g:vimclojure#ResultBuffer.New()
-	call buf.showOutput(doc)
-	wincmd p
-endfunction
-
-function! vimclojure#FindDoc()
-	let pattern = input("Pattern to look for: ")
-	let doc = vimclojure#ExecuteNailWithInput("FindDoc", pattern)
-	let buf = g:vimclojure#ResultBuffer.New()
-	call buf.showOutput(doc)
-	wincmd p
-endfunction
-
-let s:DefaultJavadocPaths = {
-			\ "java" : "http://java.sun.com/javase/6/docs/api/",
-			\ "org/apache/commons/beanutils" : "http://commons.apache.org/beanutils/api/",
-			\ "org/apache/commons/chain" : "http://commons.apache.org/chain/api-release/",
-			\ "org/apache/commons/cli" : "http://commons.apache.org/cli/api-release/",
-			\ "org/apache/commons/codec" : "http://commons.apache.org/codec/api-release/",
-			\ "org/apache/commons/collections" : "http://commons.apache.org/collections/api-release/",
-			\ "org/apache/commons/logging" : "http://commons.apache.org/logging/apidocs/",
-			\ "org/apache/commons/mail" : "http://commons.apache.org/email/api-release/",
-			\ "org/apache/commons/io" : "http://commons.apache.org/io/api-release/"
-			\ }
-
-if !exists("vimclojure#JavadocPathMap")
-	let vimclojure#JavadocPathMap = {}
-endif
-
-for k in keys(s:DefaultJavadocPaths)
-	if !has_key(vimclojure#JavadocPathMap, k)
-		let vimclojure#JavadocPathMap[k] = s:DefaultJavadocPaths[k]
-	endif
-endfor
-
-if !exists("vimclojure#Browser")
-	if has("win32") || has("win64")
-		let vimclojure#Browser = "start"
-	elseif has("mac")
-		let vimclojure#Browser = "open"
-	else
-		let vimclojure#Browser = "firefox -new-window"
-	endif
-endif
-
-function! vimclojure#JavadocLookup(word)
-	let word = substitute(a:word, "\\.$", "", "")
-	let path = vimclojure#ExecuteNailWithInput("JavadocPath", word,
-				\ "-n", b:vimclojure_namespace)
-
-	if path.stderr != ""
-		let buf = g:vimclojure#ResultBuffer.New()
-		call buf.showOutput(path)
-		wincmd p
-		return
-	endif
-
-	let match = ""
-	for pattern in keys(g:vimclojure#JavadocPathMap)
-		if path.value =~ "^" . pattern && len(match) < len(pattern)
-			let match = pattern
-		endif
-	endfor
-
-	if match == ""
-		echoerr "No matching Javadoc URL found for " . path.value
-	endif
-
-	let url = g:vimclojure#JavadocPathMap[match] . path.value
-	call system(join([g:vimclojure#Browser, url], " "))
-endfunction
-
-function! vimclojure#SourceLookup(word)
-	let source = vimclojure#ExecuteNailWithInput("SourceLookup", a:word,
-				\ "-n", b:vimclojure_namespace)
-	let buf = g:vimclojure#ClojureResultBuffer.New()
-	call buf.showOutput(source)
-	wincmd p
-endfunction
-
-function! vimclojure#MetaLookup(word)
-	let meta = vimclojure#ExecuteNailWithInput("MetaLookup", a:word,
-				\ "-n", b:vimclojure_namespace)
-	let buf = g:vimclojure#ClojureResultBuffer.New()
-	call buf.showOutput(meta)
-	wincmd p
-endfunction
-
-function! vimclojure#GotoSource(word)
-	let pos = vimclojure#ExecuteNailWithInput("SourceLocation", a:word,
-				\ "-n", b:vimclojure_namespace)
-
-	if pos.stderr != ""
-		let buf = g:vimclojure#ResultBuffer.New()
-		call buf.showOutput(pos)
-		wincmd p
-		return
-	endif
-
-	if !filereadable(pos.value.file)
-		let file = findfile(pos.value.file)
-		if file == ""
-			echoerr pos.value.file . " not found in 'path'"
-			return
-		endif
-		let pos.value.file = file
-	endif
-
-	execute "edit " . pos.value.file
-	execute pos.value.line
-endfunction
-
-" Evaluators
-function! vimclojure#MacroExpand(firstOnly)
-	let sexp = vimclojure#ExtractSexpr(0)
-	let ns = b:vimclojure_namespace
-
-	let cmd = ["MacroExpand", sexp, "-n", ns]
-	if a:firstOnly
-		let cmd = cmd + [ "-o" ]
-	endif
-
-	let expanded = call(function("vimclojure#ExecuteNailWithInput"), cmd)
-
-	let buf = g:vimclojure#ClojureResultBuffer.New()
-	call buf.showOutput(expanded)
-	wincmd p
-endfunction
-
-function! vimclojure#RequireFile(all)
-	let ns = b:vimclojure_namespace
-	let all = a:all ? "-all" : ""
-
-	let require = "(require :reload" . all . " :verbose '". ns. ")"
-	let result = vimclojure#ExecuteNailWithInput("Repl", require, "-r")
-
-	let resultBuffer = g:vimclojure#ClojureResultBuffer.New()
-	call resultBuffer.showOutput(result)
-	wincmd p
-endfunction
-
-function! vimclojure#RunTests(all)
-	let ns = b:vimclojure_namespace
-
-	let result = call(function("vimclojure#ExecuteNailWithInput"),
-				\ [ "RunTests", "", "-n", ns ] + (a:all ? [ "-a" ] : []))
-	let resultBuffer = g:vimclojure#ClojureResultBuffer.New()
-	call resultBuffer.showOutput(result)
-	wincmd p
-endfunction
-
-function! vimclojure#EvalFile()
-	let content = getbufline(bufnr("%"), 1, line("$"))
-	let file = vimclojure#BufferName()
-	let ns = b:vimclojure_namespace
-
-	let result = vimclojure#ExecuteNailWithInput("Repl", content,
-				\ "-r", "-n", ns, "-f", file)
-
-	let resultBuffer = g:vimclojure#ClojureResultBuffer.New()
-	call resultBuffer.showOutput(result)
-	wincmd p
-endfunction
-
-function! vimclojure#EvalLine()
-	let theLine = line(".")
-	let content = getline(theLine)
-	let file = vimclojure#BufferName()
-	let ns = b:vimclojure_namespace
-
-	let result = vimclojure#ExecuteNailWithInput("Repl", content,
-				\ "-r", "-n", ns, "-f", file, "-l", theLine)
-
-	let resultBuffer = g:vimclojure#ClojureResultBuffer.New()
-	call resultBuffer.showOutput(result)
-	wincmd p
-endfunction
-
-function! vimclojure#EvalBlock() range
-	let file = vimclojure#BufferName()
-	let ns = b:vimclojure_namespace
-
-	let content = getbufline(bufnr("%"), a:firstline, a:lastline)
-	let result = vimclojure#ExecuteNailWithInput("Repl", content,
-				\ "-r", "-n", ns, "-f", file, "-l", a:firstline - 1)
-
-	let resultBuffer = g:vimclojure#ClojureResultBuffer.New()
-	call resultBuffer.showOutput(result)
-	wincmd p
-endfunction
-
-function! vimclojure#EvalToplevel()
-	let file = vimclojure#BufferName()
-	let ns = b:vimclojure_namespace
-
-	let pos = searchpairpos('(', '', ')', 'bWnr',
-					\ 'vimclojure#SynIdName() !~ "clojureParen\\d"')
-
-	if pos == [0, 0]
-		throw "Error: Not in toplevel expression!"
-	endif
-
-	let expr = vimclojure#ExtractSexpr(1)
-	let result = vimclojure#ExecuteNailWithInput("Repl", expr,
-				\ "-r", "-n", ns, "-f", file, "-l", pos[0] - 1)
-
-	let resultBuffer = g:vimclojure#ClojureResultBuffer.New()
-	call resultBuffer.showOutput(result)
-	wincmd p
-endfunction
-
-function! vimclojure#EvalParagraph()
-	let file = vimclojure#BufferName()
-	let ns = b:vimclojure_namespace
-	let startPosition = line(".")
-
-	let closure = {}
-
-	function! closure.f() dict
-		normal! }
-		return line(".")
-	endfunction
-
-	let endPosition = vimclojure#WithSavedPosition(closure)
-
-	let content = getbufline(bufnr("%"), startPosition, endPosition)
-	let result = vimclojure#ExecuteNailWithInput("Repl", content,
-				\ "-r", "-n", ns, "-f", file, "-l", startPosition - 1)
-
-	let resultBuffer = g:vimclojure#ClojureResultBuffer.New()
-	call resultBuffer.showOutput(result)
-	wincmd p
-endfunction
-
-" The Repl
-let vimclojure#Repl = copy(vimclojure#Buffer)
-let vimclojure#Repl.__superBufferInit = vimclojure#Repl.Init
-
-let vimclojure#Repl._history = []
-let vimclojure#Repl._historyDepth = 0
-let vimclojure#Repl._replCommands = [ ",close", ",st", ",ct", ",toggle-pprint" ]
-
-" Simple wrapper to allow on demand load of autoload/vimclojure.vim.
-function! vimclojure#StartRepl(...)
-	let ns = a:0 > 0 ? a:1 : "user"
-	call g:vimclojure#Repl.New(ns)
-endfunction
-
-function! vimclojure#Repl.New(namespace) dict
-	let instance = copy(self)
-
-	call g:vimclojure#Buffer.MakeBuffer()
-	call self.Init(instance, a:namespace)
-
-	return instance
-endfunction
-
-function! vimclojure#Repl.Init(instance, namespace) dict
-	call self.__superBufferInit(a:instance)
-
-	let a:instance._prompt = a:namespace . "=>"
-
-	setlocal buftype=nofile
-	setlocal noswapfile
-
-	call append(line("$"), ["Clojure", a:instance._prompt . " "])
-
-	let replStart = vimclojure#ExecuteNail("Repl", "-s",
-				\ "-n", a:namespace)
-	let a:instance._id = replStart.value.id
-	call vimclojure#ExecuteNailWithInput("Repl",
-				\ "(require 'clojure.stacktrace)",
-				\ "-r", "-i", a:instance._id)
-
-	let b:vimclojure_repl = a:instance
-
-	set filetype=clojure
-
-	if !hasmapto("<Plug>ClojureReplEnterHook")
-		imap <buffer> <silent> <CR> <Plug>ClojureReplEnterHook
-	endif
-	if !hasmapto("<Plug>ClojureReplUpHistory")
-		imap <buffer> <silent> <C-Up> <Plug>ClojureReplUpHistory
-	endif
-	if !hasmapto("<Plug>ClojureReplDownHistory")
-		imap <buffer> <silent> <C-Down> <Plug>ClojureReplDownHistory
-	endif
-
-	normal! G
-	startinsert!
-endfunction
-
-function! vimclojure#Repl.isReplCommand(cmd) dict
-	for candidate in self._replCommands
-		if candidate == a:cmd
-			return 1
-		endif
-	endfor
-	return 0
-endfunction
-
-function! vimclojure#Repl.doReplCommand(cmd) dict
-	if a:cmd == ",close"
-		call vimclojure#ExecuteNail("Repl", "-S", "-i", self._id)
-		call self.close()
-		stopinsert
-	elseif a:cmd == ",st"
-		let result = vimclojure#ExecuteNailWithInput("Repl",
-					\ "(vimclojure.util/pretty-print-stacktrace *e)", "-r",
-					\ "-i", self._id)
-		call self.showOutput(result)
-		call self.showPrompt()
-	elseif a:cmd == ",ct"
-		let result = vimclojure#ExecuteNailWithInput("Repl",
-					\ "(vimclojure.util/pretty-print-causetrace *e)", "-r",
-					\ "-i", self._id)
-		call self.showOutput(result)
-		call self.showPrompt()
-	elseif a:cmd == ",toggle-pprint"
-		let result = vimclojure#ExecuteNailWithInput("Repl",
-					\ "(set! vimclojure.repl/*print-pretty* (not vimclojure.repl/*print-pretty*))", "-r",
-					\ "-i", self._id)
-		call self.showOutput(result)
-		call self.showPrompt()
-	endif
-endfunction
-
-function! vimclojure#Repl.showPrompt() dict
-	call self.showText(self._prompt . " ")
-	normal! G
-	startinsert!
-endfunction
-
-function! vimclojure#Repl.getCommand() dict
-	let ln = line("$")
-
-	while getline(ln) !~ "^" . self._prompt && ln > 0
-		let ln = ln - 1
-	endwhile
-
-	" Special Case: User deleted Prompt by accident. Insert a new one.
-	if ln == 0
-		call self.showPrompt()
-		return ""
-	endif
-
-	let cmd = vimclojure#Yank("l", ln . "," . line("$") . "yank l")
-
-	let cmd = substitute(cmd, "^" . self._prompt . "\\s*", "", "")
-	let cmd = substitute(cmd, "\n$", "", "")
-	return cmd
-endfunction
-
-function! vimclojure#Repl.enterHook() dict
-	let cmd = self.getCommand()
-
-	" Special Case: Showed prompt (or user just hit enter).
-	if cmd == ""
-		return
-	endif
-
-	if self.isReplCommand(cmd)
-		call self.doReplCommand(cmd)
-		return
-	endif
-
-	let result = vimclojure#ExecuteNailWithInput("CheckSyntax", cmd,
-				\ "-n", b:vimclojure_namespace)
-	if result.value == 0 && result.stderr == ""
-		execute "normal! GA\<CR>x"
-		normal! ==x
-		startinsert!
-	elseif result.stderr != ""
-		let buf = g:vimclojure#ResultBuffer.New()
-		call buf.showOutput(result)
-	else
-		let result = vimclojure#ExecuteNailWithInput("Repl", cmd,
-					\ "-r", "-i", self._id)
-		call self.showOutput(result)
-
-		let self._historyDepth = 0
-		let self._history = [cmd] + self._history
-
-		let namespace = vimclojure#ExecuteNailWithInput("ReplNamespace", "",
-					\ "-i", self._id)
-		let b:vimclojure_namespace = namespace.value
-		let self._prompt = namespace.value . "=>"
-
-		call self.showPrompt()
-	endif
-endfunction
-
-function! vimclojure#Repl.upHistory() dict
-	let histLen = len(self._history)
-	let histDepth = self._historyDepth
-
-	if histLen > 0 && histLen > histDepth
-		let cmd = self._history[histDepth]
-		let self._historyDepth = histDepth + 1
-
-		call self.deleteLast()
-
-		call self.showText(self._prompt . " " . cmd)
-	endif
-
-	normal! G$
-endfunction
-
-function! vimclojure#Repl.downHistory() dict
-	let histLen = len(self._history)
-	let histDepth = self._historyDepth
-
-	if histDepth > 0 && histLen > 0
-		let self._historyDepth = histDepth - 1
-		let cmd = self._history[self._historyDepth]
-
-		call self.deleteLast()
-
-		call self.showText(self._prompt . " " . cmd)
-	elseif histDepth == 0
-		call self.deleteLast()
-		call self.showText(self._prompt . " ")
-	endif
-
-	normal! G$
-endfunction
-
-function! vimclojure#Repl.deleteLast() dict
-	normal! G
-
-	while getline("$") !~ self._prompt
-		normal! dd
-	endwhile
-
-	normal! dd
-endfunction
-
-" Highlighting
-function! vimclojure#ColorNamespace(highlights)
-	for [category, words] in items(a:highlights)
-		if words != []
-			execute "syntax keyword clojure" . category . " " . join(words, " ")
-		endif
-	endfor
-endfunction
-
-" Omni Completion
-function! vimclojure#OmniCompletion(findstart, base)
-	if a:findstart == 1
-		let line = getline(".")
-		let start = col(".") - 1
-
-		while start > 0 && line[start - 1] =~ '\w\|-\|\.\|+\|*\|/'
-			let start -= 1
-		endwhile
-
-		return start
-	else
-		let slash = stridx(a:base, '/')
-		if slash > -1
-			let prefix = strpart(a:base, 0, slash)
-			let base = strpart(a:base, slash + 1)
-		else
-			let prefix = ""
-			let base = a:base
-		endif
-
-		if prefix == "" && base == ""
-			return []
-		endif
-
-		let completions = vimclojure#ExecuteNail("Complete",
-					\ "-n", b:vimclojure_namespace,
-					\ "-p", prefix, "-b", base)
-		return completions.value
-	endif
-endfunction
-
-function! vimclojure#InitBuffer()
-	if exists("b:vimclojure_loaded")
-		return
-	endif
-	let b:vimclojure_loaded = 1
-
-	if g:vimclojure#WantNailgun == 1
-		if !exists("b:vimclojure_namespace")
-			" Get the namespace of the buffer.
-			if &previewwindow
-				let b:vimclojure_namespace = "user"
-			else
-				try
-					let content = getbufline(bufnr("%"), 1, line("$"))
-					let namespace =
-								\ vimclojure#ExecuteNailWithInput(
-								\   "NamespaceOfFile", content)
-					if namespace.stderr != ""
-						throw namespace.stderr
-					endif
-					let b:vimclojure_namespace = namespace.value
-				catch /.*/
-					call vimclojure#ReportError(
-								\ "Could not determine the Namespace of the file.\n\n"
-								\ . "This might have different reasons. Please check, that the ng server\n"
-								\ . "is running with the correct classpath and that the file does not contain\n"
-								\ . "syntax errors. The interactive features will not be enabled, ie. the\n"
-								\ . "keybindings will not be mapped.\n\nReason:\n" . v:exception)
-				endtry
-			endif
-		endif
-	endif
-endfunction
-
-function! vimclojure#AddToLispWords(word)
-	execute "setlocal lw+=" . a:word
-endfunction
-
-" Epilog
-let &cpo = s:save_cpo

bin/clj

-#!/bin/bash
-
-# Copyright (c) Stephen C. Gilardi. All rights reserved.  The use and
-# distribution terms for this software are covered by the Eclipse Public
-# License 1.0 (http://opensource.org/licenses/eclipse-1.0.php) which can be
-# found in the file epl-v10.html at the root of this distribution.  By
-# using this software in any fashion, you are agreeing to be bound by the
-# terms of this license.  You must not remove this notice, or any other,
-# from this software.
-#
-# clj-env-dir Launches Clojure, passing along command line arguments. This
-#             launcher can be configured using environment variables and
-#             makes it easy to include directories full of classpath roots
-#             in CLASSPATH.
-#
-# scgilardi (gmail)
-# Created 7 January 2009
-#
-# Modified to read in an optional .clojure file in the current directory
-# naming further items for the CLASSPATH.
-#
-# Meikel Brandmeyer (mb ? kotka ! de)
-# Frankfurt am Main, 21.08.2009
-#
-# Environment variables (optional):
-#
-#  CLOJURE_EXT  Colon-delimited list of paths to directories whose top-level
-#               contents are (either directly or as symbolic links) jar
-#               files and/or directories whose paths will be in Clojure's
-#               classpath. The value of the CLASSPATH environment variable
-#               for Clojure will include these top-level paths followed by
-#               the previous value of CLASSPATH (if any).
-#               default:
-#               example: /usr/local/share/clojure/ext:$HOME/.clojure.d/ext
-#
-#  CLOJURE_JAVA The command to launch a JVM instance for Clojure
-#               default: java
-#               example: /usr/local/bin/java6
-#
-#  CLOJURE_OPTS Java options for this JVM instance
-#               default:
-#               example:"-Xms32M -Xmx128M -server"
-#
-#  CLOJURE_MAIN The Java class to launch
-#               default: clojure.main
-#               example: clojure.contrib.repl_ln
-
-set -o errexit
-#set -o nounset
-#set -o xtrace
-
-if [ -n "${CLOJURE_EXT:-}" ]; then
-    OLD="$IFS"
-    IFS=":"
-    EXT="$(find -H ${CLOJURE_EXT} -mindepth 1 -maxdepth 1 -print0 | tr \\0 \:)"
-    IFS="$OLD"
-    if [ -n "${CLASSPATH:-}" ]; then
-        CLASSPATH="${EXT}${CLASSPATH}"
-    else
-        CLASSPATH="${EXT%:}"
-    fi
-fi
-
-if [ -f .clojure ]; then
-    for path in `cat .clojure`; do
-        if [ -n "${CLASSPATH:-}" ]; then
-            CLASSPATH="${path}:${CLASSPATH}"
-        else
-            CLASSPATH="${path%:}"
-        fi
-    done
-fi
-
-export CLASSPATH
-
-JAVA=${CLOJURE_JAVA:-java}
-OPTS=${CLOJURE_OPTS:-}
-MAIN=${CLOJURE_MAIN:-clojure.main}
-
-exec ${JAVA} ${OPTS} ${MAIN} "$@"

bin/clj.bat

-@ECHO OFF
-
-REM # Copyright (c) Stephen C. Gilardi. All rights reserved.  The use and
-REM # distribution terms for this software are covered by the Eclipse Public
-REM # License 1.0 (http://opensource.org/licenses/eclipse-1.0.php) which can be
-REM # found in the file epl-v10.html at the root of this distribution.  By
-REM # using this software in any fashion, you are agreeing to be bound by the
-REM # terms of this license.  You must not remove this notice, or any other,
-REM # from this software.
-REM #
-REM # scgilardi (gmail)
-REM # Created 7 January 2009
-REM #
-REM # Modified by Justin Johnson <justin _ honesthacker com> to run on Windows
-REM # and to include a check for .clojure file in the current directory.
-REM #
-REM # Environment variables:
-REM #
-REM # Optional:
-REM #
-REM #  CLOJURE_EXT  The path to a directory containing (either directly or as
-REM #               symbolic links) jar files and/or directories whose paths
-REM #               should be in Clojure's classpath. The value of the
-REM #               CLASSPATH environment variable for Clojure will be a list
-REM #               of these paths followed by the previous value of CLASSPATH
-REM #               (if any).
-REM #
-REM #  CLOJURE_JAVA The command to launch a JVM instance for Clojure
-REM #               default: java
-REM #               example: /usr/local/bin/java6
-REM #
-REM #  CLOJURE_OPTS Java options for this JVM instance
-REM #               default:
-REM #               example:"-Xms32M -Xmx128M -server"
-REM #
-REM # Configuration files:
-REM # 
-REM # Optional:
-REM #
-REM #  .clojure     A file sitting in the directory where you invoke ng-server.
-REM #               Each line contains a single path that should be added to the classpath.
-REM #
-
-SETLOCAL ENABLEDELAYEDEXPANSION
-
-REM # Add all jar files from CLOJURE_EXT directory to classpath
-IF DEFINED CLOJURE_EXT FOR %%E IN ("%CLOJURE_EXT%\*") DO SET CP=!CP!;%%~fE
-
-IF NOT DEFINED CLOJURE_JAVA SET CLOJURE_JAVA=java
-
-REM # If the current directory has a .clojure file in it, add each path
-REM # in the file to the classpath.
-IF EXIST .clojure FOR /F %%E IN (.clojure) DO SET CP=!CP!;%%~fE
-
-%CLOJURE_JAVA% %CLOJURE_OPTS% -cp "%CP%" clojure.main %1 %2 %3 %4 %5 %6 %7 %8 %9

bin/kickoff.sh

-#! /usr/bin/env bash
-
-GRADLE_REV="0.8"
-GRADLE_URL="http://dist.codehaus.org/gradle/gradle-${GRADLE_REV}-bin.zip"
-GRADLE_ZIP="gradle.zip"
-GRADLE_DIR="gradle-${GRADLE_REV}"
-
-PLUGIN_REV="1.3.0"
-PLUGIN_URL="http://clojars.org/repo/clojuresque/clojuresque/${PLUGIN_REV}/clojuresque-${PLUGIN_REV}.jar"
-PLUGIN_JAR="clojuresque-${PLUGIN_REV}.jar"
-
-CACHE_DIR="cache"
-CACHE_GRADLE_ZIP="${CACHE_DIR}/${GRADLE_ZIP}"
-CACHE_GRADLE_DIR="${CACHE_DIR}/${GRADLE_DIR}"
-
-if [ ! -e "${CACHE_DIR}" ]; then
-    mkdir "${CACHE_DIR}"
-fi
-
-if [ ! -e "${CACHE_GRADLE_ZIP}" ]; then
-    wget ${GRADLE_URL} -O "${CACHE_GRADLE_ZIP}"
-fi
-
-if [ ! -e "${CACHE_GRADLE_DIR}" ]; then
-    pushd .
-    cd "${CACHE_DIR}"
-    unzip "${GRADLE_ZIP}"
-    popd
-fi
-
-if [ ! -e "${CACHE_PLUGIN_DIR}" ]; then
-    wget ${PLUGIN_URL} -O "${CACHE_GRADLE_DIR}/lib/${PLUGIN_JAR}"
-fi
-
-echo "clojure=clojuresque.ClojurePlugin" >> "${CACHE_GRADLE_DIR}/plugin.properties"
-
-echo "Don't forget to set GRADLE_HOME!"
-echo "export GRADLE_HOME=\"${CACHE_GRADLE_DIR}\""

bin/ng-server

-#! /usr/bin/env bash
-
-# Copyright (c) Stephen C. Gilardi. All rights reserved.  The use and
-# distribution terms for this software are covered by the Eclipse Public
-# License 1.0 (http://opensource.org/licenses/eclipse-1.0.php) which can be
-# found in the file epl-v10.html at the root of this distribution.  By
-# using this software in any fashion, you are agreeing to be bound by the
-# terms of this license.  You must not remove this notice, or any other,
-# from this software.
-#
-# clj-env-dir Launches Clojure, passing along command line arguments. This
-#             launcher can be configured using environment variables and
-#             makes it easy to include directories full of classpath roots
-#             in CLASSPATH.
-#
-# scgilardi (gmail)
-# Created 7 January 2009
-#
-# Modified to act as launcher for the Nailgun server and to read in an
-# optional .clojure file in the current directory naming further items
-# for the CLASSPATH.
-#
-# Meikel Brandmeyer (mb ? kotka ! de)
-# Frankfurt am Main, 21.08.2009
-#
-# Environment variables (optional):
-#
-#  CLOJURE_EXT  Colon-delimited list of paths to directories whose top-level
-#               contents are (either directly or as symbolic links) jar
-#               files and/or directories whose paths will be in Clojure's
-#               classpath. The value of the CLASSPATH environment variable
-#               for Clojure will include these top-level paths followed by
-#               the previous value of CLASSPATH (if any).
-#               default:
-#               example: /usr/local/share/clojure/ext:$HOME/.clojure.d/ext
-#
-#  CLOJURE_JAVA The command to launch a JVM instance for Clojure
-#               default: java
-#               example: /usr/local/bin/java6
-#
-#  CLOJURE_OPTS Java options for this JVM instance
-#               default:
-#               example:"-Xms32M -Xmx128M -server"
-#
-#  .clojure     A file in the current directory. Every line names an item
-#               which will be added to the CLASSPATH.
-
-set -o errexit
-#set -o nounset
-#set -o xtrace
-
-if [ -n "${CLOJURE_EXT:-}" ]; then
-    OLD="$IFS"
-    IFS=":"
-    EXT="$(find -H ${CLOJURE_EXT} -mindepth 1 -maxdepth 1 -print0 | tr \\0 \:)"
-    IFS="$OLD"
-    if [ -n "${CLASSPATH:-}" ]; then
-        export CLASSPATH="${EXT}${CLASSPATH}"
-    else
-        export CLASSPATH="${EXT%:}"
-    fi
-fi
-
-if [ -f .clojure ]; then
-    for path in `cat .clojure`; do
-        if [ -n "${CLASSPATH:-}" ]; then
-            export CLASSPATH="${path}:${CLASSPATH}"
-        else
-            export CLASSPATH="${path%:}"
-        fi
-    done
-fi
-
-JAVA=${CLOJURE_JAVA:-java}
-OPTS=${CLOJURE_OPTS:-}
-
-exec ${JAVA} ${OPTS} vimclojure.nailgun.NGServer 127.0.0.1 "$@"

bin/ng-server.bat

-@ECHO OFF
-
-REM # Copyright (c) Stephen C. Gilardi. All rights reserved.  The use and
-REM # distribution terms for this software are covered by the Eclipse Public
-REM # License 1.0 (http://opensource.org/licenses/eclipse-1.0.php) which can be
-REM # found in the file epl-v10.html at the root of this distribution.  By
-REM # using this software in any fashion, you are agreeing to be bound by the
-REM # terms of this license.  You must not remove this notice, or any other,
-REM # from this software.
-REM #
-REM # scgilardi (gmail)
-REM # Created 7 January 2009
-REM #
-REM # Modified by Justin Johnson <justin _ honesthacker com> to act as Windows
-REM # launcher for the Nailgun server of VimClojure, and to include a check for
-REM # a .clojure file in the current directory.
-REM #
-REM # Environment variables:
-REM #
-REM # Optional:
-REM #
-REM #  CLOJURE_EXT  The path to a directory containing (either directly or as
-REM #               symbolic links) jar files and/or directories whose paths
-REM #               should be in Clojure's classpath. The value of the
-REM #               CLASSPATH environment variable for Clojure will be a list
-REM #               of these paths followed by the previous value of CLASSPATH
-REM #               (if any).
-REM #
-REM #  CLOJURE_JAVA The command to launch a JVM instance for Clojure
-REM #               default: java
-REM #               example: /usr/local/bin/java6
-REM #
-REM #  CLOJURE_OPTS Java options for this JVM instance
-REM #               default:
-REM #               example:"-Xms32M -Xmx128M -server"
-REM #
-REM # Configuration files:
-REM # 
-REM # Optional:
-REM #
-REM #  .clojure     A file sitting in the directory where you invoke ng-server.
-REM #               Each line contains a single path that should be added to the classpath.
-REM #
-
-SETLOCAL ENABLEDELAYEDEXPANSION
-
-REM # Add all jar files from CLOJURE_EXT directory to classpath
-IF DEFINED CLOJURE_EXT FOR %%E IN ("%CLOJURE_EXT%\*") DO SET CP=!CP!;%%~fE
-
-IF NOT DEFINED CLOJURE_JAVA SET CLOJURE_JAVA=java
-
-REM # If the current directory has a .clojure file in it, add each path
-REM # in the file to the classpath.
-IF EXIST .clojure FOR /F %%E IN (.clojure) DO SET CP=!CP!;%%~fE
-
-REM # Since we do not provide any security we at least bind only to the loopback.
-%CLOJURE_JAVA% %CLOJURE_OPTS% -cp "%CP%" vimclojure.nailgun.NGServer 127.0.0.1 %1 %2 %3 %4 %5 %6 %7 %8 %9
-apply plugin: 'clojure'
+subprojects {
+    apply plugin: 'java-base'
 
-group = 'vimclojure'
-version = '2.2.0-SNAPSHOT'
+    group = 'vimclojure'
+    version = '2.2.0-SNAPSHOT'
 
-repositories {
-    clojureReleasesRepo()
+    defaultTasks 'build'
 }
 
-dependencies {
-    development 'org.clojure:clojure:1.1.0'
+project(':server') {
+    apply plugin: 'clojure'
+
+    repositories {
+        clojureReleasesRepo()
+    }
+
+    dependencies {
+        development 'org.clojure:clojure:1.1.0'
+    }
+
+    compileClojure.dependsOn compileJava
 }
 
-compileClojure.dependsOn compileJava
-
-defaultTasks 'build'
-
-task vimZip(type: Zip) {
-    from('.') {
-        include 'autoload/**/*'
-        include 'bin/**/*'
-        exclude 'bin/kickoff.sh'
-        include 'doc/**/*'
-        include 'ftdetect/**/*'
-        include 'ftplugin/**/*'
-        include 'indent/**/*'
-        include 'plugin/**/*'
-        include 'syntax/**/*'
-        include 'LICENSE.txt'
-        include 'README.txt'
-    }
-}
-
-task nailgunClientZip(type: Zip) {
-    archiveName = "vimclojure-nailgun-client-" + project.version + ".zip"
-    into("vimclojure-nailgun-client") {
-        from('.') {
-            include "ngclient/**/*"
-            include "Makefile"
-            include "ng.exe"
+project(':client') {
+    task nailgunClientZip(type: Zip) {
+        archiveName = "vimclojure-nailgun-client-" + project.version + ".zip"
+        into("vimclojure-nailgun-client") {
+            from('.') {
+                include "ngclient/**/*"
+                include "Makefile"
+                include "ng.exe"
+            }
         }
     }
 }
 
-// Install the Vim part of the plugin
-void installFiles(File directory, String pattern, File destination) {
-    destination.mkdirs()
-    ant.copy(todir: destination) {
-        fileset dir: directory, includes: pattern
-    }
-}
-
-task installVim << {
-    File installDir
-
-    if (project.hasProperty('vimdir')) {
-        installDir = new File(project.vimdir)
-    } else if (System.getProperty('os.name').toLowerCase().startsWith("win")) {
-        installDir = new File(System.getProperty('user.home') + "/vimfiles")
-    } else {
-        installDir = new File(System.getProperty('user.home') + "/.vim")
+project(':vim') {
+    task vimZip(type: Zip) {
+        archiveName = "vimclojure-" + project.version + ".zip"
+        from('.') {
+            include 'autoload/**/*'
+            include 'bin/**/*'
+            exclude 'bin/kickoff.sh'
+            include 'doc/**/*'
+            include 'ftdetect/**/*'
+            include 'ftplugin/**/*'
+            include 'indent/**/*'
+            include 'plugin/**/*'
+            include 'syntax/**/*'
+        }
+        from('..') {
+            include 'LICENSE.txt'
+            include 'README.markdown'
+        }
     }
 
-    // The Vim files:
-    [ 'autoload', 'indent', 'syntax', 'ftdetect', 'ftplugin', 'plugin' ].each {
-        File subDir = new File(installDir, it)
-        installFiles file(it), '**/*.vim', subDir
+    // Install the Vim part of the plugin
+    def installFiles = { File directory, String pattern, File destination ->
+        destination.mkdirs()
+        ant.copy(todir: destination) {
+            fileset dir: directory, includes: pattern
+        }
     }
 
-    // The Docs and other text files:
-    [ 'doc', 'ftplugin/clojure' ].each {
-        File subDir = new File(installDir, it)
-        installFiles file(it), '**/*.txt', subDir
+    task installVim << {
+        File installDir
+
+        if (project.hasProperty('vimdir')) {
+            installDir = new File(project.vimdir)
+        } else if (System.getProperty('os.name').toLowerCase().startsWith("win")) {
+            installDir = new File(System.getProperty('user.home') + "/vimfiles")
+        } else {
+            installDir = new File(System.getProperty('user.home') + "/.vim")
+        }
+
+        // The Vim files:
+        [ 'autoload', 'indent', 'syntax', 'ftdetect', 'ftplugin', 'plugin' ].each {
+            File subDir = new File(installDir, it)
+            installFiles file(it), '**/*.vim', subDir
+        }
+
+        // The Docs and other text files:
+        [ 'doc', 'ftplugin/clojure' ].each {
+            File subDir = new File(installDir, it)
+            installFiles file(it), '**/*.txt', subDir
+        }
     }
 }
 
 task genCompletions(type: JavaExec.class) {
     classpath = project.files(
-        sourceSets.main.clojure.sourceDir,
-        sourceSets.main.classesDir,
-        sourceSets.main.compileClasspath
+        project(':server').sourceSets.main.clojure.sourceDir,
+        project(':server').sourceSets.main.classesDir,
+        project(':server').sourceSets.main.compileClasspath
     )
     main = "clojure.main"
     args = [ "-e", "(require 'vimclojure.gencompletions)", "-e",
     ]
 }
 
-task runNailgun(type: JavaExec.class, dependsOn: classes) {
+task runNailgun(type: JavaExec.class, dependsOn: project(':server').classes) {
     classpath = project.files(
-        sourceSets.main.clojure.sourceDir,
-        sourceSets.main.classesDir,
-        sourceSets.main.compileClasspath
+        project(':server').sourceSets.main.clojure.sourceDir,
+        project(':server').sourceSets.main.classesDir,
+        project(':server').sourceSets.main.compileClasspath
     )
     main = 'vimclojure.nailgun.NGServer'
     args = [ '127.0.0.1' ]
+# This Makefile has only been tested on linux.  It uses
+# MinGW32 to cross-compile for windows.  To install and
+# configure MinGW32 on linux, see
+# http://www.mingw.org/MinGWiki/index.php/BuildMingwCross
+#
+# Marty Lamb
+
+CC=gcc
+CFLAGS=-Wall -pedantic -s -O3
+
+# Special library requirements
+# Default:
+LIBS=
+
+# OpenSolaris 2009.06
+#LIBS=-lsocket -lnsl
+
+# Windows
+#LIBS=-lwsock32
+
+ng: ngclient/ng.c
+	@echo "Building ng client.  To build a Windows binary, type 'make ng.exe'"
+	${CC} ${CFLAGS} ${LIBS} -o ng ngclient/ng.c
+
+clean:
+	@echo "If you have a Windows binary, 'make clean' won't delete it."
+	@echo "You must remove this manually.  Most users won't have MinGW"
+	@echo "installed - so I'd rather not delete something they can't rebuild."
+	rm ng
+#	rm ng.exe

client/ng.exe

Binary file added.

client/ngclient/ng.c

+/*   
+
+  Copyright 2004, Martian Software, Inc.
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+  
+*/
+
+/**
+ * @author <a href="http://www.martiansoftware.com/contact.html">Marty Lamb</a>
+ * @author Pete Kirkham (Win32 port)
+ */
+
+#ifdef WIN32
+	#include <direct.h>
+	#include <winsock2.h>
+#else
+	#include <arpa/inet.h>
+	#include <netdb.h>
+	#include <netinet/in.h>
+	#include <sys/socket.h>
+	#include <sys/types.h>
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#define NAILGUN_VERSION "0.7.1"
+
+#define BUFSIZE (2048)
+
+#ifdef WIN32
+	HANDLE NG_STDIN_FILENO;
+	HANDLE NG_STDOUT_FILENO;
+	HANDLE NG_STDERR_FILENO;
+	#define FILE_SEPARATOR '\\'
+	#define MSG_WAITALL 0
+#else
+	#define NG_STDIN_FILENO STDIN_FILENO
+	#define NG_STDOUT_FILENO STDOUT_FILENO
+	#define NG_STDERR_FILENO STDERR_FILENO
+	#define FILE_SEPARATOR '/'
+	typedef int HANDLE;
+	typedef unsigned int SOCKET;
+	/* buffer used for reading an writing chunk data */
+	char buf[BUFSIZE];
+#endif
+
+#ifndef MIN
+#define MIN(a,b) ((a<b)?(a):(b))
+#endif
+
+#ifdef WIN32
+	#define NAILGUN_FILESEPARATOR "NAILGUN_FILESEPARATOR=\\"
+	#define NAILGUN_PATHSEPARATOR "NAILGUN_PATHSEPARATOR=;"
+#else
+	#define NAILGUN_FILESEPARATOR "NAILGUN_FILESEPARATOR=/"
+	#define NAILGUN_PATHSEPARATOR "NAILGUN_PATHSEPARATOR=:"
+#endif
+
+#define NAILGUN_CLIENT_NAME_EXE "ng.exe"
+
+#define NAILGUN_PORT_DEFAULT "2113"
+#define NAILGUN_CLIENT_NAME "ng"
+#define CHUNK_HEADER_LEN (5)
+
+#define NAILGUN_SOCKET_FAILED (999)
+#define NAILGUN_CONNECT_FAILED (998)
+#define NAILGUN_UNEXPECTED_CHUNKTYPE (997)
+#define NAILGUN_EXCEPTION_ON_SERVER (996)
+#define NAILGUN_CONNECTION_BROKEN (995)
+#define NAILGUN_BAD_ARGUMENTS (994)
+
+#define CHUNKTYPE_STDIN '0'
+#define CHUNKTYPE_STDOUT '1'
+#define CHUNKTYPE_STDERR '2'
+#define CHUNKTYPE_STDIN_EOF '.'
+#define CHUNKTYPE_ARG 'A'
+#define CHUNKTYPE_ENV 'E'
+#define CHUNKTYPE_DIR 'D'
+#define CHUNKTYPE_CMD 'C'
+#define CHUNKTYPE_EXIT 'X'
+
+
+/* the socket connected to the nailgun server */
+int nailgunsocket = 0;
+
+/**
+ * Clean up the application.
+ */
+void cleanUpAndExit (int exitCode) {
+
+
+  #ifdef WIN32
+    CancelIo(STDIN_FILENO);
+    WSACleanup();
+    if (nailgunsocket) {
+      closesocket(nailgunsocket);
+    }
+  #else
+    close(nailgunsocket);
+  #endif
+
+  exit(exitCode);
+}
+
+#ifdef WIN32
+/**
+ * Handles an error.
+ * Shows the message for the latest error then exits.
+ */
+void handleError () {
+  LPVOID lpMsgBuf;
+  int error = GetLastError();
+
+  FormatMessage( 
+    FORMAT_MESSAGE_ALLOCATE_BUFFER | 
+    FORMAT_MESSAGE_FROM_SYSTEM | 
+    FORMAT_MESSAGE_IGNORE_INSERTS,
+    NULL,
+    error,
+    MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), /* Default language */
+    (LPTSTR) &lpMsgBuf,
+    0,
+    NULL);
+
+  /* Display the string. */
+  MessageBox( NULL, (LPCTSTR)lpMsgBuf, "Error", MB_OK | MB_ICONERROR );
+
+  /* Free the buffer. */
+  LocalFree( lpMsgBuf );
+ 
+  cleanUpAndExit(error);
+}
+#endif
+
+/**
+ * Writes everything in the specified buffer to the specified
+ * socket handle.
+ *
+ * @param s the socket descriptor
+ * @param buf the buffer containing the data to send
+ * @param len the number of bytes to send.  Also used to
+ *            return the number of bytes sent.
+ * @return total bytes written or 0 if failure
+ */
+int sendAll(SOCKET s, char *buf, int len) {
+  int total = 0;      
+  int bytesleft = len; 
+  int n = 0;
+    
+  while(total < len) {
+    n = send(s, buf+total, bytesleft, 0);
+    
+    if (n == -1) { 
+      break;
+    }
+    
+    total += n;
+    bytesleft -= n;
+  }
+
+  return n==-1 ? 0:total; 
+}
+
+/**
+ * Sends a chunk header noting the specified payload size and chunk type.
+ * 
+ * @param size the payload size
+ * @param chunkType the chunk type identifier
+ */
+void sendHeader(unsigned int size, char chunkType) {
+  /* buffer used for reading and writing chunk headers */
+  char header[CHUNK_HEADER_LEN];
+
+  header[0] = (size >> 24) & 0xff;
+  header[1] = (size >> 16) & 0xff;
+  header[2] = (size >> 8) & 0xff;
+  header[3] = size & 0xff;
+  header[4] = chunkType;
+
+  sendAll(nailgunsocket, header, CHUNK_HEADER_LEN);
+}
+
+/**
+ * Sends a null-terminated string with the specified chunk type.
+ *
+ * @param chunkType the chunk type identifier
+ * @param text the null-terminated string to send
+ */
+void sendText(char chunkType, char *text) {
+  int len = 0;
+  if (text != NULL)
+    len = strlen(text);
+  sendHeader(len, chunkType);
+  sendAll(nailgunsocket, text, len);
+}
+
+/**
+ * Exits the client if the nailgun server ungracefully shut down the connection.
+ */
+void handleSocketClose() {
+  cleanUpAndExit(NAILGUN_CONNECTION_BROKEN);
+}
+
+/**
+ * Receives len bytes from the nailgun socket and copies them to the specified file descriptor.
+ * Used to route data to stdout or stderr on the client.
+ *
+ * @param destFD the destination file descriptor (stdout or stderr)
+ * @param len the number of bytes to copy
+ */
+void recvToFD(HANDLE destFD, char *buf, unsigned long len) {
+  unsigned long bytesRead = 0;
+  int bytesCopied;
+  
+  while (bytesRead < len) {
+    unsigned long bytesRemaining = len - bytesRead;
+    int bytesToRead = (BUFSIZE < bytesRemaining) ? BUFSIZE : bytesRemaining;
+    int thisPass = 0;
+    
+    thisPass = recv(nailgunsocket, buf, bytesToRead, MSG_WAITALL);
+   
+    bytesRead += thisPass;
+
+    bytesCopied = 0;
+
+    while(bytesCopied < thisPass) {
+      #ifdef WIN32
+        DWORD thisWrite =  0;
+
+        WriteFile(destFD, buf + bytesCopied, thisPass - bytesCopied,
+          &thisWrite, NULL);
+
+        if (thisWrite < 0) {
+          break;
+        }
+
+        bytesCopied += thisWrite;
+      #else
+        bytesCopied += write(destFD, buf + bytesCopied, thisPass - bytesCopied);
+      #endif
+    }  
+  }
+}
+
+
+/**
+ * Processes an exit chunk from the server.  This is just a string
+ * containing the exit code in decimal format.  It should fit well
+ * within our buffer, so assume that it does.
+ *
+ * @param len the current length of the buffer containing the exit code.
+ */
+void processExit(char *buf, unsigned long len) {
+  int exitcode;
+  int bytesToRead = (BUFSIZE - 1 < len) ? BUFSIZE - 1 : len;
+  int bytesRead = recv(nailgunsocket, buf, bytesToRead, MSG_WAITALL);
+  
+  if (bytesRead < 0) {
+    handleSocketClose();
+  }
+  
+  buf[bytesRead] = 0;
+  
+  exitcode = atoi(buf);
+  
+  cleanUpAndExit(exitcode);
+}
+
+/**
+ * Processes data from the nailgun server.
+ */
+void processnailgunstream() {
+  /* buffer used for receiving and writing nail output chunks */
+  char buf[BUFSIZE];
+
+  /*for (;;) {*/
+    int bytesRead = 0;
+    unsigned long len;
+    char chunkType;
+
+    bytesRead = recv(nailgunsocket, buf, CHUNK_HEADER_LEN, 0);
+
+    if (bytesRead < CHUNK_HEADER_LEN) {
+      handleSocketClose();
+    }
+  
+    len = ((buf[0] << 24) & 0xff000000)
+      | ((buf[1] << 16) & 0x00ff0000)
+      | ((buf[2] << 8) & 0x0000ff00)
+      | ((buf[3]) & 0x000000ff);
+  
+    chunkType = buf[4];
+  
+    switch(chunkType) {
+      case CHUNKTYPE_STDOUT: recvToFD(NG_STDOUT_FILENO, buf, len);
+            break;
+      case CHUNKTYPE_STDERR: recvToFD(NG_STDERR_FILENO, buf, len);
+            break;
+      case CHUNKTYPE_EXIT:   processExit(buf, len);
+            break;
+      default:  fprintf(stderr, "Unexpected chunk type %d ('%c')\n", chunkType, chunkType);
+          cleanUpAndExit(NAILGUN_UNEXPECTED_CHUNKTYPE);
+    }
+  /*}*/
+}
+
+/**
+ * Sends len bytes from buf to the nailgun server in a stdin chunk.
+ *
+ * @param buf the bytes to send
+ * @param len the number of bytes to send
+ */
+void sendStdin(char *buf, unsigned int len) {
+  sendHeader(len, CHUNKTYPE_STDIN);
+  sendAll(nailgunsocket, buf, len);
+}
+
+/**
+ * Sends a stdin-eof chunk to the nailgun server
+ */
+void processEof() {
+  sendHeader(0, CHUNKTYPE_STDIN_EOF);
+}
+
+
+#ifdef WIN32
+/**
+ * Thread main for reading from stdin and sending
+ */
+DWORD WINAPI processStdin (LPVOID lpParameter) {
+  /* buffer used for reading and sending stdin chunks */
+  char buf[BUFSIZE];
+
+  for (;;) {
+    DWORD numberOfBytes = 0;
+
+    if (!ReadFile(NG_STDIN_FILENO, buf, BUFSIZE, &numberOfBytes, NULL)) {
+      if (numberOfBytes != 0) {
+        handleError();
+      }
+    }
+
+    if (numberOfBytes > 0) {
+      sendStdin(buf, numberOfBytes);
+    } else {
+      processEof();
+      break;
+    }
+  }
+
+  return 0;
+}
+#else
+/**
+ * Reads from stdin and transmits it to the nailgun server in a stdin chunk.
+ * Sends a stdin-eof chunk if necessary.
+ *
+ * @return zero if eof has been reached.
+ */
+int processStdin() {
+	int bytesread = read(STDIN_FILENO, buf, BUFSIZE);
+	if (bytesread > 0) {
+		sendStdin(buf, bytesread);
+	} else if (bytesread == 0) {
+		processEof();
+	}
+	return(bytesread);
+}
+#endif
+
+#ifdef WIN32
+/**
+ * Initialise Windows sockets
+ */
+void initSockets () {
+  WSADATA win_socket_data;     /* required to initialise winsock */
+  
+  WSAStartup(2, &win_socket_data);
+}
+#endif
+
+#ifdef WIN32
+/**
+ * Initialise the asynchronous io.
+ */
+void initIo () {
+  SECURITY_ATTRIBUTES securityAttributes;
+  DWORD threadId = 0;
+
+  /* create non-blocking console io */
+  AllocConsole();
+
+  securityAttributes.bInheritHandle = TRUE;
+  securityAttributes.lpSecurityDescriptor = NULL;
+  securityAttributes.nLength = 0;
+  
+  NG_STDIN_FILENO = GetStdHandle(STD_INPUT_HANDLE);
+  NG_STDOUT_FILENO = GetStdHandle(STD_OUTPUT_HANDLE);
+  NG_STDERR_FILENO = GetStdHandle(STD_ERROR_HANDLE);
+   
+  if (!CreateThread(&securityAttributes, 0, &processStdin, NULL, 0, &threadId)) {
+    handleError();
+  }
+}
+#endif
+
+/**
+ * Trims any path info from the beginning of argv[0] to determine
+ * the name used to launch the client.
+ *
+ * @param s argv[0]
+ */
+char *shortClientName(char *s) {
+  char *result = strrchr(s, FILE_SEPARATOR);
+  return ((result == NULL) ? s : result + 1);
+}
+
+/**
+ * Returns true if the specified string is the name of the nailgun
+ * client.  The comparison is made case-insensitively for windows.
+ *