Compare commits
151 Commits
dispatch_e
...
master
Author | SHA1 | Date |
---|---|---|
Tim Pope | 2bab337396 | |
Richard Hull | 0814dd0d2d | |
Tim Pope | b550ac6680 | |
Siyuan Ma | fd18e8481d | |
Tim Pope | fd94f70fff | |
Dominic Monroe | 2d5177abef | |
Tim Pope | 1c75b56ceb | |
Daniel Silva | f57537135a | |
Tim Pope | 8579a41a18 | |
Vitaliy Vlasov | 3474bd5d72 | |
Tim Pope | 3ffdb062c6 | |
Tim Pope | b1725f68a1 | |
Tim Pope | 7d500028e6 | |
Juho Teperi | df563ed15f | |
Tim Pope | 04a7f542f5 | |
Tim Pope | 3d9b9a59cd | |
Janko Marohnić | 9a770d3716 | |
Tim Pope | b3b54b8715 | |
Nicolas Berger | b50e74f342 | |
Tim Pope | 9f7b1844cf | |
kul | 74d392339c | |
Tim Pope | a1571cd258 | |
Tim Pope | f456f04b65 | |
Tim Pope | 09c80c6794 | |
Tim Pope | 459904381b | |
Tim Pope | 69bf9ef519 | |
Tim Pope | 1f478e401a | |
Tim Pope | cb3c270c99 | |
Tim Pope | 7b2ae78bd7 | |
Tim Pope | b0a540c68d | |
Tim Pope | 09eedd05af | |
Tim Pope | 89aee9c00c | |
Juho Teperi | c22e61c69b | |
Roger Gilliar | 13a21bff0f | |
Tim Pope | 1646a01b0b | |
Juho Teperi | aede23c46a | |
Tim Pope | 819438bdf4 | |
Juho Teperi | 9ccaea1f2b | |
Juho Teperi | 44e766d5a5 | |
Tim Pope | 49153a39fc | |
kul | 0aabcdd798 | |
Joshua Davey | 5866d0017a | |
Robert Pitts | 7cebf6847e | |
Tim Pope | 71e44af208 | |
Tim Pope | b999b09cd9 | |
Tim Pope | 506cf288bd | |
Tim Pope | 0ecd9ec587 | |
Tim Pope | 874505e9f2 | |
Tim Pope | 04ce1b64af | |
Tim Pope | db2e70ee3f | |
Tim Pope | 8f7a07cffd | |
Tim Pope | 97758acc16 | |
Tim Pope | eeccb69a2f | |
Tim Pope | c0e574387d | |
Tim Pope | fccb149148 | |
Tim Pope | c1416c89ba | |
Tim Pope | b256399f3f | |
Jonathan Henry | 142fab4e0f | |
Tim Pope | 06f6bc5de6 | |
Tim Pope | d6b3e1c67c | |
Tim Pope | ebb2933f4c | |
Tim Pope | 3e978e4cd4 | |
Tim Pope | a39092ebe3 | |
Tim Pope | 835fdedf5f | |
Tim Pope | e107b2ae17 | |
Tim Pope | 1dc5129c0e | |
Tim Pope | 712205e66a | |
Tim Pope | ffc41e86f3 | |
Tim Pope | 37e3a474c5 | |
Tim Pope | 1f36136346 | |
Tim Pope | ea15c81773 | |
Tim Pope | 25e18b5f82 | |
Tim Pope | a14328c1dc | |
Tim Pope | eae17cfb42 | |
Tim Pope | 845b362a17 | |
Tim Pope | a1eef3dda1 | |
Tim Pope | 0e42998a27 | |
Tim Pope | 9c78e32f4b | |
Tim Pope | fb6975bfdf | |
Tim Pope | 8defd6b17e | |
Tim Pope | 26e467c2e7 | |
Tim Pope | 6dbf627022 | |
Tim Pope | 5ff2eeae1c | |
Tim Pope | 94ff1464a4 | |
Tim Pope | f2b6a2101f | |
Tim Pope | b10259bcca | |
Tim Pope | bfdd052fc7 | |
Tim Pope | c657faaf4e | |
Tim Pope | e4b975eaec | |
Tim Pope | 2cbaacf0d0 | |
Tim Pope | 83a317c10b | |
Joshua Davey | e6c4b5547a | |
Tim Pope | 049005dec7 | |
Bohr Shaw | 88648b2578 | |
Tim Pope | 67078e0c34 | |
Joshua Davey | 99d93ceba1 | |
Tim Pope | 29af4adc46 | |
Tim Pope | ac88f17bb4 | |
Tim Pope | af14811869 | |
Tim Pope | 0b17709b56 | |
Tim Pope | fa7a19140b | |
Tim Pope | 6cea463c97 | |
Tim Pope | fff348ccd0 | |
Tim Pope | 020a10d06c | |
Tim Pope | afb036203e | |
Tim Pope | 58896e23fa | |
Tim Pope | 57c18b778a | |
Tim Pope | 0bc928f0fc | |
Tim Pope | 062256b9fd | |
Tim Pope | a2278afbdd | |
Tim Pope | 9eb5099ba1 | |
Tim Pope | 12386dc0c2 | |
Tim Pope | 05cbc742a1 | |
Tim Pope | e484ad6996 | |
Tim Pope | e974dd4766 | |
Tim Pope | 2d1f3088b2 | |
Tim Pope | f25003deef | |
Tim Pope | c0a4901181 | |
Tim Pope | 7b19c1b2f6 | |
Tim Pope | 672d3b5c82 | |
Tim Pope | 0936b3cb4f | |
Tim Pope | 05206aa2e9 | |
Tim Pope | 5f1cee19c0 | |
Tim Pope | c6e0d55143 | |
Tim Pope | 89acd66d6d | |
Tim Pope | feb8ebc976 | |
Tim Pope | f5ded81baf | |
Tim Pope | 238b526cf2 | |
Tim Pope | 9e826faff4 | |
Tim Pope | 79c2a718da | |
Tim Pope | c48adc045b | |
Tim Pope | bc8f3af299 | |
Tim Pope | 2dec3b49b2 | |
Tim Pope | ea1012e1be | |
Tim Pope | 916fc04ecb | |
Tim Pope | ead617d9c3 | |
Tim Pope | f43fa99703 | |
Tim Pope | 6130d01b33 | |
Tim Pope | b0f9fad9ec | |
Tim Pope | 4425618825 | |
Tim Pope | 092ab0f70e | |
Tim Pope | 73f9a3adf4 | |
Tim Pope | 6c13396262 | |
Tim Pope | 9a689480ef | |
Tim Pope | ab5eee34d8 | |
Tim Pope | 1bfb5aadcf | |
Tim Pope | ab6d9db216 | |
Tim Pope | 095ee57d12 | |
Tim Pope | da3f5857b5 | |
Tim Pope | d65eaa5068 | |
Tim Pope | 90b909b9f4 |
|
@ -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
|
||||||
|
|
||||||
Fireplace.vim doesn't provide indenting or syntax highlighting, so you'll want
|
First, set up [cider-nrepl][]. (If you skip this step, fireplace.vim will
|
||||||
[a set of Clojure runtime files](https://github.com/guns/vim-clojure-static).
|
make do with eval, which mostly works.) Next, fireplace.vim doesn't provide
|
||||||
You might also want [classpath.vim][] to run code when no REPL is available.
|
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
|
||||||
|
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,8 +19,6 @@ 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`.
|
||||||
|
@ -32,22 +30,24 @@ 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 `target/repl-port`, otherwise it's just a `:Connect` away. You can connect
|
on `.nrepl-port`, otherwise it's just a `:Connect` away. You can connect to
|
||||||
to multiple instances of nREPL for different projects, and it will use the
|
multiple instances of nREPL for different projects, and it will use the right
|
||||||
right one automatically. ClojureScript support is just as seamless with
|
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 [classpath.vim][]
|
Oh, and if you don't have an nREPL connection, installing [salve.vim][]
|
||||||
lets it fall back to using `java clojure.main`, using a class path based on
|
lets it fall back to using `java clojure.main` for some of the basics, using a
|
||||||
your Leiningen or Maven config. It's a bit slow, but a two-second delay is
|
class path based on your Leiningen config. It's a bit slow, but a two-second
|
||||||
vastly preferable to being forced out of my flow for a single command, in my
|
delay is vastly preferable to being forced out of my flow for a single
|
||||||
book.
|
command, in my 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,20 +68,24 @@ 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. There's a `cp`
|
`:reload-all`), either the current buffer or a given argument. `:RunTests`
|
||||||
operator that evaluates a given motion (`cpp` for the outermost form under the
|
kicks off `(clojure.test/run-tests)` and loads the results into the quickfix
|
||||||
cursor). `cm` and `c1m` are similar, but they only run
|
list.
|
||||||
`clojure.walk/macroexpand-all` and `macroexpand-1` instead of evaluating the
|
|
||||||
form entirely.
|
There's a `cp` operator that evaluates a given motion (`cpp` for the
|
||||||
|
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'm new to Clojure, so stuff that helps me understand code is a top priority.
|
I was brand new to Clojure when I started this plugin, so stuff that helped me
|
||||||
|
understand code was a top priority.
|
||||||
|
|
||||||
* `:Source`, `:Doc`, `:FindDoc`, and `:Apropos`, which map to the underlying
|
* `:Source`, `:Doc`, and `:FindDoc`, 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`.
|
||||||
|
@ -104,15 +108,13 @@ 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?
|
||||||
|
|
||||||
See the [classpath.vim FAQ][]. You can uninstall classpath.vim if you only
|
That's either [classpath.vim][] or [salve.vim][].
|
||||||
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 if
|
[GitHub](https://github.com/tpope/vim-fireplace) and vote for it on
|
||||||
|
[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).
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
" Fireplace nREPL session
|
" Location: autoload/nrepl/fireplace.vim
|
||||||
|
|
||||||
if exists("g:autoloaded_fireplace_nrepl")
|
if exists("g:autoloaded_fireplace_nrepl")
|
||||||
finish
|
finish
|
||||||
|
@ -33,14 +33,33 @@ 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 response = client.process({'op': 'eval', 'code':
|
let client.describe = client.process({'op': 'describe', 'verbose?': 1})
|
||||||
\ '(do (println "success") (symbol (str (System/getProperty "path.separator") (System/getProperty "java.class.path"))))'})
|
if get(client.describe.versions.nrepl, 'major', -1) == 0 &&
|
||||||
let client._path = response.value[-1]
|
\ client.describe.versions.nrepl.minor < 2
|
||||||
if has_key(response, 'out')
|
throw 'nREPL: 0.2.0 or higher required'
|
||||||
let g:fireplace_nrepl_sessions[client.session] = client
|
|
||||||
else
|
|
||||||
unlet client.session
|
|
||||||
endif
|
endif
|
||||||
|
" Handle boot, which sets a fake.class.path entry
|
||||||
|
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]
|
||||||
|
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
|
||||||
return client
|
return client
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
|
@ -68,7 +87,7 @@ function! s:nrepl_clone() dict abort
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
function! s:nrepl_path() dict abort
|
function! s:nrepl_path() dict abort
|
||||||
return split(self._path[1:-1], self._path[0])
|
return self._path
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
function! fireplace#nrepl#combine(responses)
|
function! fireplace#nrepl#combine(responses)
|
||||||
|
@ -119,7 +138,11 @@ 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
|
||||||
let msg.id = fireplace#nrepl#next_id()
|
if has_key(options, 'id')
|
||||||
|
let msg.id = options.id
|
||||||
|
else
|
||||||
|
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
|
||||||
|
@ -134,18 +157,21 @@ function! s:nrepl_eval(expr, ...) dict abort
|
||||||
endif
|
endif
|
||||||
try
|
try
|
||||||
let response = self.process(msg)
|
let response = self.process(msg)
|
||||||
catch /^Vim:Interrupt$/
|
finally
|
||||||
if has_key(msg, 'session')
|
if !exists('response')
|
||||||
call self.message({'op': 'interrupt', 'session': msg.session, 'interrupt-id': msg.id}, 'ignore')
|
let session = get(msg, 'session', self.session)
|
||||||
|
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') && !has_key(options, 'ns')
|
if has_key(response, 'ns') && empty(get(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)
|
let response.stacktrace = s:extract_last_stacktrace(self, get(msg, 'session', self.session))
|
||||||
endif
|
endif
|
||||||
|
|
||||||
if has_key(response, 'value')
|
if has_key(response, 'value')
|
||||||
|
@ -154,12 +180,28 @@ function! s:nrepl_eval(expr, ...) dict abort
|
||||||
return response
|
return response
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
function! s:extract_last_stacktrace(nrepl) abort
|
function! s:extract_last_stacktrace(nrepl, session) abort
|
||||||
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"))'
|
if a:nrepl.has_op('stacktrace')
|
||||||
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")
|
let stacktrace = a:nrepl.message({'op': 'stacktrace', 'session': a:session})
|
||||||
call a:nrepl.message({'op': 'eval', 'code': '(nth *1 1)', 'session': a:nrepl.session})
|
if len(stacktrace) > 0 && has_key(stacktrace[0], 'stacktrace')
|
||||||
call a:nrepl.message({'op': 'eval', 'code': '(nth *2 2)', 'session': a:nrepl.session})
|
let stacktrace = stacktrace[0].stacktrace
|
||||||
call a:nrepl.message({'op': 'eval', 'code': '(nth *3 3)', 'session': a:nrepl.session})
|
endif
|
||||||
|
|
||||||
|
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
|
||||||
|
|
||||||
|
@ -171,27 +213,26 @@ 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, fn)
|
function! fireplace#nrepl#callback(body, type, callback) abort
|
||||||
let response = {'body': a:body, 'type': a:type}
|
try
|
||||||
if has_key(a:body, 'session')
|
let response = {'body': a:body, 'type': a:type}
|
||||||
let response.session = g:fireplace_nrepl_sessions[a:body.session]
|
if has_key(g:fireplace_nrepl_sessions, get(a:body, 'session'))
|
||||||
endif
|
let response.session = g:fireplace_nrepl_sessions[a:body.session]
|
||||||
call call(a:fn, [response])
|
endif
|
||||||
|
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
|
||||||
|
@ -206,6 +247,10 @@ 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'),
|
||||||
|
@ -213,5 +258,6 @@ 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')}
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
" autoload/nrepl/fireplace_connection.vim
|
" Location: 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
|
||||||
|
@ -14,15 +13,19 @@ endfunction
|
||||||
|
|
||||||
" Bencode {{{1
|
" Bencode {{{1
|
||||||
|
|
||||||
function! nrepl#fireplace_connection#bencode(value) abort
|
function! fireplace#nrepl_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),'nrepl#fireplace_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(values(map(copy(a:value),'nrepl#fireplace_connection#bencode(v:key).nrepl#fireplace_connection#bencode(v:val)')),'').'e'
|
return 'd'.join(map(
|
||||||
|
\ 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
|
||||||
|
@ -34,14 +37,7 @@ 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'
|
||||||
if &shellxquote ==# '"'
|
throw 'Python interface not working. See :help python-dynamic'
|
||||||
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'
|
||||||
|
@ -61,11 +57,11 @@ function! s:id() abort
|
||||||
return 'fireplace-'.hostname().'-'.s:vim_id.'-'.s:id
|
return 'fireplace-'.hostname().'-'.s:vim_id.'-'.s:id
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
function! nrepl#fireplace_connection#prompt() abort
|
function! fireplace#nrepl_connection#prompt() abort
|
||||||
return fireplace#input_host_port()
|
return fireplace#input_host_port()
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
function! nrepl#fireplace_connection#open(arg) abort
|
function! fireplace#nrepl_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
|
||||||
|
@ -95,7 +91,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(nrepl#fireplace_connection#bencode(v:val))'), ' ')
|
\ . ' ' . join(map(copy(a:args), 's:shellesc(fireplace#nrepl_connection#bencode(v:val))'), ' ')
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
function! s:nrepl_transport_dispatch(cmd, ...) dict abort
|
function! s:nrepl_transport_dispatch(cmd, ...) dict abort
|
||||||
|
@ -108,12 +104,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 = nrepl#fireplace_connection#bencode(a:msg)
|
let payload = fireplace#nrepl_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:1)')
|
return map(response, 'fireplace#nrepl#callback(v:val, "synchronous", a:000)')
|
||||||
endif
|
endif
|
||||||
endfunction
|
endfunction
|
||||||
|
|
|
@ -1,9 +0,0 @@
|
||||||
" Vim compiler file
|
|
||||||
|
|
||||||
if exists("current_compiler")
|
|
||||||
finish
|
|
||||||
endif
|
|
||||||
let current_compiler = "lein"
|
|
||||||
|
|
||||||
CompilerSet makeprg=lein
|
|
||||||
CompilerSet errorformat=%+G,fireplace
|
|
|
@ -1,4 +1,4 @@
|
||||||
*fireplace.txt* Clojure REPL tease
|
*fireplace.txt* Clojure REPL support
|
||||||
|
|
||||||
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,7 +6,8 @@ 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*
|
||||||
You need Clojure runtime files to use this plugin. Try vim-clojure-static.
|
While not strictly necessary, this plugin works best with the middleware
|
||||||
|
provided by <https://github.com/clojure-emacs/cider-nrepl>.
|
||||||
|
|
||||||
CONNECTING TO A REPL *fireplace-connect*
|
CONNECTING TO A REPL *fireplace-connect*
|
||||||
|
|
||||||
|
@ -22,35 +23,31 @@ 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 classpath.vim is installed, java (or $JAVA_CMD) is invoked
|
buffer and 'path' contains at least one jar file, java (or $JAVA_CMD) is
|
||||||
directly, which can be quite slow depending on your setup.
|
invoked 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 is can be evaled with Piggieback if the appropriate nREPL
|
ClojureScript 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.
|
properly, and that not all operations are supported.
|
||||||
|
|
||||||
*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 not invoked explicitly. If {env} is a number, the
|
||||||
|
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*
|
||||||
|
@ -60,19 +57,16 @@ 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 keyword under cursor.
|
K Look up docs for symbol 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 keyword under cursor.
|
[d Show source for symbol under cursor.
|
||||||
]d
|
]d
|
||||||
|
|
||||||
NAVIGATING *fireplace-navigating*
|
NAVIGATING *fireplace-navigating*
|
||||||
|
@ -81,11 +75,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 keyword under the cursor.
|
[<C-D> Jump to the source of the symbol 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 keyword under the cursor in
|
<C-W><C-D> Jump to the source of the symbol under the cursor in
|
||||||
<C-W>d a split.
|
<C-W>d a split.
|
||||||
|
|
||||||
*fireplace-gf*
|
*fireplace-gf*
|
||||||
|
@ -98,21 +92,6 @@ 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
|
||||||
|
@ -127,8 +106,7 @@ 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 expression for the current
|
:Eval Eval/print the outermost form for the current line.
|
||||||
line.
|
|
||||||
|
|
||||||
:{range}Eval Eval/print the given range.
|
:{range}Eval Eval/print the given range.
|
||||||
|
|
||||||
|
@ -141,13 +119,25 @@ 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 outermost form at the cursor.
|
cpp Eval/print the innermost form at the cursor.
|
||||||
|
|
||||||
*fireplace-cpr*
|
*fireplace-cpr*
|
||||||
cpr Eval a require :reload form.
|
cpr :Require|RunTests
|
||||||
|
|
||||||
*fireplace-c!*
|
*fireplace-c!*
|
||||||
c!{motion} Eval/replace the code indicated by {motion}.
|
c!{motion} Eval/replace the code indicated by {motion}.
|
||||||
|
@ -169,6 +159,10 @@ 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.
|
||||||
|
|
1131
plugin/fireplace.vim
1131
plugin/fireplace.vim
File diff suppressed because it is too large
Load Diff
|
@ -1,13 +1,13 @@
|
||||||
" fireplace/zip.vim: zip.vim monkey patch to allow access from quickfix
|
" Location: plugin/fireplace/zip.vim
|
||||||
" Maintainer: Tim Pope <http://tpo.pe>
|
|
||||||
|
|
||||||
if exists("g:loaded_zip") || &cp
|
if exists("g:loaded_zip") || &cp || v:version >= 704
|
||||||
finish
|
finish
|
||||||
endif
|
endif
|
||||||
|
|
||||||
runtime! autoload/zip.vim
|
runtime! autoload/zip.vim
|
||||||
|
|
||||||
" Copied and pasted verbatim from autoload/zip.vim.
|
" Patched to allow loading from the quickfix list. The version that ships
|
||||||
|
" 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.")")
|
||||||
|
|
|
@ -4,7 +4,10 @@ import select
|
||||||
import socket
|
import socket
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
from StringIO import StringIO
|
try:
|
||||||
|
from StringIO import StringIO
|
||||||
|
except ImportError:
|
||||||
|
from io import StringIO
|
||||||
|
|
||||||
def noop():
|
def noop():
|
||||||
pass
|
pass
|
||||||
|
@ -46,12 +49,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 = 0
|
i = ''
|
||||||
while True:
|
while True:
|
||||||
char = f.read(1)
|
char = f.read(1)
|
||||||
if char == 'e':
|
if char == 'e':
|
||||||
return i
|
return int(i)
|
||||||
i = 10 * i + int(char)
|
i += char
|
||||||
elif char.isdigit():
|
elif char.isdigit():
|
||||||
i = int(char)
|
i = int(char)
|
||||||
while True:
|
while True:
|
||||||
|
@ -84,13 +87,16 @@ class Connection:
|
||||||
return self.socket.close()
|
return self.socket.close()
|
||||||
|
|
||||||
def send(self, payload):
|
def send(self, payload):
|
||||||
self.socket.sendall(payload)
|
if sys.version_info[0] >= 3:
|
||||||
|
self.socket.sendall(bytes(payload, 'UTF-8'))
|
||||||
|
else:
|
||||||
|
self.socket.sendall(payload)
|
||||||
return ''
|
return ''
|
||||||
|
|
||||||
def receive(self, char=None):
|
def receive(self, char=None):
|
||||||
while len(select.select([self.socket], [], [], 0.1)[0]) == 0:
|
|
||||||
self.poll()
|
|
||||||
f = self.socket.makefile()
|
f = self.socket.makefile()
|
||||||
|
while len(select.select([f], [], [], 0.1)[0]) == 0:
|
||||||
|
self.poll()
|
||||||
try:
|
try:
|
||||||
return bdecode(f)
|
return bdecode(f)
|
||||||
finally:
|
finally:
|
||||||
|
@ -118,8 +124,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, e:
|
except Exception:
|
||||||
print(e)
|
print((sys.exc_info()[1]))
|
||||||
exit(1)
|
exit(1)
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
|
|
Loading…
Reference in New Issue