Compare commits

..

No commits in common. "master" and "preload" have entirely different histories.

7 changed files with 196 additions and 496 deletions

View File

@ -4,13 +4,16 @@ There's a REPL in fireplace, but you probably wouldn't have noticed if I hadn't
told you. Such is the way with fireplace.vim. By the way, this plugin is for told you. Such is the way with fireplace.vim. By the way, this plugin is for
Clojure. Clojure.
Fireplace.vim used to be called foreplay.vim, but it was renamed so Java
developers wouldn't have to speak in hushed tones.
## Installation ## Installation
First, set up [cider-nrepl][]. (If you skip this step, fireplace.vim will First, set up [cider-nrepl][]. (If you skip this step, fireplace.vim will
make do with eval, which mostly works.) Next, fireplace.vim doesn't provide make do with eval, which mostly works.) Next, fireplace.vim doesn't provide
indenting or syntax highlighting, so you'll want [a set of Clojure runtime indenting or syntax highlighting, so you'll want [a set of Clojure runtime
files](https://github.com/guns/vim-clojure-static) if you're on a version of files](https://github.com/guns/vim-clojure-static) if you're on a version of
Vim earlier than 7.4. You might also want [salve.vim][] for assorted Vim earlier than 7.4. You might also want [leiningen.vim][] for assorted
static project support. static project support.
If you don't have a preferred installation method, I recommend If you don't have a preferred installation method, I recommend
@ -38,16 +41,16 @@ one automatically. ClojureScript support is just as seamless with
The only external dependency is that you have either a Vim with Python support The only external dependency is that you have either a Vim with Python support
compiled in, or `python` in your path. compiled in, or `python` in your path.
Oh, and if you don't have an nREPL connection, installing [salve.vim][] Oh, and if you don't have an nREPL connection, installing [leiningen.vim][]
lets it fall back to using `java clojure.main` for some of the basics, using a lets it fall back to using `java clojure.main` for some of the basics, using a
class path based on your Leiningen config. It's a bit slow, but a two-second class path based on your Leiningen or Maven config. It's a bit slow, but a
delay is vastly preferable to being forced out of my flow for a single two-second delay is vastly preferable to being forced out of my flow for a
command, in my book. single command, in my book.
[cider-nrepl]: https://github.com/clojure-emacs/cider-nrepl [cider-nrepl]: https://github.com/clojure-emacs/cider-nrepl
[Piggieback]: https://github.com/cemerick/piggieback [Piggieback]: https://github.com/cemerick/piggieback
[classpath.vim]: https://github.com/tpope/vim-classpath [classpath.vim]: https://github.com/tpope/vim-classpath
[salve.vim]: https://github.com/tpope/vim-salve [leiningen.vim]: https://github.com/tpope/vim-leiningen
### Not quite a REPL ### Not quite a REPL
@ -108,13 +111,12 @@ Because why not? It works in the quasi-REPL too.
> Why does it take so long for Vim to startup? > Why does it take so long for Vim to startup?
That's either [classpath.vim][] or [salve.vim][]. That's either [classpath.vim][] or [leiningen.vim][].
## Self-Promotion ## Self-Promotion
Like fireplace.vim? Follow the repository on Like fireplace.vim? Follow the repository on
[GitHub](https://github.com/tpope/vim-fireplace) and vote for it on [GitHub](https://github.com/tpope/vim-fireplace). And if
[vim.org](http://www.vim.org/scripts/script.php?script_id=4978). And if
you're feeling especially charitable, follow [tpope](http://tpo.pe/) on you're feeling especially charitable, follow [tpope](http://tpo.pe/) on
[Twitter](http://twitter.com/tpope) and [Twitter](http://twitter.com/tpope) and
[GitHub](https://github.com/tpope). [GitHub](https://github.com/tpope).

View File

@ -1,4 +1,4 @@
" Location: autoload/nrepl/fireplace.vim " Fireplace nREPL session
if exists("g:autoloaded_fireplace_nrepl") if exists("g:autoloaded_fireplace_nrepl")
finish finish
@ -34,24 +34,14 @@ function! fireplace#nrepl#for(transport) abort
let client.transport = a:transport let client.transport = a:transport
let client.session = client.process({'op': 'clone', 'session': 0})['new-session'] let client.session = client.process({'op': 'clone', 'session': 0})['new-session']
let client.describe = client.process({'op': 'describe', 'verbose?': 1}) let client.describe = client.process({'op': 'describe', 'verbose?': 1})
if get(client.describe.versions.nrepl, 'major', -1) == 0 && if client.describe.versions.nrepl.major == 0 &&
\ client.describe.versions.nrepl.minor < 2 \ client.describe.versions.nrepl.minor < 2
throw 'nREPL: 0.2.0 or higher required' throw 'nREPL: 0.2.0 or higher required'
endif endif
" Handle boot, which sets a fake.class.path entry if client.has_op('classpath')
let response = client.process({'op': 'eval', 'code':
\ '[(System/getProperty "path.separator") (System/getProperty "fake.class.path")]', 'session': ''})
let cpath = response.value[-1][5:-2]
if cpath !=# 'nil'
let cpath = eval(cpath)
if !empty(cpath)
let client._path = split(cpath, response.value[-1][2])
endif
endif
if !has_key(client, '_path') && client.has_op('classpath')
let response = client.message({'op': 'classpath'})[0] let response = client.message({'op': 'classpath'})[0]
if type(get(response, 'classpath')) == type([]) if type(get(response, 'value')) == type([])
let client._path = response.classpath let client._path = response.value
endif endif
endif endif
if !has_key(client, '_path') if !has_key(client, '_path')
@ -157,16 +147,13 @@ function! s:nrepl_eval(expr, ...) dict abort
endif endif
try try
let response = self.process(msg) let response = self.process(msg)
finally catch /^Vim:Interrupt$/
if !exists('response') if has_key(msg, 'session')
let session = get(msg, 'session', self.session) call self.message({'op': 'interrupt', 'session': msg.session, 'interrupt-id': msg.id}, 'ignore')
if !empty(session)
call self.message({'op': 'interrupt', 'session': session, 'interrupt-id': msg.id}, 'ignore')
endif
throw 'Clojure: Interrupt'
endif endif
throw 'Clojure: Interrupt'
endtry endtry
if has_key(response, 'ns') && empty(get(options, 'ns')) if has_key(response, 'ns') && !has_key(options, 'ns')
let self.ns = response.ns let self.ns = response.ns
endif endif
@ -182,23 +169,13 @@ endfunction
function! s:extract_last_stacktrace(nrepl, session) abort function! s:extract_last_stacktrace(nrepl, session) abort
if a:nrepl.has_op('stacktrace') if a:nrepl.has_op('stacktrace')
let stacktrace = a:nrepl.message({'op': 'stacktrace', 'session': a:session}) let stacktrace = filter(a:nrepl.message({'op': 'stacktrace', 'session': a:session}), 'has_key(v:val, "file")')
if len(stacktrace) > 0 && has_key(stacktrace[0], 'stacktrace')
let stacktrace = stacktrace[0].stacktrace
endif
call filter(stacktrace, 'has_key(v:val, "file")')
if !empty(stacktrace) if !empty(stacktrace)
return map(stacktrace, 'v:val.class.".".v:val.method."(".v:val.file.":".v:val.line.")"') return map(stacktrace, 'v:val.class.".".v:val.method."(".v:val.file.":".v:val.line.")"')
endif endif
endif endif
let format_st = '(symbol (str "\n\b" (apply str (interleave (repeat "\n") (map str (.getStackTrace *e)))) "\n\b\n"))' let format_st = '(symbol (str "\n\b" (apply str (interleave (repeat "\n") (map str (.getStackTrace *e)))) "\n\b\n"))'
let response = a:nrepl.process({'op': 'eval', 'code': '['.format_st.' *3 *2 *1]', 'ns': 'user', 'session': a:session}) let stacktrace = split(get(split(a:nrepl.process({'op': 'eval', 'code': '['.format_st.' *3 *2 *1]', 'ns': 'user', 'session': a:session}).value[0], "\n\b\n"), 1, ""), "\n")
try
let stacktrace = split(get(split(response.value[0], "\n\b\n"), 1, ""), "\n")
catch
throw string(response)
endtry
call a:nrepl.message({'op': 'eval', 'code': '(*1 1)', 'ns': 'user', 'session': a:session}) call a:nrepl.message({'op': 'eval', 'code': '(*1 1)', 'ns': 'user', 'session': a:session})
call a:nrepl.message({'op': 'eval', 'code': '(*2 2)', 'ns': 'user', 'session': a:session}) call a:nrepl.message({'op': 'eval', 'code': '(*2 2)', 'ns': 'user', 'session': a:session})
call a:nrepl.message({'op': 'eval', 'code': '(*3 3)', 'ns': 'user', 'session': a:session}) call a:nrepl.message({'op': 'eval', 'code': '(*3 3)', 'ns': 'user', 'session': a:session})
@ -213,9 +190,6 @@ function! s:nrepl_prepare(msg) dict abort
if !has_key(msg, 'id') if !has_key(msg, 'id')
let msg.id = fireplace#nrepl#next_id() let msg.id = fireplace#nrepl#next_id()
endif endif
if empty(get(msg, 'ns', 1))
unlet msg.ns
endif
if empty(get(msg, 'session', 1)) if empty(get(msg, 'session', 1))
unlet msg.session unlet msg.session
elseif !has_key(msg, 'session') elseif !has_key(msg, 'session')
@ -224,15 +198,12 @@ function! s:nrepl_prepare(msg) dict abort
return msg return msg
endfunction endfunction
function! fireplace#nrepl#callback(body, type, callback) abort function! fireplace#nrepl#callback(body, type, fn)
try let response = {'body': a:body, 'type': a:type}
let response = {'body': a:body, 'type': a:type} if has_key(g:fireplace_nrepl_sessions, get(a:body, 'session'))
if has_key(g:fireplace_nrepl_sessions, get(a:body, 'session')) let response.session = g:fireplace_nrepl_sessions[a:body.session]
let response.session = g:fireplace_nrepl_sessions[a:body.session] endif
endif call call(a:fn, [response])
call call(a:callback[0], [response] + a:callback[1:-1])
catch
endtry
endfunction endfunction
function! s:nrepl_call(msg, ...) dict abort function! s:nrepl_call(msg, ...) dict abort

View File

@ -1,4 +1,5 @@
" Location: autoload/nrepl/fireplace_connection.vim " autoload/nrepl/fireplace_connection.vim
" Maintainer: Tim Pope <http://tpo.pe/>
if exists("g:autoloaded_nrepl_fireplace_connection") || &cp if exists("g:autoloaded_nrepl_fireplace_connection") || &cp
finish finish
@ -21,11 +22,7 @@ function! fireplace#nrepl_connection#bencode(value) abort
elseif type(a:value) == type([]) elseif type(a:value) == type([])
return 'l'.join(map(copy(a:value),'fireplace#nrepl_connection#bencode(v:val)'),'').'e' return 'l'.join(map(copy(a:value),'fireplace#nrepl_connection#bencode(v:val)'),'').'e'
elseif type(a:value) == type({}) elseif type(a:value) == type({})
return 'd'.join(map( return 'd'.join(values(map(copy(a:value),'fireplace#nrepl_connection#bencode(v:key).fireplace#nrepl_connection#bencode(v:val)')),'').'e'
\ sort(keys(a:value)),
\ 'fireplace#nrepl_connection#bencode(v:val) . ' .
\ 'fireplace#nrepl_connection#bencode(a:value[v:val])'
\ ),'').'e'
else else
throw "Can't bencode ".string(a:value) throw "Can't bencode ".string(a:value)
endif endif
@ -109,7 +106,7 @@ function! s:nrepl_transport_call(msg, terms, sels, ...) dict abort
if !a:0 if !a:0
return response return response
elseif a:1 !=# 'ignore' elseif a:1 !=# 'ignore'
return map(response, 'fireplace#nrepl#callback(v:val, "synchronous", a:000)') return map(response, 'fireplace#nrepl#callback(v:val, "synchronous", a:1)')
endif endif
endfunction endfunction

9
compiler/lein.vim Normal file
View File

@ -0,0 +1,9 @@
" Vim compiler file
if exists("current_compiler")
finish
endif
let current_compiler = "lein"
CompilerSet makeprg=lein
CompilerSet errorformat=%+G

View File

@ -1,4 +1,4 @@
*fireplace.txt* Clojure REPL support *fireplace.txt* Clojure REPL tease
Author: Tim Pope <http://tpo.pe/> Author: Tim Pope <http://tpo.pe/>
License: Same terms as Vim itself (see |license|) License: Same terms as Vim itself (see |license|)
@ -123,12 +123,7 @@ stack trace is loaded into the |location-list|. Use |:lopen| to view it.
:RunTests [ns] [...] Call clojure.test/run-tests on the given namespaces :RunTests [ns] [...] Call clojure.test/run-tests on the given namespaces
and load the results into the quickfix list. and load the results into the quickfix list.
:[range]RunTests Call clojure.test/test-var on the var defined at or :RunTests! [pattern] Call clojure.test/run-all-tests with the given pattern
above the specicied line and load the results into the
quickfix list. Typically invoked as :.RunTests to run
the test under the cursor.
:0RunTests [pattern] Call clojure.test/run-all-tests with the given pattern
and load the results into the quickfix list. and load the results into the quickfix list.
*fireplace-cp* *fireplace-cp*
@ -159,10 +154,6 @@ c1mm Macroexpand the innermost form at the cursor once.
*fireplace-cqp* *fireplace-cqp*
cqp Bring up a prompt for code to eval/print. cqp Bring up a prompt for code to eval/print.
*fireplace-cqq*
cqq Bring up a |command-line-window| with innermost form
at the cursor prepopulated.
*fireplace-cqc* *fireplace-cqc*
cqc Bring up a |command-line-window| for code to cqc Bring up a |command-line-window| for code to
eval/print. Equivalent to cqp<C-F>i. eval/print. Equivalent to cqp<C-F>i.

View File

@ -1,7 +1,5 @@
" fireplace.vim - Clojure REPL support " fireplace.vim - Clojure REPL tease
" Maintainer: Tim Pope <http://tpo.pe/> " Maintainer: Tim Pope <http://tpo.pe/>
" Version: 1.1
" GetLatestVimScripts: 4978 1 :AutoInstall: fireplace.vim
if exists("g:loaded_fireplace") || v:version < 700 || &cp if exists("g:loaded_fireplace") || v:version < 700 || &cp
finish finish
@ -41,8 +39,6 @@ function! fireplace#jar_contents(path) abort
if !exists('s:zipinfo') if !exists('s:zipinfo')
if executable('zipinfo') if executable('zipinfo')
let s:zipinfo = 'zipinfo -1 ' let s:zipinfo = 'zipinfo -1 '
elseif executable('jar')
let s:zipinfo = 'jar tf '
elseif executable('python') elseif executable('python')
let s:zipinfo = 'python -c '.shellescape('import zipfile, sys; print chr(10).join(zipfile.ZipFile(sys.argv[1]).namelist())').' ' let s:zipinfo = 'python -c '.shellescape('import zipfile, sys; print chr(10).join(zipfile.ZipFile(sys.argv[1]).namelist())').' '
else else
@ -83,64 +79,6 @@ function! fireplace#ns_complete(A, L, P) abort
return filter(map(matches, 's:to_ns(v:val)'), 'a:A ==# "" || a:A ==# v:val[0 : strlen(a:A)-1]') return filter(map(matches, 's:to_ns(v:val)'), 'a:A ==# "" || a:A ==# v:val[0 : strlen(a:A)-1]')
endfunction endfunction
let s:short_types = {
\ 'function': 'f',
\ 'macro': 'm',
\ 'var': 'v',
\ 'special-form': 's',
\ 'class': 'c',
\ 'keyword': 'k',
\ 'local': 'l',
\ 'namespace': 'n',
\ 'field': 'i',
\ 'method': 'f',
\ 'static-field': 'i',
\ 'static-method': 'f',
\ 'resource': 'r'
\ }
function! s:candidate(val) abort
let type = get(a:val, 'type', '')
let arglists = get(a:val, 'arglists', [])
return {
\ 'word': get(a:val, 'candidate'),
\ 'kind': get(s:short_types, type, type),
\ 'info': get(a:val, 'doc', ''),
\ 'menu': empty(arglists) ? '' : '(' . join(arglists, ' ') . ')'
\ }
endfunction
function! s:get_complete_context() abort
" Find toplevel form
" If cursor is on start parenthesis we don't want to find the form
" If cursor is on end parenthesis we want to find the form
let [line1, col1] = searchpairpos('(', '', ')', 'Wrnb', g:fireplace#skip)
let [line2, col2] = searchpairpos('(', '', ')', 'Wrnc', g:fireplace#skip)
if (line1 == 0 && col1 == 0) || (line2 == 0 && col2 == 0)
return ""
endif
if line1 == line2
let expr = getline(line1)[col1-1 : col2-1]
else
let expr = getline(line1)[col1-1 : -1] . ' '
\ . join(getline(line1+1, line2-1), ' ')
\ . getline(line2)[0 : col2-1]
endif
" Calculate the position of cursor inside the expr
if line1 == line('.')
let p = col('.') - col1
else
let p = strlen(getline(line1)[col1-1 : -1])
\ + strlen(join(getline(line1 + 1, line('.') - 1), ' '))
\ + col('.')
endif
return strpart(expr, 0, p) . '__prefix__' . strpart(expr, p)
endfunction
function! fireplace#omnicomplete(findstart, base) abort function! fireplace#omnicomplete(findstart, base) abort
if a:findstart if a:findstart
let line = getline('.')[0 : col('.')-2] let line = getline('.')[0 : col('.')-2]
@ -149,21 +87,12 @@ function! fireplace#omnicomplete(findstart, base) abort
try try
if fireplace#op_available('complete') if fireplace#op_available('complete')
let response = fireplace#message({ let response = fireplace#message({'op': 'complete', 'symbol': a:base})
\ 'op': 'complete', if type(get(response[0], 'value')) == type([])
\ 'symbol': a:base, if type(get(response[0].value, 0)) == type([])
\ 'extra-metadata': ['arglists', 'doc'], return map(response[0].value[0], '{"word": v:val}')
\ 'context': s:get_complete_context() elseif type(get(response[0].value, 0)) == type('')
\ }) return map(response[0].value, '{"word": v:val}')
let trans = '{"word": (v:val =~# ''[./]'' ? "" : matchstr(a:base, ''^.\+/'')) . v:val}'
let value = get(response[0], 'value', get(response[0], 'completions'))
if type(value) == type([])
if type(get(value, 0)) == type({})
return map(value, 's:candidate(v:val)')
elseif type(get(value, 0)) == type([])
return map(value[0], trans)
elseif type(get(value, 0)) == type('')
return map(value, trans)
else else
return [] return []
endif endif
@ -219,6 +148,10 @@ if !exists('s:repls')
let s:repl_portfiles = {} let s:repl_portfiles = {}
endif endif
function! s:repl.user_ns() abort
return 'user'
endfunction
function! s:repl.path() dict abort function! s:repl.path() dict abort
return self.connection.path() return self.connection.path()
endfunction endfunction
@ -232,6 +165,16 @@ function! s:conn_try(connection, function, ...) abort
endtry endtry
endfunction endfunction
function! s:repl.eval(expr, options) dict abort
if has_key(a:options, 'ns') && a:options.ns !=# self.user_ns()
let error = self.preload(a:options.ns)
if !empty(error)
return error
endif
endif
return s:conn_try(self.connection, 'eval', a:expr, a:options)
endfunction
function! s:repl.message(payload, ...) dict abort function! s:repl.message(payload, ...) dict abort
if has_key(a:payload, 'ns') && a:payload.ns !=# self.user_ns() if has_key(a:payload, 'ns') && a:payload.ns !=# self.user_ns()
let ignored_error = self.preload(a:payload.ns) let ignored_error = self.preload(a:payload.ns)
@ -277,19 +220,15 @@ function! s:repl.piggieback(arg, ...) abort
let connection = s:conn_try(self.connection, 'clone') let connection = s:conn_try(self.connection, 'clone')
if empty(a:arg) if empty(a:arg)
let arg = '(cljs.repl.rhino/repl-env)' let arg = ''
elseif a:arg =~# '^\d\{1,5}$' elseif a:arg =~# '^\d\{1,5}$'
let replns = 'weasel.repl.websocket' call connection.eval("(require 'cljs.repl.browser)")
if has_key(connection.eval("(require '" . replns . ")"), 'ex')
let replns = 'cljs.repl.browser'
call connection.eval("(require '" . replns . ")")
endif
let port = matchstr(a:arg, '^\d\{1,5}$') let port = matchstr(a:arg, '^\d\{1,5}$')
let arg = '('.replns.'/repl-env :port '.port.')' let arg = ' :repl-env (cljs.repl.browser/repl-env :port '.port.')'
else else
let arg = a:arg let arg = ' :repl-env ' . a:arg
endif endif
let response = connection.eval('(cemerick.piggieback/cljs-repl'.' '.arg.')') let response = connection.eval('(cemerick.piggieback/cljs-repl'.arg.')')
if empty(get(response, 'ex')) if empty(get(response, 'ex'))
call insert(self.piggiebacks, extend({'connection': connection}, deepcopy(s:piggieback))) call insert(self.piggiebacks, extend({'connection': connection}, deepcopy(s:piggieback)))
@ -311,20 +250,6 @@ function! s:piggieback.eval(expr, options) abort
return call(s:repl.eval, [a:expr, options], self) return call(s:repl.eval, [a:expr, options], self)
endfunction endfunction
function! s:repl.user_ns() abort
return 'user'
endfunction
function! s:repl.eval(expr, options) dict abort
if has_key(a:options, 'ns') && a:options.ns !=# self.user_ns()
let error = self.preload(a:options.ns)
if !empty(error)
return error
endif
endif
return s:conn_try(self.connection, 'eval', a:expr, a:options)
endfunction
function! s:register_connection(conn, ...) abort function! s:register_connection(conn, ...) abort
call insert(s:repls, extend({'connection': a:conn, 'piggiebacks': []}, deepcopy(s:repl))) call insert(s:repls, extend({'connection': a:conn, 'piggiebacks': []}, deepcopy(s:repl)))
if a:0 && a:1 !=# '' if a:0 && a:1 !=# ''
@ -347,11 +272,10 @@ function! fireplace#register_port_file(portfile, ...) abort
endif endif
if empty(old) && getfsize(a:portfile) > 0 if empty(old) && getfsize(a:portfile) > 0
let port = matchstr(readfile(a:portfile, 'b', 1)[0], '\d\+') let port = matchstr(readfile(a:portfile, 'b', 1)[0], '\d\+')
let s:repl_portfiles[a:portfile] = {'time': getftime(a:portfile)}
try try
let conn = fireplace#nrepl_connection#open(port) let conn = fireplace#nrepl_connection#open(port)
let s:repl_portfiles[a:portfile] = { let s:repl_portfiles[a:portfile].connection = conn
\ 'time': getftime(a:portfile),
\ 'connection': conn}
call s:register_connection(conn, a:0 ? a:1 : '') call s:register_connection(conn, a:0 ? a:1 : '')
return conn return conn
catch /^nREPL Connection Error:/ catch /^nREPL Connection Error:/
@ -386,7 +310,7 @@ function! fireplace#input_host_port() abort
endfunction endfunction
function! s:protos() abort function! s:protos() abort
return map(split(globpath(&runtimepath, 'autoload/fireplace/*_connection.vim'), "\n"), 'fnamemodify(v:val, ":t")[0:-16]') return map(split(globpath(&runtimepath, 'autoload/*/fireplace_connection.vim'), "\n"), 'fnamemodify(v:val, ":h:t")')
endfunction endfunction
function! s:connect_complete(A, L, P) abort function! s:connect_complete(A, L, P) abort
@ -411,8 +335,6 @@ endfunction
function! s:Connect(...) abort function! s:Connect(...) abort
if (a:0 ? a:1 : '') =~# '^\w\+://' if (a:0 ? a:1 : '') =~# '^\w\+://'
let [proto, arg] = split(a:1, '://') let [proto, arg] = split(a:1, '://')
elseif (a:0 ? a:1 : '') =~# '^\%([[:alnum:].-]\+:\)\=\d\+$'
let [proto, arg] = ['nrepl', a:1]
elseif a:0 elseif a:0
return 'echoerr '.string('Usage: :Connect proto://...') return 'echoerr '.string('Usage: :Connect proto://...')
else else
@ -427,10 +349,10 @@ function! s:Connect(...) abort
redraw! redraw!
echo ':Connect' echo ':Connect'
echo 'Protocol> '.proto echo 'Protocol> '.proto
let arg = fireplace#{proto}_connection#prompt() let arg = {proto}#fireplace_connection#prompt()
endif endif
try try
let connection = fireplace#{proto}_connection#open(arg) let connection = {proto}#fireplace_connection#open(arg)
catch /.*/ catch /.*/
return 'echoerr '.string(v:exception) return 'echoerr '.string(v:exception)
endtry endtry
@ -454,10 +376,8 @@ endfunction
augroup fireplace_connect augroup fireplace_connect
autocmd! autocmd!
autocmd FileType clojure command! -buffer -bar -complete=customlist,s:connect_complete -nargs=* autocmd FileType clojure command! -bar -complete=customlist,s:connect_complete -nargs=* Connect :FireplaceConnect <args>
\ Connect FireplaceConnect <args> autocmd FileType clojure command! -complete=customlist,fireplace#eval_complete -bang -nargs=* Piggieback :call s:piggieback(<q-args>, <bang>0)
autocmd FileType clojure command! -buffer -bang -complete=customlist,fireplace#eval_complete -nargs=*
\ Piggieback call s:piggieback(<q-args>, <bang>0)
augroup END augroup END
" Section: Java runner " Section: Java runner
@ -543,41 +463,6 @@ let s:oneoff.piggieback = s:oneoff.message
" Section: Client " Section: Client
function! s:buffer_path(...) abort
let buffer = a:0 ? a:1 : s:buf()
if getbufvar(buffer, '&buftype') =~# '^no'
return ''
endif
let path = substitute(fnamemodify(bufname(buffer), ':p'), '\C^zipfile:\(.*\)::', '\1/', '')
for dir in fireplace#path(buffer)
if dir !=# '' && path[0 : strlen(dir)-1] ==# dir && path[strlen(dir)] =~# '[\/]'
return path[strlen(dir)+1:-1]
endif
endfor
return ''
endfunction
function! fireplace#ns(...) abort
let buffer = a:0 ? a:1 : s:buf()
if !empty(getbufvar(buffer, 'fireplace_ns'))
return getbufvar(buffer, 'fireplace_ns')
endif
let head = getbufline(buffer, 1, 500)
let blank = '^\s*\%(;.*\)\=$'
call filter(head, 'v:val !~# blank')
let keyword_group = '[A-Za-z0-9_?*!+/=<>.-]'
let lines = join(head[0:49], ' ')
let lines = substitute(lines, '"\%(\\.\|[^"]\)*"\|\\.', '', 'g')
let lines = substitute(lines, '\^\={[^{}]*}', '', '')
let lines = substitute(lines, '\^:'.keyword_group.'\+', '', 'g')
let ns = matchstr(lines, '\C^(\s*\%(in-ns\s*''\|ns\s\+\)\zs'.keyword_group.'\+\ze')
if ns !=# ''
return ns
endif
let path = s:buffer_path(buffer)
return s:to_ns(path ==# '' ? fireplace#client(buffer).user_ns() : path)
endfunction
function! s:buf() abort function! s:buf() abort
if exists('s:input') if exists('s:input')
return s:input return s:input
@ -631,7 +516,7 @@ function! fireplace#platform(...) abort
let portfile = findfile('.nrepl-port', '.;') let portfile = findfile('.nrepl-port', '.;')
if !empty(portfile) if !empty(portfile)
call fireplace#register_port_file(portfile, fnamemodify(portfile, ':p:h')) call fireplace#register_port_file(portfile, fnamemodify(portfile, ':h'))
endif endif
silent doautocmd User FireplacePreConnect silent doautocmd User FireplacePreConnect
@ -651,7 +536,7 @@ function! fireplace#platform(...) abort
endif endif
endfor endfor
let path = s:path_extract(getbufvar(buf, '&path')) let path = s:path_extract(getbufvar(buf, '&path'))
if !empty(path) && fnamemodify(bufname(buf), ':e') =~# '^clj[cx]\=$' if !empty(path) && fnamemodify(bufname(buf), ':e') =~# '^cljx\=$'
return extend({'_path': path, 'nr': bufnr(buf)}, s:oneoff) return extend({'_path': path, 'nr': bufnr(buf)}, s:oneoff)
endif endif
throw 'Fireplace: :Connect to a REPL or install classpath.vim' throw 'Fireplace: :Connect to a REPL or install classpath.vim'
@ -667,7 +552,7 @@ function! fireplace#client(...) abort
if empty(client.piggiebacks) if empty(client.piggiebacks)
let result = client.piggieback('') let result = client.piggieback('')
if has_key(result, 'ex') if has_key(result, 'ex')
throw 'Fireplace: '.result.ex return result
endif endif
endif endif
return client.piggiebacks[0] return client.piggiebacks[0]
@ -802,14 +687,6 @@ function! fireplace#session_eval(expr, ...) abort
endif endif
endif endif
try
silent doautocmd User FireplaceEvalPost
catch
echohl ErrorMSG
echomsg v:exception
echohl NONE
endtry
call s:output_response(response) call s:output_response(response)
if get(response, 'ex', '') !=# '' if get(response, 'ex', '') !=# ''
@ -872,10 +749,6 @@ function! fireplace#evalparse(expr, ...) abort
throw err throw err
endfunction endfunction
function! fireplace#query(expr, ...) abort
return fireplace#evalparse(a:expr, a:0 ? a:1 : {})
endfunction
" Section: Quickfix " Section: Quickfix
function! s:qfmassage(line, path) abort function! s:qfmassage(line, path) abort
@ -926,7 +799,7 @@ augroup END
" Section: Eval " Section: Eval
let fireplace#skip = 'synIDattr(synID(line("."),col("."),1),"name") =~? "comment\\|string\\|char\\|regexp"' let fireplace#skip = 'synIDattr(synID(line("."),col("."),1),"name") =~? "comment\\|string\\|char"'
function! s:opfunc(type) abort function! s:opfunc(type) abort
let sel_save = &selection let sel_save = &selection
@ -963,11 +836,7 @@ function! s:opfunc(type) abort
silent exe "normal! `[v`]y" silent exe "normal! `[v`]y"
endif endif
redraw redraw
if fireplace#client().user_ns() ==# 'user' return repeat("\n", line("'<")-1) . repeat(" ", col("'<")-1) . @@
return repeat("\n", line("'<")-1) . repeat(" ", col("'<")-1) . @@
else
return @@
endif
finally finally
let @@ = reg_save let @@ = reg_save
let &selection = sel_save let &selection = sel_save
@ -1168,7 +1037,7 @@ xnoremap <silent> <Plug>FireplaceMacroExpand :<C-U>call <SID>macroexpandop(visu
nnoremap <silent> <Plug>FireplaceCountMacroExpand :<C-U>call <SID>macroexpandop(v:count)<CR> nnoremap <silent> <Plug>FireplaceCountMacroExpand :<C-U>call <SID>macroexpandop(v:count)<CR>
nnoremap <silent> <Plug>Fireplace1MacroExpand :<C-U>set opfunc=<SID>macroexpand1op<CR>g@ nnoremap <silent> <Plug>Fireplace1MacroExpand :<C-U>set opfunc=<SID>macroexpand1op<CR>g@
xnoremap <silent> <Plug>Fireplace1MacroExpand :<C-U>call <SID>macroexpand1op(visualmode())<CR> xnoremap <silent> <Plug>Fireplace1MacroExpand :<C-U>call <SID>macroexpand1op(visualmode())<CR>
nnoremap <silent> <Plug>FireplaceCount1MacroExpand :<C-U>call <SID>macroexpand1op(v:count)<CR> nnoremap <silent> <Plug>Fireplace1MacroExpand :<C-U>call <SID>macroexpand1op(v:count)<CR>
nnoremap <silent> <Plug>FireplaceEdit :<C-U>set opfunc=<SID>editop<CR>g@ nnoremap <silent> <Plug>FireplaceEdit :<C-U>set opfunc=<SID>editop<CR>g@
xnoremap <silent> <Plug>FireplaceEdit :<C-U>call <SID>editop(visualmode())<CR> xnoremap <silent> <Plug>FireplaceEdit :<C-U>call <SID>editop(visualmode())<CR>
@ -1199,12 +1068,10 @@ function! s:Last(bang, count) abort
return '' return ''
endfunction endfunction
function! s:set_up_eval() abort function! s:setup_eval() abort
command! -buffer -bang -range=0 -nargs=? -complete=customlist,fireplace#eval_complete Eval :exe s:Eval(<bang>0, <line1>, <line2>, <count>, <q-args>) command! -buffer -bang -range=0 -nargs=? -complete=customlist,fireplace#eval_complete Eval :exe s:Eval(<bang>0, <line1>, <line2>, <count>, <q-args>)
command! -buffer -bang -bar -count=1 Last exe s:Last(<bang>0, <count>) command! -buffer -bang -bar -count=1 Last exe s:Last(<bang>0, <count>)
if get(g:, 'fireplace_no_maps') | return | endif
nmap <buffer> cp <Plug>FireplacePrint nmap <buffer> cp <Plug>FireplacePrint
nmap <buffer> cpp <Plug>FireplaceCountPrint nmap <buffer> cpp <Plug>FireplaceCountPrint
@ -1225,7 +1092,7 @@ function! s:set_up_eval() abort
map! <buffer> <C-R>( <Plug>FireplaceRecall map! <buffer> <C-R>( <Plug>FireplaceRecall
endfunction endfunction
function! s:set_up_historical() abort function! s:setup_historical() abort
setlocal readonly nomodifiable setlocal readonly nomodifiable
nnoremap <buffer><silent>q :bdelete<CR> nnoremap <buffer><silent>q :bdelete<CR>
endfunction endfunction
@ -1240,9 +1107,9 @@ endfunction
augroup fireplace_eval augroup fireplace_eval
autocmd! autocmd!
autocmd FileType clojure call s:set_up_eval() autocmd FileType clojure call s:setup_eval()
autocmd BufReadPost * if has_key(s:qffiles, expand('<amatch>:p')) | autocmd BufReadPost * if has_key(s:qffiles, expand('<amatch>:p')) |
\ call s:set_up_historical() | \ call s:setup_historical() |
\ endif \ endif
autocmd CmdWinEnter @ if exists('s:input') | call s:cmdwinenter() | endif autocmd CmdWinEnter @ if exists('s:input') | call s:cmdwinenter() | endif
autocmd CmdWinLeave @ if exists('s:input') | call s:cmdwinleave() | endif autocmd CmdWinLeave @ if exists('s:input') | call s:cmdwinleave() | endif
@ -1270,16 +1137,14 @@ function! s:Require(bang, echo, ns) abort
endtry endtry
endfunction endfunction
function! s:set_up_require() abort function! s:setup_require() abort
command! -buffer -bar -bang -complete=customlist,fireplace#ns_complete -nargs=? Require :exe s:Require(<bang>0, 1, <q-args>) command! -buffer -bar -bang -complete=customlist,fireplace#ns_complete -nargs=? Require :exe s:Require(<bang>0, 1, <q-args>)
nnoremap <silent><buffer> cpr :if expand('%:e') ==# 'cljs'<Bar>Require<Bar>else<Bar>RunTests<Bar>endif<CR>
if get(g:, 'fireplace_no_maps') | return | endif
nnoremap <silent><buffer> cpr :<C-R>=expand('%:e') ==# 'cljs' ? 'Require' : 'RunTests'<CR><CR>
endfunction endfunction
augroup fireplace_require augroup fireplace_require
autocmd! autocmd!
autocmd FileType clojure call s:set_up_require() autocmd FileType clojure call s:setup_require()
augroup END augroup END
" Section: Go to source " Section: Go to source
@ -1289,8 +1154,6 @@ function! fireplace#info(symbol) abort
let response = fireplace#message({'op': 'info', 'symbol': a:symbol})[0] let response = fireplace#message({'op': 'info', 'symbol': a:symbol})[0]
if type(get(response, 'value')) == type({}) if type(get(response, 'value')) == type({})
return response.value return response.value
elseif has_key(response, 'file')
return response
endif endif
endif endif
let cmd = let cmd =
@ -1349,22 +1212,23 @@ nnoremap <silent> <Plug>FireplaceDjump :<C-U>exe <SID>Edit('edit', expand('<cwor
nnoremap <silent> <Plug>FireplaceDsplit :<C-U>exe <SID>Edit('split', expand('<cword>'))<CR> nnoremap <silent> <Plug>FireplaceDsplit :<C-U>exe <SID>Edit('split', expand('<cword>'))<CR>
nnoremap <silent> <Plug>FireplaceDtabjump :<C-U>exe <SID>Edit('tabedit', expand('<cword>'))<CR> nnoremap <silent> <Plug>FireplaceDtabjump :<C-U>exe <SID>Edit('tabedit', expand('<cword>'))<CR>
function! s:set_up_source() abort
setlocal define=^\\s*(def\\w*
command! -bar -buffer -nargs=1 -complete=customlist,fireplace#eval_complete Djump :exe s:Edit('edit', <q-args>)
command! -bar -buffer -nargs=1 -complete=customlist,fireplace#eval_complete Dsplit :exe s:Edit('split', <q-args>)
if get(g:, 'fireplace_no_maps') | return | endif
nmap <buffer> [<C-D> <Plug>FireplaceDjump
nmap <buffer> ]<C-D> <Plug>FireplaceDjump
nmap <buffer> <C-W><C-D> <Plug>FireplaceDsplit
nmap <buffer> <C-W>d <Plug>FireplaceDsplit
nmap <buffer> <C-W>gd <Plug>FireplaceDtabjump
endfunction
augroup fireplace_source augroup fireplace_source
autocmd! autocmd!
autocmd FileType clojure call s:set_up_source() autocmd FileType clojure setlocal includeexpr=tr(v:fname,'.-','/_')
autocmd FileType clojure
\ if expand('%:e') ==# 'cljs' |
\ setlocal suffixesadd=.cljs,.cljx,.clj,.java |
\ else |
\ setlocal suffixesadd=.clj,.cljx,.cljs,.java |
\ endif
autocmd FileType clojure setlocal define=^\\s*(def\\w*
autocmd FileType clojure command! -bar -buffer -nargs=1 -complete=customlist,fireplace#eval_complete Djump :exe s:Edit('edit', <q-args>)
autocmd FileType clojure command! -bar -buffer -nargs=1 -complete=customlist,fireplace#eval_complete Dsplit :exe s:Edit('split', <q-args>)
autocmd FileType clojure nmap <buffer> [<C-D> <Plug>FireplaceDjump
autocmd FileType clojure nmap <buffer> ]<C-D> <Plug>FireplaceDjump
autocmd FileType clojure nmap <buffer> <C-W><C-D> <Plug>FireplaceDsplit
autocmd FileType clojure nmap <buffer> <C-W>d <Plug>FireplaceDsplit
autocmd FileType clojure nmap <buffer> <C-W>gd <Plug>FireplaceDtabjump
augroup END augroup END
" Section: Go to file " Section: Go to file
@ -1374,7 +1238,7 @@ function! fireplace#findfile(path) abort
if a:path !~# '/' if a:path !~# '/'
let path = tr(a:path, '.-', '/_') let path = tr(a:path, '.-', '/_')
else else
let path = substitute(a:path, '^/', '', '') let path = substitute(a:path, '^/', '')
endif endif
let resource = fireplace#findresource(path, fireplace#path(), 0, &suffixesadd) let resource = fireplace#findresource(path, fireplace#path(), 0, &suffixesadd)
if !empty(resource) if !empty(resource)
@ -1387,171 +1251,74 @@ function! fireplace#findfile(path) abort
return '' return ''
endfunction endfunction
let s:iskeyword = '[[:alnum:]_=?!#$%&*+|./<>:-]' function! s:GF(cmd, file) abort
let s:token = '^\%(#"\%(\\\@<!\%(\\\\\)*\\"\|[^"]\)*"\|"\%(\\.\|[^"]\)*"\|[[:space:],]\+\|\%(;\|#!\)[^'."\n".']*\|\~@\|#[[:punct:]]\|'.s:iskeyword.'\+\|\\\%(space\|tab\|newline\|return\|.\)\|.\)' if a:file =~# '^[^/]*/[^/.]*$' && a:file =~# '^\k\+$'
function! s:read_token(str, pos) abort let [file, jump] = split(a:file, "/")
let pos = a:pos if file !~# '\.'
let match = ' ' try
while match =~# '^[[:space:],;]' let file = fireplace#evalparse('((ns-aliases *ns*) '.s:qsym(file).' '.s:qsym(file).')')
let match = matchstr(a:str, s:token, pos) catch /^Clojure:/
let pos += len(match) endtry
endwhile
if empty(match)
throw 'fireplace: Clojure parse error'
endif
return [match, pos]
endfunction
function! s:read(str, pos) abort
let [token, pos] = s:read_token(a:str, a:pos)
if token =~# '^#\=[[{(]'
let list = []
while index([')', ']', '}', ''], get(list, -1)) < 0
unlet token
let [token, pos] = s:read(a:str, pos)
call add(list, token)
endwhile
call remove(list, -1)
return [list, pos]
elseif token ==# '#_'
let pos = s:read(a:str, pos)[1]
return s:read(a:str, pos)
else
return [token, pos]
endif
endfunction
function! s:ns(...) abort
let buffer = a:0 ? a:1 : s:buf()
let head = getbufline(buffer, 1, 1000)
let blank = '^\s*\%(;.*\)\=$'
call filter(head, 'v:val !~# blank')
let keyword_group = '[A-Za-z0-9_?*!+/=<>.-]'
let lines = join(head, "\n")
let match = matchstr(lines, '\C^(\s*ns\s\+.*')
if len(match)
try
return s:read(match, 0)[0]
catch /^fireplace: Clojure parse error$/
endtry
endif
return []
endfunction
function! fireplace#resolve_alias(name) abort
if a:name =~# '\.'
return a:name
endif
let _ = {}
for refs in filter(copy(s:ns()), 'type(v:val) == type([])')
if a:name =~# '^\u' && get(refs, 0) is# ':import'
for _.ref in refs
if type(_.ref) == type([]) && index(_.ref, a:name) > 0
return _.ref[0] . '.' . a:name
elseif type(_.ref) == type('') && _.ref =~# '\.'.a:name.'$'
return _.ref
endif
endfor
endif endif
if get(refs, 0) is# ':require'
for _.ref in refs
if type(_.ref) == type([])
let i = index(_.ref, ':as')
if i > 0 && get(_.ref, i+1) ==# a:name
return _.ref[0]
endif
for nref in filter(copy(_.ref), 'type(v:val) == type([])')
let i = index(nref, ':as')
if i > 0 && get(nref, i+1) ==# a:name
return _.ref[0].'.'.nref[0]
endif
endfor
endif
endfor
endif
endfor
return a:name
endfunction
function! fireplace#cfile() abort
let file = expand('<cfile>')
if file =~# '^\w[[:alnum:]_/]*$' &&
\ synIDattr(synID(line("."),col("."),1),"name") =~# 'String'
let file = substitute(expand('%:p'), '[^\/:]*$', '', '').file
elseif file =~# '^[^/]*/[^/.]*$' && file =~# '^\k\+$'
let [file, jump] = split(file, "/")
let file = fireplace#resolve_alias(file)
if file !~# '\.' && fireplace#op_available('info')
let res = fireplace#message({'op': 'info', 'symbol': file})
let file = get(get(res, 0, {}), 'ns', file)
endif
let file = tr(file, '.-', '/_')
elseif file =~# '^\w[[:alnum:].-]*$'
let file = tr(fireplace#resolve_alias(file), '.-', '/_')
endif
if exists('jump')
return '+sil!dj\ ' . jump . ' ' . fnameescape(file)
else else
return fnameescape(file) let file = a:file
endif endif
endfunction let file = fireplace#findfile(file)
if file ==# ''
function! s:Find(find, edit) abort let v:errmsg = "Couldn't find file for ".a:file
let cfile = fireplace#cfile() return 'echoerr v:errmsg'
let prefix = matchstr(cfile, '^\%(+\%(\\.\|\S\)*\s\+\)')
let file = fireplace#findfile(expand(strpart(cfile, len(prefix))))
if file =~# '^zipfile:'
let setpath = 'let\ &l:path=getbufvar('.bufnr('').",'&path')"
if prefix =~# '^+[^+]'
let prefix = substitute(prefix, '+', '\="+".setpath."\\|"', '')
else
let prefix = '+'.setpath.' '.prefix
endif
endif
if len(file)
return (len(a:edit) ? a:edit . ' ' : '') . prefix . fnameescape(file)
else
return len(a:find) ? a:find . ' ' . cfile : "\<C-R>\<C-P>"
endif
endfunction
nnoremap <silent> <Plug>FireplaceEditFile :<C-U>exe <SID>Find('find','edit')<CR>
nnoremap <silent> <Plug>FireplaceSplitFile :<C-U>exe <SID>Find('sfind','split')<CR>
nnoremap <silent> <Plug>FireplaceTabeditFile :<C-U>exe <SID>Find('tabfind','tabedit')<CR>
function! s:set_up_go_to_file() abort
if expand('%:e') ==# 'cljs'
setlocal suffixesadd=.cljs,.cljc,.cljx,.clj,.java
else
setlocal suffixesadd=.clj,.cljc,.cljx,.cljs,.java
endif
cmap <buffer><script><expr> <Plug><cfile> substitute(fireplace#cfile(),'^$',"\022\006",'')
cmap <buffer><script><expr> <Plug><cpath> <SID>Find('','')
if get(g:, 'fireplace_no_maps') | return | endif
cmap <buffer> <C-R><C-F> <Plug><cfile>
cmap <buffer> <C-R><C-P> <Plug><cpath>
if empty(mapcheck('gf', 'n'))
nmap <buffer> gf <Plug>FireplaceEditFile
endif
if empty(mapcheck('<C-W>f', 'n'))
nmap <buffer> <C-W>f <Plug>FireplaceSplitFile
endif
if empty(mapcheck('<C-W><C-F>', 'n'))
nmap <buffer> <C-W><C-F> <Plug>FireplaceSplitFile
endif
if empty(mapcheck('<C-W>gf', 'n'))
nmap <buffer> <C-W>gf <Plug>FireplaceTabeditFile
endif endif
return a:cmd .
\ (exists('jump') ? ' +sil!\ djump\ ' . jump : '') .
\ ' ' . fnameescape(file) .
\ '| let &l:path = ' . string(&l:path)
endfunction endfunction
augroup fireplace_go_to_file augroup fireplace_go_to_file
autocmd! autocmd!
autocmd FileType clojure call s:set_up_go_to_file() autocmd FileType clojure nnoremap <silent><buffer> gf :<C-U>exe <SID>GF('edit', expand('<cfile>'))<CR>
autocmd FileType clojure nnoremap <silent><buffer> <C-W>f :<C-U>exe <SID>GF('split', expand('<cfile>'))<CR>
autocmd FileType clojure nnoremap <silent><buffer> <C-W><C-F> :<C-U>exe <SID>GF('split', expand('<cfile>'))<CR>
autocmd FileType clojure nnoremap <silent><buffer> <C-W>gf :<C-U>exe <SID>GF('tabedit', expand('<cfile>'))<CR>
augroup END augroup END
" Section: Documentation " Section: Documentation
function! s:buffer_path(...) abort
let buffer = a:0 ? a:1 : s:buf()
if getbufvar(buffer, '&buftype') =~# '^no'
return ''
endif
let path = substitute(fnamemodify(bufname(buffer), ':p'), '\C^zipfile:\(.*\)::', '\1/', '')
for dir in fireplace#path(buffer)
if dir !=# '' && path[0 : strlen(dir)-1] ==# dir && path[strlen(dir)] =~# '[\/]'
return path[strlen(dir)+1:-1]
endif
endfor
return ''
endfunction
function! fireplace#ns(...) abort
let buffer = a:0 ? a:1 : s:buf()
if !empty(getbufvar(buffer, 'fireplace_ns'))
return getbufvar(buffer, 'fireplace_ns')
endif
let head = getbufline(buffer, 1, 500)
let blank = '^\s*\%(;.*\)\=$'
call filter(head, 'v:val !~# blank')
let keyword_group = '[A-Za-z0-9_?*!+/=<>.-]'
let lines = join(head[0:49], ' ')
let lines = substitute(lines, '"\%(\\.\|[^"]\)*"\|\\.', '', 'g')
let lines = substitute(lines, '\^\={[^{}]*}', '', '')
let lines = substitute(lines, '\^:'.keyword_group.'\+', '', 'g')
let ns = matchstr(lines, '\C^(\s*\%(in-ns\s*''\|ns\s\+\)\zs'.keyword_group.'\+\ze')
if ns !=# ''
return ns
endif
let path = s:buffer_path(buffer)
return s:to_ns(path ==# '' ? fireplace#client(buffer).user_ns() : path)
endfunction
function! s:Lookup(ns, macro, arg) abort function! s:Lookup(ns, macro, arg) abort
try try
let response = s:eval('('.a:ns.'/'.a:macro.' '.a:arg.')', {'session': 0}) let response = s:eval('('.a:ns.'/'.a:macro.' '.a:arg.')', {'session': 0})
@ -1594,7 +1361,7 @@ endfunction
function! s:K() abort function! s:K() abort
let word = expand('<cword>') let word = expand('<cword>')
let java_candidate = matchstr(word, '^\%(\w\+\.\)*\u\l[[:alnum:]$]*\ze\%(\.\|\/\w\+\)\=$') let java_candidate = matchstr(word, '^\%(\w\+\.\)*\u\l\w*\ze\%(\.\|\/\w\+\)\=$')
if java_candidate !=# '' if java_candidate !=# ''
return 'Javadoc '.java_candidate return 'Javadoc '.java_candidate
else else
@ -1605,37 +1372,30 @@ endfunction
nnoremap <Plug>FireplaceK :<C-R>=<SID>K()<CR><CR> nnoremap <Plug>FireplaceK :<C-R>=<SID>K()<CR><CR>
nnoremap <Plug>FireplaceSource :Source <C-R><C-W><CR> nnoremap <Plug>FireplaceSource :Source <C-R><C-W><CR>
function! s:set_up_doc() abort
command! -buffer -nargs=1 FindDoc :exe s:Lookup('clojure.repl', 'find-doc', printf('#"%s"', <q-args>))
command! -buffer -bar -nargs=1 Javadoc :exe s:Lookup('clojure.java.javadoc', 'javadoc', <q-args>)
command! -buffer -bar -nargs=1 -complete=customlist,fireplace#eval_complete Doc :exe s:Doc(<q-args>)
command! -buffer -bar -nargs=1 -complete=customlist,fireplace#eval_complete Source :exe s:Lookup('clojure.repl', 'source', <q-args>)
setlocal keywordprg=:Doc
if get(g:, 'fireplace_no_maps') | return | endif
if empty(mapcheck('K', 'n'))
nmap <buffer> K <Plug>FireplaceK
endif
nmap <buffer> [d <Plug>FireplaceSource
nmap <buffer> ]d <Plug>FireplaceSource
endfunction
augroup fireplace_doc augroup fireplace_doc
autocmd! autocmd!
autocmd FileType clojure call s:set_up_doc() autocmd FileType clojure setlocal keywordprg=:Doc |
\ if empty(mapcheck('K', 'n')) |
\ nmap <buffer> K <Plug>FireplaceK|
\ endif
autocmd FileType clojure nmap <buffer> [d <Plug>FireplaceSource
autocmd FileType clojure nmap <buffer> ]d <Plug>FireplaceSource
autocmd FileType clojure command! -buffer -nargs=1 FindDoc :exe s:Lookup('clojure.repl', 'find-doc', printf('#"%s"', <q-args>))
autocmd FileType clojure command! -buffer -bar -nargs=1 Javadoc :exe s:Lookup('clojure.java.javadoc', 'javadoc', <q-args>)
autocmd FileType clojure command! -buffer -bar -nargs=1 -complete=customlist,fireplace#eval_complete Doc :exe s:Doc(<q-args>)
autocmd FileType clojure command! -buffer -bar -nargs=1 -complete=customlist,fireplace#eval_complete Source :exe s:Lookup('clojure.repl', 'source', <q-args>)
augroup END augroup END
" Section: Tests " Section: Tests
function! fireplace#capture_test_run(expr, ...) abort function! fireplace#capture_test_run(expr, ...) abort
let expr = '(try' let expr = '(require ''clojure.test) '
\ . ' (require ''clojure.test)' \ . '(try '
\ . ' (binding [clojure.test/report (fn [m]' \ . '(binding [clojure.test/report (fn [m]'
\ . ' (case (:type m)' \ . ' (case (:type m)'
\ . ' (:fail :error)' \ . ' (:fail :error)'
\ . ' (let [{file :file line :line test :name} (meta (last clojure.test/*testing-vars*))]' \ . ' (let [{file :file line :line test :name} (meta (last clojure.test/*testing-vars*))]'
\ . ' (clojure.test/with-test-out' \ . ' (clojure.test/with-test-out'
\ . ' (clojure.test/inc-report-counter (:type m))'
\ . ' (println (clojure.string/join "\t" [file line (name (:type m)) test]))' \ . ' (println (clojure.string/join "\t" [file line (name (:type m)) test]))'
\ . ' (when (seq clojure.test/*testing-contexts*) (println (clojure.test/testing-contexts-str)))' \ . ' (when (seq clojure.test/*testing-contexts*) (println (clojure.test/testing-contexts-str)))'
\ . ' (when-let [message (:message m)] (println message))' \ . ' (when-let [message (:message m)] (println message))'
@ -1652,7 +1412,7 @@ function! fireplace#capture_test_run(expr, ...) abort
call setqflist(fireplace#quickfix_for(get(response, 'stacktrace', []))) call setqflist(fireplace#quickfix_for(get(response, 'stacktrace', [])))
return s:output_response(response) return s:output_response(response)
endif endif
for line in split(response.out, "\r\\=\n") for line in split(response.out, "\n")
if line =~# '\t.*\t.*\t' if line =~# '\t.*\t.*\t'
let entry = {'text': line} let entry = {'text': line}
let [resource, lnum, type, name] = split(line, "\t", 1) let [resource, lnum, type, name] = split(line, "\t", 1)
@ -1686,57 +1446,27 @@ function! fireplace#capture_test_run(expr, ...) abort
endfor endfor
endfunction endfunction
function! s:RunTests(bang, count, ...) abort function! s:RunTests(bang, ...) abort
if &autowrite || &autowriteall if &autowrite || &autowriteall
silent! wall silent! wall
endif endif
if a:count < 0 let pre = ''
let pre = '' if a:bang && a:0
if a:0 let expr = '(clojure.test/run-all-tests #"'.join(a:000, '|').'")'
let expr = ['(clojure.test/run-all-tests #"'.join(a:000, '|').'")'] elseif a:bang
else let expr = '(clojure.test/run-all-tests)'
let expr = ['(clojure.test/run-all-tests)']
endif
else else
if a:0 && a:000 !=# [fireplace#ns()] let reqs = map(copy(a:000), '"''".v:val')
let args = a:000 let pre = '(clojure.core/require '.join(empty(a:000) ? ["'".fireplace#ns()] : reqs, ' ').' :reload) '
else let expr = join(['(clojure.test/run-tests'] + reqs, ' ').')'
let args = [fireplace#ns()]
if a:count
let pattern = '^\s*(def\k*\s\+\(\h\k*\)'
let line = search(pattern, 'bcWn')
if line
let args[0] .= '/' . matchlist(getline(line), pattern)[1]
endif
endif
endif
let reqs = map(copy(args), '"''".v:val')
let pre = '(clojure.core/require '.substitute(join(reqs, ' '), '/\k\+', '', 'g').' :reload) '
let expr = []
let vars = filter(copy(reqs), 'v:val =~# "/"')
let nses = filter(copy(reqs), 'v:val !~# "/"')
if len(vars) == 1
call add(expr, '(clojure.test/test-vars [#' . vars[0] . '])')
elseif !empty(vars)
call add(expr, join(['(clojure.test/test-vars'] + map(vars, '"#".v:val'), ' ').')')
endif
if !empty(nses)
call add(expr, join(['(clojure.test/run-tests'] + nses, ' ').')')
endif
endif endif
call fireplace#capture_test_run(join(expr, ' '), pre) call fireplace#capture_test_run(expr, pre)
echo join(expr, ' ') echo expr
endfunction endfunction
function! s:set_up_tests() abort augroup fireplace_command
command! -buffer -bar -bang -range=0 -nargs=*
\ -complete=customlist,fireplace#ns_complete RunTests
\ call s:RunTests(<bang>0, <line1> == 0 ? -1 : <count>, <f-args>)
command! -buffer -bang -nargs=* RunAllTests
\ call s:RunTests(<bang>0, -1, <f-args>)
endfunction
augroup fireplace_tests
autocmd! autocmd!
autocmd FileType clojure call s:set_up_tests() autocmd FileType clojure command! -buffer -bar -bang -nargs=*
\ -complete=customlist,fireplace#ns_complete RunTests
\ call s:RunTests(<bang>0, <f-args>)
augroup END augroup END

View File

@ -1,13 +1,13 @@
" Location: plugin/fireplace/zip.vim " fireplace/zip.vim: zip.vim monkey patch to allow access from quickfix
" Maintainer: Tim Pope <http://tpo.pe>
if exists("g:loaded_zip") || &cp || v:version >= 704 if exists("g:loaded_zip") || &cp
finish finish
endif endif
runtime! autoload/zip.vim runtime! autoload/zip.vim
" Patched to allow loading from the quickfix list. The version that ships " Copied and pasted verbatim from autoload/zip.vim.
" with Vim 7.4 already has this change.
fun! zip#Read(fname,mode) fun! zip#Read(fname,mode)
" call Dfunc("zip#Read(fname<".a:fname.">,mode=".a:mode.")") " call Dfunc("zip#Read(fname<".a:fname.">,mode=".a:mode.")")