Compare commits

..

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

8 changed files with 539 additions and 929 deletions

View File

@ -4,14 +4,14 @@ 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 Fireplace.vim doesn't provide indenting or syntax highlighting, so you'll want
make do with eval, which mostly works.) Next, fireplace.vim doesn't provide [a set of Clojure runtime files](https://github.com/guns/vim-clojure-static).
indenting or syntax highlighting, so you'll want [a set of Clojure runtime You might also want [classpath.vim][] to run code when no REPL is available.
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
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
installing [pathogen.vim](https://github.com/tpope/vim-pathogen), and installing [pathogen.vim](https://github.com/tpope/vim-pathogen), and
@ -19,6 +19,8 @@ then simply copy and paste:
cd ~/.vim/bundle cd ~/.vim/bundle
git clone git://github.com/tpope/vim-fireplace.git git clone git://github.com/tpope/vim-fireplace.git
git clone git://github.com/tpope/vim-classpath.git
git clone git://github.com/guns/vim-clojure-static.git
Once help tags have been generated, you can view the manual with Once help tags have been generated, you can view the manual with
`:help fireplace`. `:help fireplace`.
@ -30,24 +32,22 @@ This list isn't exhaustive; see the `:help` for details.
### Transparent setup ### Transparent setup
Fireplace.vim talks to nREPL. With Leiningen, it connects automatically based Fireplace.vim talks to nREPL. With Leiningen, it connects automatically based
on `.nrepl-port`, otherwise it's just a `:Connect` away. You can connect to on `target/repl-port`, otherwise it's just a `:Connect` away. You can connect
multiple instances of nREPL for different projects, and it will use the right to multiple instances of nREPL for different projects, and it will use the
one automatically. ClojureScript support is just as seamless with right one automatically. ClojureScript support is just as seamless with
[Piggieback][]. [Piggieback][].
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 [classpath.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`, using a class path based on
class path based on your Leiningen config. It's a bit slow, but a two-second your Leiningen or Maven config. It's a bit slow, but a two-second delay is
delay is vastly preferable to being forced out of my flow for a single vastly preferable to being forced out of my flow for a single command, in my
command, in my book. book.
[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
### Not quite a REPL ### Not quite a REPL
@ -68,24 +68,20 @@ cursor. `cqc` gives you a blank line in insert mode.
Standard stuff here. `:Eval` evaluates a range (`:%Eval` gets the whole Standard stuff here. `:Eval` evaluates a range (`:%Eval` gets the whole
file), `:Require` requires a namespace with `:reload` (`:Require!` does file), `:Require` requires a namespace with `:reload` (`:Require!` does
`:reload-all`), either the current buffer or a given argument. `:RunTests` `:reload-all`), either the current buffer or a given argument. There's a `cp`
kicks off `(clojure.test/run-tests)` and loads the results into the quickfix operator that evaluates a given motion (`cpp` for the outermost form under the
list. cursor). `cm` and `c1m` are similar, but they only run
`clojure.walk/macroexpand-all` and `macroexpand-1` instead of evaluating the
There's a `cp` operator that evaluates a given motion (`cpp` for the form entirely.
innermost form under the cursor). `cm` and `c1m` are similar, but they only
run `clojure.walk/macroexpand-all` and `macroexpand-1` instead of evaluating
the form entirely.
Any failed evaluation loads the stack trace into the location list, which Any failed evaluation loads the stack trace into the location list, which
can be easily accessed with `:lopen`. can be easily accessed with `:lopen`.
### Navigating and Comprehending ### Navigating and Comprehending
I was brand new to Clojure when I started this plugin, so stuff that helped me I'm new to Clojure, so stuff that helps me understand code is a top priority.
understand code was a top priority.
* `:Source`, `:Doc`, and `:FindDoc`, which map to the underlying * `:Source`, `:Doc`, `:FindDoc`, and `:Apropos`, which map to the underlying
`clojure.repl` macro (with tab complete, of course). `clojure.repl` macro (with tab complete, of course).
* `K` is mapped to look up the symbol under the cursor with `doc`. * `K` is mapped to look up the symbol under the cursor with `doc`.
@ -108,13 +104,15 @@ 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][]. See the [classpath.vim FAQ][]. You can uninstall classpath.vim if you only
care about nREPL support.
[classpath.vim FAQ]: https://github.com/tpope/vim-classpath#FAQ
## 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
@ -33,33 +33,14 @@ function! fireplace#nrepl#for(transport) abort
let client = copy(s:nrepl) let client = copy(s:nrepl)
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})
if get(client.describe.versions.nrepl, 'major', -1) == 0 &&
\ client.describe.versions.nrepl.minor < 2
throw 'nREPL: 0.2.0 or higher required'
endif
" Handle boot, which sets a fake.class.path entry
let response = client.process({'op': 'eval', 'code': let response = client.process({'op': 'eval', 'code':
\ '[(System/getProperty "path.separator") (System/getProperty "fake.class.path")]', 'session': ''}) \ '(do (println "success") (symbol (str (System/getProperty "path.separator") (System/getProperty "java.class.path"))))'})
let cpath = response.value[-1][5:-2] let client._path = response.value[-1]
if cpath !=# 'nil' if has_key(response, 'out')
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]
if type(get(response, 'classpath')) == type([])
let client._path = response.classpath
endif
endif
if !has_key(client, '_path')
let response = client.process({'op': 'eval', 'code':
\ '[(System/getProperty "path.separator") (System/getProperty "java.class.path")]', 'session': ''})
let client._path = split(eval(response.value[-1][5:-2]), response.value[-1][2])
endif
let g:fireplace_nrepl_sessions[client.session] = client let g:fireplace_nrepl_sessions[client.session] = client
else
unlet client.session
endif
return client return client
endfunction endfunction
@ -87,7 +68,7 @@ function! s:nrepl_clone() dict abort
endfunction endfunction
function! s:nrepl_path() dict abort function! s:nrepl_path() dict abort
return self._path return split(self._path[1:-1], self._path[0])
endfunction endfunction
function! fireplace#nrepl#combine(responses) function! fireplace#nrepl#combine(responses)
@ -138,11 +119,7 @@ function! s:nrepl_eval(expr, ...) dict abort
if has_key(options, 'session') if has_key(options, 'session')
let msg.session = options.session let msg.session = options.session
endif endif
if has_key(options, 'id')
let msg.id = options.id
else
let msg.id = fireplace#nrepl#next_id() let msg.id = fireplace#nrepl#next_id()
endif
if has_key(options, 'file_path') if has_key(options, 'file_path')
let msg.op = 'load-file' let msg.op = 'load-file'
let msg['file-path'] = options.file_path let msg['file-path'] = options.file_path
@ -157,21 +134,18 @@ 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 endif
throw 'Clojure: Interrupt' throw 'Clojure: Interrupt'
endif
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
if has_key(response, 'ex') && !empty(get(msg, 'session', 1)) if has_key(response, 'ex') && !empty(get(msg, 'session', 1))
let response.stacktrace = s:extract_last_stacktrace(self, get(msg, 'session', self.session)) let response.stacktrace = s:extract_last_stacktrace(self)
endif endif
if has_key(response, 'value') if has_key(response, 'value')
@ -180,28 +154,12 @@ function! s:nrepl_eval(expr, ...) dict abort
return response return response
endfunction endfunction
function! s:extract_last_stacktrace(nrepl, session) abort function! s:extract_last_stacktrace(nrepl) abort
if a:nrepl.has_op('stacktrace') let format_st = '(clojure.core/symbol (clojure.core/str "\n\b" (clojure.core/apply clojure.core/str (clojure.core/interleave (clojure.core/repeat "\n") (clojure.core/map clojure.core/str (.getStackTrace *e)))) "\n\b\n"))'
let stacktrace = a:nrepl.message({'op': 'stacktrace', 'session': a:session}) let stacktrace = split(get(split(a:nrepl.process({'op': 'eval', 'code': '['.format_st.' *3 *2 *1]', 'session': a:nrepl.session}).value[0], "\n\b\n"), 1, ""), "\n")
if len(stacktrace) > 0 && has_key(stacktrace[0], 'stacktrace') call a:nrepl.message({'op': 'eval', 'code': '(nth *1 1)', 'session': a:nrepl.session})
let stacktrace = stacktrace[0].stacktrace call a:nrepl.message({'op': 'eval', 'code': '(nth *2 2)', 'session': a:nrepl.session})
endif call a:nrepl.message({'op': 'eval', 'code': '(nth *3 3)', 'session': a:nrepl.session})
call filter(stacktrace, 'has_key(v:val, "file")')
if !empty(stacktrace)
return map(stacktrace, 'v:val.class.".".v:val.method."(".v:val.file.":".v:val.line.")"')
endif
endif
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})
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': '(*2 2)', 'ns': 'user', 'session': a:session})
call a:nrepl.message({'op': 'eval', 'code': '(*3 3)', 'ns': 'user', 'session': a:session})
return stacktrace return stacktrace
endfunction endfunction
@ -213,26 +171,27 @@ 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(self, 'session')
if &verbose
echohl WarningMSG
echo "nREPL: server has bug preventing session support"
echohl None
endif
unlet! msg.session
elseif !has_key(msg, 'session') elseif !has_key(msg, 'session')
let msg.session = self.session let msg.session = self.session
endif endif
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(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:callback[0], [response] + a:callback[1:-1]) call call(a:fn, [response])
catch
endtry
endfunction endfunction
function! s:nrepl_call(msg, ...) dict abort function! s:nrepl_call(msg, ...) dict abort
@ -247,10 +206,6 @@ function! s:nrepl_message(msg, ...) dict abort
return call(self.call, [msg, ['done'], sel] + a:000, self) return call(self.call, [msg, ['done'], sel] + a:000, self)
endfunction endfunction
function! s:nrepl_has_op(op) dict abort
return has_key(self.describe.ops, a:op)
endfunction
let s:nrepl = { let s:nrepl = {
\ 'close': s:function('s:nrepl_close'), \ 'close': s:function('s:nrepl_close'),
\ 'clone': s:function('s:nrepl_clone'), \ 'clone': s:function('s:nrepl_clone'),
@ -258,6 +213,5 @@ let s:nrepl = {
\ 'call': s:function('s:nrepl_call'), \ 'call': s:function('s:nrepl_call'),
\ 'message': s:function('s:nrepl_message'), \ 'message': s:function('s:nrepl_message'),
\ 'eval': s:function('s:nrepl_eval'), \ 'eval': s:function('s:nrepl_eval'),
\ 'has_op': s:function('s:nrepl_has_op'),
\ 'path': s:function('s:nrepl_path'), \ 'path': s:function('s:nrepl_path'),
\ 'process': s:function('s:nrepl_process')} \ 'process': s:function('s:nrepl_process')}

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
@ -13,19 +14,15 @@ endfunction
" Bencode {{{1 " Bencode {{{1
function! fireplace#nrepl_connection#bencode(value) abort function! nrepl#fireplace_connection#bencode(value) abort
if type(a:value) == type(0) if type(a:value) == type(0)
return 'i'.a:value.'e' return 'i'.a:value.'e'
elseif type(a:value) == type('') elseif type(a:value) == type('')
return strlen(a:value).':'.a:value return strlen(a:value).':'.a:value
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),'nrepl#fireplace_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),'nrepl#fireplace_connection#bencode(v:key).nrepl#fireplace_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
@ -37,7 +34,14 @@ function! s:shellesc(arg) abort
if a:arg =~ '^[A-Za-z0-9_/.-]\+$' if a:arg =~ '^[A-Za-z0-9_/.-]\+$'
return a:arg return a:arg
elseif &shell =~# 'cmd' elseif &shell =~# 'cmd'
throw 'Python interface not working. See :help python-dynamic' if &shellxquote ==# '"'
return '"' . substitute(a:arg, '"', '""', 'g') . '"'
else
let esc = exists('+shellxescape') ? &shellxescape : '"&|<>()@^'
return &shellxquote .
\ substitute(a:arg, '['.esc.']', '^&', 'g') .
\ get({'(': ')', '"(': ')"'}, &shellxquote, &shellxquote)
endif
else else
let escaped = shellescape(a:arg) let escaped = shellescape(a:arg)
if &shell =~# 'sh' && &shell !~# 'csh' if &shell =~# 'sh' && &shell !~# 'csh'
@ -57,11 +61,11 @@ function! s:id() abort
return 'fireplace-'.hostname().'-'.s:vim_id.'-'.s:id return 'fireplace-'.hostname().'-'.s:vim_id.'-'.s:id
endfunction endfunction
function! fireplace#nrepl_connection#prompt() abort function! nrepl#fireplace_connection#prompt() abort
return fireplace#input_host_port() return fireplace#input_host_port()
endfunction endfunction
function! fireplace#nrepl_connection#open(arg) abort function! nrepl#fireplace_connection#open(arg) abort
if a:arg =~# '^\d\+$' if a:arg =~# '^\d\+$'
let host = 'localhost' let host = 'localhost'
let port = a:arg let port = a:arg
@ -91,7 +95,7 @@ function! s:nrepl_transport_command(cmd, args) dict abort
\ . ' ' . s:shellesc(self.port) \ . ' ' . s:shellesc(self.port)
\ . ' ' . s:shellesc(s:keepalive) \ . ' ' . s:shellesc(s:keepalive)
\ . ' ' . s:shellesc(a:cmd) \ . ' ' . s:shellesc(a:cmd)
\ . ' ' . join(map(copy(a:args), 's:shellesc(fireplace#nrepl_connection#bencode(v:val))'), ' ') \ . ' ' . join(map(copy(a:args), 's:shellesc(nrepl#fireplace_connection#bencode(v:val))'), ' ')
endfunction endfunction
function! s:nrepl_transport_dispatch(cmd, ...) dict abort function! s:nrepl_transport_dispatch(cmd, ...) dict abort
@ -104,12 +108,12 @@ function! s:nrepl_transport_dispatch(cmd, ...) dict abort
endfunction endfunction
function! s:nrepl_transport_call(msg, terms, sels, ...) dict abort function! s:nrepl_transport_call(msg, terms, sels, ...) dict abort
let payload = fireplace#nrepl_connection#bencode(a:msg) let payload = nrepl#fireplace_connection#bencode(a:msg)
let response = self.dispatch('call', payload, a:terms, a:sels) let response = self.dispatch('call', payload, a:terms, a:sels)
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,fireplace

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|)
@ -6,8 +6,7 @@ License: Same terms as Vim itself (see |license|)
This plugin is only available if 'compatible' is not set. This plugin is only available if 'compatible' is not set.
*fireplace* *fireplace*
While not strictly necessary, this plugin works best with the middleware You need Clojure runtime files to use this plugin. Try vim-clojure-static.
provided by <https://github.com/clojure-emacs/cider-nrepl>.
CONNECTING TO A REPL *fireplace-connect* CONNECTING TO A REPL *fireplace-connect*
@ -23,31 +22,35 @@ you can connect by hand.
REPL server. REPL server.
The REPL is used for the commands below. If no REPL is found for the current The REPL is used for the commands below. If no REPL is found for the current
buffer and 'path' contains at least one jar file, java (or $JAVA_CMD) is buffer and classpath.vim is installed, java (or $JAVA_CMD) is invoked
invoked directly, which can be quite slow depending on your setup. directly, which can be quite slow depending on your setup.
The only adapter shipped with fireplace.vim is for nREPL. You need either The only adapter shipped with fireplace.vim is for nREPL. You need either
|if_pyth| or the python command in your PATH. |if_pyth| or the python command in your PATH.
*fireplace-piggieback* *fireplace-clojurescript* *fireplace-piggieback* *fireplace-clojurescript*
ClojureScript can be evaled with Piggieback if the appropriate nREPL ClojureScript is can be evaled with Piggieback if the appropriate nREPL
middleware is loaded: https://github.com/cemerick/piggieback. Be aware that middleware is loaded. https://github.com/cemerick/piggieback. Be aware that
your ClojureScript files must be available on the classpath for this to work your ClojureScript files must be available on the classpath for this to work
properly, and that not all operations are supported. properly.
*fireplace-:Piggieback* *fireplace-:Piggieback*
:Piggieback [{env}] Create a new nREPL session and invoke :Piggieback [{env}] Create a new nREPL session and invoke
cemerick.piggieback/cljs-repl with the given or cemerick.piggieback/cljs-repl with the given or
default (Rhino) environment. This will also happen default (Rhino) environment. This will also happen
automatically on first eval in a ClojureScript buffer automatically on first eval in a ClojureScript buffer
if not invoked explicitly. If {env} is a number, the if not invoked explicitly.
piggieback repl-env will will use a cljs.repl.browser
(rather than a Rhino) env with the port set to the
number provided.
:Piggieback! Terminate the most recently created piggieback :Piggieback! Terminate the most recently created piggieback
session. session.
LEININGEN *fireplace-leiningen*
In addition to automatic repl connection, Clojure buffers in a Leiningen
project will automatically have their 'makeprg' set to lein and 'efm' set to
"%+G,fireplace". This combination enables `:make test` to run `lein test` and
parse the stacktraces in the results.
DOCUMENTATION *fireplace-documentation* DOCUMENTATION *fireplace-documentation*
*fireplace-:Doc* *fireplace-:Doc*
@ -57,16 +60,19 @@ DOCUMENTATION *fireplace-documentation*
:Javadoc {class} Open the java docs for the given class in a browser. :Javadoc {class} Open the java docs for the given class in a browser.
*fireplace-K* *fireplace-K*
K Look up docs for symbol under cursor. K Look up docs for keyword under cursor.
*fireplace-:FindDoc* *fireplace-:FindDoc*
:FindDoc {arg} Wrapper around (clojure.repl/find-doc ...). :FindDoc {arg} Wrapper around (clojure.repl/find-doc ...).
*fireplace-:Apropos*
:Apropos {arg} Wrapper around (clojure.repl/apropos ...).
*fireplace-:Source* *fireplace-:Source*
:Source {symbol} Show the source for the given symbol. :Source {symbol} Show the source for the given symbol.
*fireplace-[d* *fireplace-[d*
[d Show source for symbol under cursor. [d Show source for keyword under cursor.
]d ]d
NAVIGATING *fireplace-navigating* NAVIGATING *fireplace-navigating*
@ -75,11 +81,11 @@ These commands will never use a remote REPL, only a local one, as file paths
on a remote server wouldn't be very useful locally. on a remote server wouldn't be very useful locally.
*fireplace-[_CTRL-D* *fireplace-[_CTRL-D*
[<C-D> Jump to the source of the symbol under the cursor. [<C-D> Jump to the source of the keyword under the cursor.
]<C-D> ]<C-D>
*fireplace-CTRL-W_CTRL-D* *fireplace-CTRL-W_CTRL-D*
<C-W><C-D> Jump to the source of the symbol under the cursor in <C-W><C-D> Jump to the source of the keyword under the cursor in
<C-W>d a split. <C-W>d a split.
*fireplace-gf* *fireplace-gf*
@ -92,6 +98,21 @@ gf Go to the file for the namespace under the cursor.
:Dsplit {symbol} Jump to the definition for the given symbol in a :Dsplit {symbol} Jump to the definition for the given symbol in a
split. split.
*fireplace-:A*
:A In a test file, edit the implementation, and vice
versa. Basically adds or removes -test from the end
of the current namespace and searches for it in the
class path.
*fireplace-:AS*
:AS Like :A, but in a split.
*fireplace-:AV*
:AV Like :A, but in a vertical split.
*fireplace-:AT*
:AT Like :A, but in a tab.
EVALUATING CODE *fireplace-eval* EVALUATING CODE *fireplace-eval*
All code is evaluated in the namespace of the current file, requiring it if All code is evaluated in the namespace of the current file, requiring it if
@ -106,7 +127,8 @@ stack trace is loaded into the |location-list|. Use |:lopen| to view it.
:Require! [ns] Require :reload-all the given/current namespace. :Require! [ns] Require :reload-all the given/current namespace.
*fireplace-:Eval* *fireplace-:Eval*
:Eval Eval/print the outermost form for the current line. :Eval Eval/print the outermost expression for the current
line.
:{range}Eval Eval/print the given range. :{range}Eval Eval/print the given range.
@ -119,25 +141,13 @@ stack trace is loaded into the |location-list|. Use |:lopen| to view it.
:[range]Eval! {expr} Eval the given expression and insert it after :[range]Eval! {expr} Eval the given expression and insert it after
the given range or current line. the given range or current line.
*fireplace-:RunTests*
:RunTests [ns] [...] Call clojure.test/run-tests on the given namespaces
and load the results into the quickfix list.
:[range]RunTests Call clojure.test/test-var on the var defined at or
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.
*fireplace-cp* *fireplace-cp*
cp{motion} Eval/print the code indicated by {motion}. cp{motion} Eval/print the code indicated by {motion}.
cpp Eval/print the innermost form at the cursor. cpp Eval/print the outermost form at the cursor.
*fireplace-cpr* *fireplace-cpr*
cpr :Require|RunTests cpr Eval a require :reload form.
*fireplace-c!* *fireplace-c!*
c!{motion} Eval/replace the code indicated by {motion}. c!{motion} Eval/replace the code indicated by {motion}.
@ -159,10 +169,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.

File diff suppressed because it is too large Load Diff

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.")")

View File

@ -4,10 +4,7 @@ import select
import socket import socket
import sys import sys
try: from StringIO import StringIO
from StringIO import StringIO
except ImportError:
from io import StringIO
def noop(): def noop():
pass pass
@ -49,12 +46,12 @@ def bdecode(f, char=None):
key = bdecode(f, char) key = bdecode(f, char)
d[key] = bdecode(f) d[key] = bdecode(f)
elif char == 'i': elif char == 'i':
i = '' i = 0
while True: while True:
char = f.read(1) char = f.read(1)
if char == 'e': if char == 'e':
return int(i) return i
i += char i = 10 * i + int(char)
elif char.isdigit(): elif char.isdigit():
i = int(char) i = int(char)
while True: while True:
@ -87,16 +84,13 @@ class Connection:
return self.socket.close() return self.socket.close()
def send(self, payload): def send(self, payload):
if sys.version_info[0] >= 3:
self.socket.sendall(bytes(payload, 'UTF-8'))
else:
self.socket.sendall(payload) self.socket.sendall(payload)
return '' return ''
def receive(self, char=None): def receive(self, char=None):
f = self.socket.makefile() while len(select.select([self.socket], [], [], 0.1)[0]) == 0:
while len(select.select([f], [], [], 0.1)[0]) == 0:
self.poll() self.poll()
f = self.socket.makefile()
try: try:
return bdecode(f) return bdecode(f)
finally: finally:
@ -124,8 +118,8 @@ def dispatch(host, port, poll, keepalive, command, *args):
def main(host, port, keepalive, command, *args): def main(host, port, keepalive, command, *args):
try: try:
sys.stdout.write(vim_encode(dispatch(host, port, noop, keepalive, command, *[bdecode(StringIO(arg)) for arg in args]))) sys.stdout.write(vim_encode(dispatch(host, port, noop, keepalive, command, *[bdecode(StringIO(arg)) for arg in args])))
except Exception: except Exception, e:
print((sys.exc_info()[1])) print(e)
exit(1) exit(1)
if __name__ == "__main__": if __name__ == "__main__":