Compare commits

...

84 Commits

Author SHA1 Message Date
Tim Pope 2bab337396 Merge pull request #259 from rm-hull/bugfix/handle-nREPL-stacktrace
Handle new/old nREPL stacktraces - fixes #258
2016-01-29 16:03:38 -05:00
Richard Hull 0814dd0d2d Handle new/old nREPL stacktraces - fixes #258
At some point there was an upstream change to the message format that
cider-nrepl returned. This resulted in in a crash when trying to eval
an expression that threw an exception, resulting in the exception
being obscured by a Vim error, and no stacktrace being produced.
This patch inspects the returned payload and optionally extracts
any embedded stacktrace before processing.
2016-01-29 20:45:57 +00:00
Tim Pope b550ac6680 Merge pull request #254 from smy20011/master
Use CRLF on windows when parsing test result
2015-12-29 00:46:03 -05:00
Siyuan Ma fd18e8481d Use "\r\\=\n" indicate line break. 2015-12-28 22:17:03 -06:00
Tim Pope fd94f70fff Merge pull request #251 from SevereOverfl0w/patch-1
Replace leiningen.vim with salve.vim
2015-12-07 21:03:48 -05:00
Dominic Monroe 2d5177abef Replace leiningen.vim with salve.vim 2015-12-07 20:52:52 +00:00
Tim Pope 1c75b56ceb Sort bencode keys
Closes https://github.com/tpope/vim-fireplace/issues/248
2015-11-30 19:31:27 -05:00
Daniel Silva f57537135a Add FireplaceEvalPost autocommand
Closes #232.
2015-11-13 18:29:41 -05:00
Tim Pope 8579a41a18 Merge pull request #239 from siphiuel/master
Change :Piggieback behavior for empty/port parameters
2015-10-02 12:12:42 -04:00
Vitaliy Vlasov 3474bd5d72 Change :Piggieback behavior for empty/port parameters
- Explicitly specify Rhino REPL when :Piggieback has no parameters

- Use Weasel REPL when port parameter is provided to :Piggieback

- Improve leading space handling for :Piggieback params

- Fall back to cljs.repl.browser if Weasel in not in classpath

- Use has_key() when checking for Weasel repl availability
2015-10-02 11:07:28 +03:00
Tim Pope 3ffdb062c6 Allow for empty lists in ns declaration 2015-09-30 12:52:10 -04:00
Tim Pope b1725f68a1 Determine aliases by statically parsing ns declaration 2015-09-30 12:22:01 -04:00
Tim Pope 7d500028e6 Rearrange 2015-09-28 18:02:10 -04:00
Juho Teperi df563ed15f Fix alias edge case detection in cfile 2015-09-28 15:00:06 -04:00
Tim Pope 04a7f542f5 Improve error on piggieback failure
References #167.
2015-09-22 14:29:07 -04:00
Tim Pope 3d9b9a59cd Merge pull request #236 from janko-m/runtests-error
Fix a runtime error in :RunTests
2015-08-24 14:23:19 -04:00
Janko Marohnić 9a770d3716 Fix a runtime error in :RunTests 2015-08-24 11:54:05 +02:00
Tim Pope b3b54b8715 Merge pull request #231 from nberger/use-test-vars-on-single-var
Run (single) test under cursor with fixtures applied
2015-07-31 14:39:19 -04:00
Nicolas Berger b50e74f342 Run test under cursor with fixtures applied
Use `test-vars` instead of `test-var` so the test runs with the fixtures
applied. That's the expected behavior when running a test. It's also
what's being done when multiple tests are matched.
2015-07-31 14:53:12 -03:00
Tim Pope 9f7b1844cf Merge pull request #229 from kul/master
Remove superfluous padding from expression
2015-07-18 12:51:18 -04:00
kul 74d392339c Remove superfluous padding from expression 2015-07-18 12:23:31 +05:30
Tim Pope a1571cd258 fireplace.vim 1.1
* Support cider completion, including context aware completion.
* Updates for latest cider-nrepl and piggieback.
* Use :.RunTests or 1cpr to run test under cursor.
* Add CTRL-R CTRL-F and CTRL-R CTRL-P command line maps.
* Add support for boot's fake class path.
* Fix handling of CTRL-C interrupt while evaling.
* Numerous minor bug fixes.
2015-06-30 18:34:36 -04:00
Tim Pope f456f04b65 Work around bug on ancient Vim
Closes #226.
2015-06-29 17:46:45 -04:00
Tim Pope 09c80c6794 Allow 1cpr to run test under cursor 2015-06-26 09:36:14 -04:00
Tim Pope 459904381b Use :.RunTests to run test under cursor
Closes #223.
2015-06-25 15:34:45 -04:00
Tim Pope 69bf9ef519 Make :0RunTests equivalent to RunAllTests 2015-06-25 15:04:12 -04:00
Tim Pope 1f478e401a Tweak <cfile> 2015-06-25 10:17:58 -04:00
Tim Pope cb3c270c99 Add cljc extension support to connection process 2015-06-23 15:56:50 -04:00
Tim Pope 7b2ae78bd7 Add <C-R> command line maps 2015-06-21 15:12:39 -04:00
Tim Pope b0a540c68d Add .cljc extension 2015-06-21 15:08:30 -04:00
Tim Pope 09eedd05af Use jar command if available to query zip files 2015-06-21 15:08:29 -04:00
Tim Pope 89aee9c00c Merge pull request #214 from Deraen/completion-context
Completion context
2015-05-17 11:01:43 -04:00
Juho Teperi c22e61c69b Add support for context aware completion
If complete operation is given context property containing the
current toplevel form Compliment library can give better completion
results in some contexts:

- Local vars for let and defn
- Resources in classpath for io/resource calls
- Vars in specific ns for :require :refer
- Better Java class name completion for :import

The context string should contain symbol __prefix__ in place of the word
being completed. To achieve this location of cursor inside the toplevel
form is calculated so that the placeholder symbol can be placed in the
proper place.
2015-05-17 17:54:06 +03:00
Roger Gilliar 13a21bff0f Fix count of test errors and failures
Closes #208.
2015-05-17 10:06:21 -04:00
Tim Pope 1646a01b0b Merge pull request #211 from Deraen/all-candidate-types
Add all candidate types to short_types map
2015-05-16 16:17:59 -04:00
Juho Teperi aede23c46a Add all candidate types to short_types map 2015-05-16 23:01:23 +03:00
Tim Pope 819438bdf4 Merge pull request #210 from Deraen/cider-nrepl-0.9.0
Cider nrepl 0.9.0 completion support
2015-05-15 16:19:55 -04:00
Juho Teperi 9ccaea1f2b Request extra-metadata for completion candidates
In cider-nrepl 0.9.0 there is new extra-metadata option for complete op
[1]. It can be used to enrich the candiate results with additional
properties like arglists and docstring.

This commit adds extra-metadata option to complete call and changes the
candidate function to set fields in omnicomplete result so that arglists
are shown on omnicomplete menu and docstring is shown in preview window.

[1]: https://github.com/clojure-emacs/cider-nrepl/pull/195/files
2015-05-15 22:54:08 +03:00
Juho Teperi 44e766d5a5 Add support for Cider-nrepl 0.9.0 complete op
Response from complete operation now returns list of maps containing
e.g. namespace and type of the completion candidate.
This change adds a new type check to check if complete returned list of
maps and converts those maps to format required by omnicomplete.
In addition to candidate name its type is now shown. The type is
shortned to one character.
2015-05-15 22:31:54 +03:00
Tim Pope 49153a39fc Merge pull request #201 from kul/master
Remove `:repl-env` for latest piggieback compatibility.
2015-04-13 16:27:49 -04:00
kul 0aabcdd798 Remove `:repl-env` for latest piggieback compatibility. 2015-03-31 20:52:10 +05:30
Joshua Davey 5866d0017a Add support for boot 2.0 and up
Boot's built-in repl task adds a fake.class.path System property which
refers back to the original user files (as opposed to the temporary
files it uses to actually do builds). We should prefer that to anything
else when the property is set.

Fixes #194.
2015-02-15 13:45:21 -05:00
Robert Pitts 7cebf6847e Document `cqq` 2015-02-10 15:27:43 -05:00
Tim Pope 71e44af208 Fix c1mm 2015-02-10 11:11:53 -05:00
Tim Pope b999b09cd9 Fix project directory path for autoconnection
Closes #189.
2014-12-20 01:27:23 -05:00
Tim Pope 506cf288bd Skip regexp when selecting form for cpp
Closes #188.
2014-12-11 11:31:23 -05:00
Tim Pope 0ecd9ec587 Fix duplicate namespaces in completion 2014-11-30 00:53:32 -05:00
Tim Pope 874505e9f2 Support new return value of completions operator 2014-11-30 00:46:33 -05:00
Tim Pope 04ce1b64af Support new return value of classpath operator 2014-11-30 00:36:33 -05:00
Tim Pope db2e70ee3f Cider info op no longer embeds in value attribute
Closes #186.
2014-11-19 00:49:58 -05:00
Tim Pope 8f7a07cffd Allow forcing default ns 2014-10-23 15:52:50 -04:00
Tim Pope 97758acc16 Fix sending interrupt commands after SIGINT
Via @benmoss.  Closes #182.
2014-10-21 15:29:31 -04:00
Tim Pope eeccb69a2f Fix typo 2014-10-21 15:14:38 -04:00
Tim Pope c0e574387d Fix completion in aliased namespaces 2014-10-10 02:40:10 -04:00
Tim Pope fccb149148 Recognize nested classes in K
Closes #176.
2014-09-05 13:10:21 -04:00
Tim Pope c1416c89ba Don't choke on missing API version
Closes #175.
2014-09-02 12:26:13 -04:00
Tim Pope b256399f3f Merge pull request #169 from oahner/fix-portfile-issue
Register port file after connecting to port
2014-07-31 10:34:32 -04:00
Jonathan Henry 142fab4e0f Register port file after connecting to port 2014-07-31 00:57:15 -04:00
Tim Pope 06f6bc5de6 Evaluate single expression when running tests
This eliminates an extra "nil" value in the response.
2014-07-12 23:17:30 -04:00
Tim Pope d6b3e1c67c Silence all callback errors
If this is to be made asynchronous, there's not really a good way to
display the exception.
2014-07-10 22:58:35 -04:00
Tim Pope ebb2933f4c Pass additional .message arguments to callback 2014-07-10 22:43:03 -04:00
Tim Pope 3e978e4cd4 Add better name for fireplace#evalparse() 2014-07-04 17:14:10 -04:00
Tim Pope a39092ebe3 Add script id 2014-07-04 17:00:21 -04:00
Tim Pope 835fdedf5f fireplace.vim 1.0 2014-07-04 16:50:18 -04:00
Tim Pope e107b2ae17 Drop reference to old name 2014-07-04 16:32:52 -04:00
Tim Pope 1dc5129c0e Tweak description 2014-07-04 16:24:46 -04:00
Tim Pope 712205e66a Normalize headers 2014-07-04 16:06:43 -04:00
Tim Pope ffc41e86f3 Remove obsolete Maven reference 2014-07-04 15:38:00 -04:00
Tim Pope 37e3a474c5 Clarify plugin/fireplace/zip.vim 2014-07-04 15:04:44 -04:00
Tim Pope 1f36136346 Zip hack unnecessary on Vim 7.4 2014-07-03 14:49:18 -04:00
Tim Pope ea15c81773 Remove extracted compiler plugin 2014-07-03 14:45:11 -04:00
Tim Pope 25e18b5f82 Support gf on relative (load) paths
This doesn't do a file existence check because that's tricky with jar
files in the mix.  Instead, it's limited to strings, so a gf on a random
symbol doesn't send us flying.
2014-07-03 12:30:32 -04:00
Tim Pope a14328c1dc Allow disabling all maps 2014-07-03 12:28:23 -04:00
Tim Pope eae17cfb42 Drop 'includeexpr' entirely 2014-07-03 10:22:55 -04:00
Tim Pope 845b362a17 Find absolute path in 'includeexpr'
The gf map is still necessary because Vim doesn't accept zipfile paths
as valid.
2014-07-03 10:02:34 -04:00
Tim Pope a1eef3dda1 Rearrange 2014-07-03 09:52:28 -04:00
Tim Pope 0e42998a27 Provide :RunAllTests
Don't waste :RunTests! on this cleverness.
2014-07-02 19:20:11 -04:00
Tim Pope 9c78e32f4b Add plugin maps for go to file 2014-07-02 18:44:20 -04:00
Tim Pope fb6975bfdf Extract autocmd repetition to functions 2014-07-02 18:38:49 -04:00
Tim Pope 8defd6b17e Fix grammar: setup -> set_up 2014-07-02 18:33:23 -04:00
Tim Pope 26e467c2e7 Fix list of available protocols
Closes #165.
2014-07-01 09:19:32 -04:00
Tim Pope 6dbf627022 Make connect commands buffer local 2014-06-29 19:03:49 -04:00
Tim Pope 5ff2eeae1c Default to nrepl protocol 2014-06-29 18:54:07 -04:00
Tim Pope 94ff1464a4 Fix manual connection 2014-06-29 18:53:41 -04:00
7 changed files with 497 additions and 197 deletions

View File

@ -4,16 +4,13 @@ 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
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
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
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 [leiningen.vim][] for assorted
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
@ -41,16 +38,16 @@ one automatically. ClojureScript support is just as seamless with
The only external dependency is that you have either a Vim with Python support
compiled in, or `python` in your path.
Oh, and if you don't have an nREPL connection, installing [leiningen.vim][]
Oh, and if you don't have an nREPL connection, installing [salve.vim][]
lets it fall back to using `java clojure.main` for some of the basics, using a
class path based on your Leiningen or Maven config. It's a bit slow, but a
two-second delay is vastly preferable to being forced out of my flow for a
single command, in my book.
class path based on your Leiningen config. It's a bit slow, but a two-second
delay is vastly preferable to being forced out of my flow for a single
command, in my book.
[cider-nrepl]: https://github.com/clojure-emacs/cider-nrepl
[Piggieback]: https://github.com/cemerick/piggieback
[classpath.vim]: https://github.com/tpope/vim-classpath
[leiningen.vim]: https://github.com/tpope/vim-leiningen
[salve.vim]: https://github.com/tpope/vim-salve
### Not quite a REPL
@ -111,12 +108,13 @@ Because why not? It works in the quasi-REPL too.
> Why does it take so long for Vim to startup?
That's either [classpath.vim][] or [leiningen.vim][].
That's either [classpath.vim][] or [salve.vim][].
## Self-Promotion
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
[Twitter](http://twitter.com/tpope) and
[GitHub](https://github.com/tpope).

View File

@ -1,4 +1,4 @@
" Fireplace nREPL session
" Location: autoload/nrepl/fireplace.vim
if exists("g:autoloaded_fireplace_nrepl")
finish
@ -34,14 +34,24 @@ function! fireplace#nrepl#for(transport) abort
let client.transport = a:transport
let client.session = client.process({'op': 'clone', 'session': 0})['new-session']
let client.describe = client.process({'op': 'describe', 'verbose?': 1})
if client.describe.versions.nrepl.major == 0 &&
if get(client.describe.versions.nrepl, 'major', -1) == 0 &&
\ client.describe.versions.nrepl.minor < 2
throw 'nREPL: 0.2.0 or higher required'
endif
if client.has_op('classpath')
" 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, 'value')) == type([])
let client._path = response.value
if type(get(response, 'classpath')) == type([])
let client._path = response.classpath
endif
endif
if !has_key(client, '_path')
@ -147,13 +157,16 @@ function! s:nrepl_eval(expr, ...) dict abort
endif
try
let response = self.process(msg)
catch /^Vim:Interrupt$/
if has_key(msg, 'session')
call self.message({'op': 'interrupt', 'session': msg.session, 'interrupt-id': msg.id}, 'ignore')
finally
if !exists('response')
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
throw 'Clojure: Interrupt'
endtry
if has_key(response, 'ns') && !has_key(options, 'ns')
if has_key(response, 'ns') && empty(get(options, 'ns'))
let self.ns = response.ns
endif
@ -169,13 +182,23 @@ endfunction
function! s:extract_last_stacktrace(nrepl, session) abort
if a:nrepl.has_op('stacktrace')
let stacktrace = filter(a:nrepl.message({'op': 'stacktrace', 'session': a:session}), 'has_key(v:val, "file")')
let stacktrace = a:nrepl.message({'op': 'stacktrace', 'session': a:session})
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)
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 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")
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})
@ -190,6 +213,9 @@ function! s:nrepl_prepare(msg) dict abort
if !has_key(msg, 'id')
let msg.id = fireplace#nrepl#next_id()
endif
if empty(get(msg, 'ns', 1))
unlet msg.ns
endif
if empty(get(msg, 'session', 1))
unlet msg.session
elseif !has_key(msg, 'session')
@ -198,12 +224,15 @@ function! s:nrepl_prepare(msg) dict abort
return msg
endfunction
function! fireplace#nrepl#callback(body, type, fn)
let response = {'body': a:body, 'type': a:type}
if has_key(g:fireplace_nrepl_sessions, get(a:body, 'session'))
let response.session = g:fireplace_nrepl_sessions[a:body.session]
endif
call call(a:fn, [response])
function! fireplace#nrepl#callback(body, type, callback) abort
try
let response = {'body': a:body, 'type': a:type}
if has_key(g:fireplace_nrepl_sessions, get(a:body, 'session'))
let response.session = g:fireplace_nrepl_sessions[a:body.session]
endif
call call(a:callback[0], [response] + a:callback[1:-1])
catch
endtry
endfunction
function! s:nrepl_call(msg, ...) dict abort

View File

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

View File

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

View File

@ -1,5 +1,7 @@
" fireplace.vim - Clojure REPL tease
" fireplace.vim - Clojure REPL support
" Maintainer: Tim Pope <http://tpo.pe/>
" Version: 1.1
" GetLatestVimScripts: 4978 1 :AutoInstall: fireplace.vim
if exists("g:loaded_fireplace") || v:version < 700 || &cp
finish
@ -39,6 +41,8 @@ function! fireplace#jar_contents(path) abort
if !exists('s:zipinfo')
if executable('zipinfo')
let s:zipinfo = 'zipinfo -1 '
elseif executable('jar')
let s:zipinfo = 'jar tf '
elseif executable('python')
let s:zipinfo = 'python -c '.shellescape('import zipfile, sys; print chr(10).join(zipfile.ZipFile(sys.argv[1]).namelist())').' '
else
@ -79,6 +83,64 @@ 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]')
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
if a:findstart
let line = getline('.')[0 : col('.')-2]
@ -87,12 +149,21 @@ function! fireplace#omnicomplete(findstart, base) abort
try
if fireplace#op_available('complete')
let response = fireplace#message({'op': 'complete', 'symbol': a:base})
if type(get(response[0], 'value')) == type([])
if type(get(response[0].value, 0)) == type([])
return map(response[0].value[0], '{"word": v:val}')
elseif type(get(response[0].value, 0)) == type('')
return map(response[0].value, '{"word": v:val}')
let response = fireplace#message({
\ 'op': 'complete',
\ 'symbol': a:base,
\ 'extra-metadata': ['arglists', 'doc'],
\ 'context': s:get_complete_context()
\ })
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
return []
endif
@ -148,10 +219,6 @@ if !exists('s:repls')
let s:repl_portfiles = {}
endif
function! s:repl.user_ns() abort
return 'user'
endfunction
function! s:repl.path() dict abort
return self.connection.path()
endfunction
@ -165,16 +232,6 @@ function! s:conn_try(connection, function, ...) abort
endtry
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
if has_key(a:payload, 'ns') && a:payload.ns !=# self.user_ns()
let ignored_error = self.preload(a:payload.ns)
@ -220,15 +277,19 @@ function! s:repl.piggieback(arg, ...) abort
let connection = s:conn_try(self.connection, 'clone')
if empty(a:arg)
let arg = ''
let arg = '(cljs.repl.rhino/repl-env)'
elseif a:arg =~# '^\d\{1,5}$'
call connection.eval("(require 'cljs.repl.browser)")
let replns = 'weasel.repl.websocket'
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 arg = ' :repl-env (cljs.repl.browser/repl-env :port '.port.')'
let arg = '('.replns.'/repl-env :port '.port.')'
else
let arg = ' :repl-env ' . a:arg
let arg = a:arg
endif
let response = connection.eval('(cemerick.piggieback/cljs-repl'.arg.')')
let response = connection.eval('(cemerick.piggieback/cljs-repl'.' '.arg.')')
if empty(get(response, 'ex'))
call insert(self.piggiebacks, extend({'connection': connection}, deepcopy(s:piggieback)))
@ -250,6 +311,20 @@ function! s:piggieback.eval(expr, options) abort
return call(s:repl.eval, [a:expr, options], self)
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
call insert(s:repls, extend({'connection': a:conn, 'piggiebacks': []}, deepcopy(s:repl)))
if a:0 && a:1 !=# ''
@ -272,10 +347,11 @@ function! fireplace#register_port_file(portfile, ...) abort
endif
if empty(old) && getfsize(a:portfile) > 0
let port = matchstr(readfile(a:portfile, 'b', 1)[0], '\d\+')
let s:repl_portfiles[a:portfile] = {'time': getftime(a:portfile)}
try
let conn = fireplace#nrepl_connection#open(port)
let s:repl_portfiles[a:portfile].connection = conn
let s:repl_portfiles[a:portfile] = {
\ 'time': getftime(a:portfile),
\ 'connection': conn}
call s:register_connection(conn, a:0 ? a:1 : '')
return conn
catch /^nREPL Connection Error:/
@ -310,7 +386,7 @@ function! fireplace#input_host_port() abort
endfunction
function! s:protos() abort
return map(split(globpath(&runtimepath, 'autoload/*/fireplace_connection.vim'), "\n"), 'fnamemodify(v:val, ":h:t")')
return map(split(globpath(&runtimepath, 'autoload/fireplace/*_connection.vim'), "\n"), 'fnamemodify(v:val, ":t")[0:-16]')
endfunction
function! s:connect_complete(A, L, P) abort
@ -335,6 +411,8 @@ endfunction
function! s:Connect(...) abort
if (a:0 ? a:1 : '') =~# '^\w\+://'
let [proto, arg] = split(a:1, '://')
elseif (a:0 ? a:1 : '') =~# '^\%([[:alnum:].-]\+:\)\=\d\+$'
let [proto, arg] = ['nrepl', a:1]
elseif a:0
return 'echoerr '.string('Usage: :Connect proto://...')
else
@ -349,10 +427,10 @@ function! s:Connect(...) abort
redraw!
echo ':Connect'
echo 'Protocol> '.proto
let arg = {proto}#fireplace_connection#prompt()
let arg = fireplace#{proto}_connection#prompt()
endif
try
let connection = {proto}#fireplace_connection#open(arg)
let connection = fireplace#{proto}_connection#open(arg)
catch /.*/
return 'echoerr '.string(v:exception)
endtry
@ -376,8 +454,10 @@ endfunction
augroup fireplace_connect
autocmd!
autocmd FileType clojure command! -bar -complete=customlist,s:connect_complete -nargs=* 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 -bar -complete=customlist,s:connect_complete -nargs=*
\ Connect FireplaceConnect <args>
autocmd FileType clojure command! -buffer -bang -complete=customlist,fireplace#eval_complete -nargs=*
\ Piggieback call s:piggieback(<q-args>, <bang>0)
augroup END
" Section: Java runner
@ -463,6 +543,41 @@ let s:oneoff.piggieback = s:oneoff.message
" 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
if exists('s:input')
return s:input
@ -516,7 +631,7 @@ function! fireplace#platform(...) abort
let portfile = findfile('.nrepl-port', '.;')
if !empty(portfile)
call fireplace#register_port_file(portfile, fnamemodify(portfile, ':h'))
call fireplace#register_port_file(portfile, fnamemodify(portfile, ':p:h'))
endif
silent doautocmd User FireplacePreConnect
@ -536,7 +651,7 @@ function! fireplace#platform(...) abort
endif
endfor
let path = s:path_extract(getbufvar(buf, '&path'))
if !empty(path) && fnamemodify(bufname(buf), ':e') =~# '^cljx\=$'
if !empty(path) && fnamemodify(bufname(buf), ':e') =~# '^clj[cx]\=$'
return extend({'_path': path, 'nr': bufnr(buf)}, s:oneoff)
endif
throw 'Fireplace: :Connect to a REPL or install classpath.vim'
@ -552,7 +667,7 @@ function! fireplace#client(...) abort
if empty(client.piggiebacks)
let result = client.piggieback('')
if has_key(result, 'ex')
return result
throw 'Fireplace: '.result.ex
endif
endif
return client.piggiebacks[0]
@ -687,6 +802,14 @@ function! fireplace#session_eval(expr, ...) abort
endif
endif
try
silent doautocmd User FireplaceEvalPost
catch
echohl ErrorMSG
echomsg v:exception
echohl NONE
endtry
call s:output_response(response)
if get(response, 'ex', '') !=# ''
@ -749,6 +872,10 @@ function! fireplace#evalparse(expr, ...) abort
throw err
endfunction
function! fireplace#query(expr, ...) abort
return fireplace#evalparse(a:expr, a:0 ? a:1 : {})
endfunction
" Section: Quickfix
function! s:qfmassage(line, path) abort
@ -799,7 +926,7 @@ augroup END
" Section: Eval
let fireplace#skip = 'synIDattr(synID(line("."),col("."),1),"name") =~? "comment\\|string\\|char"'
let fireplace#skip = 'synIDattr(synID(line("."),col("."),1),"name") =~? "comment\\|string\\|char\\|regexp"'
function! s:opfunc(type) abort
let sel_save = &selection
@ -836,7 +963,11 @@ function! s:opfunc(type) abort
silent exe "normal! `[v`]y"
endif
redraw
return repeat("\n", line("'<")-1) . repeat(" ", col("'<")-1) . @@
if fireplace#client().user_ns() ==# 'user'
return repeat("\n", line("'<")-1) . repeat(" ", col("'<")-1) . @@
else
return @@
endif
finally
let @@ = reg_save
let &selection = sel_save
@ -1037,7 +1168,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>Fireplace1MacroExpand :<C-U>set opfunc=<SID>macroexpand1op<CR>g@
xnoremap <silent> <Plug>Fireplace1MacroExpand :<C-U>call <SID>macroexpand1op(visualmode())<CR>
nnoremap <silent> <Plug>Fireplace1MacroExpand :<C-U>call <SID>macroexpand1op(v:count)<CR>
nnoremap <silent> <Plug>FireplaceCount1MacroExpand :<C-U>call <SID>macroexpand1op(v:count)<CR>
nnoremap <silent> <Plug>FireplaceEdit :<C-U>set opfunc=<SID>editop<CR>g@
xnoremap <silent> <Plug>FireplaceEdit :<C-U>call <SID>editop(visualmode())<CR>
@ -1068,10 +1199,12 @@ function! s:Last(bang, count) abort
return ''
endfunction
function! s:setup_eval() abort
function! s:set_up_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 -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> cpp <Plug>FireplaceCountPrint
@ -1092,7 +1225,7 @@ function! s:setup_eval() abort
map! <buffer> <C-R>( <Plug>FireplaceRecall
endfunction
function! s:setup_historical() abort
function! s:set_up_historical() abort
setlocal readonly nomodifiable
nnoremap <buffer><silent>q :bdelete<CR>
endfunction
@ -1107,9 +1240,9 @@ endfunction
augroup fireplace_eval
autocmd!
autocmd FileType clojure call s:setup_eval()
autocmd FileType clojure call s:set_up_eval()
autocmd BufReadPost * if has_key(s:qffiles, expand('<amatch>:p')) |
\ call s:setup_historical() |
\ call s:set_up_historical() |
\ endif
autocmd CmdWinEnter @ if exists('s:input') | call s:cmdwinenter() | endif
autocmd CmdWinLeave @ if exists('s:input') | call s:cmdwinleave() | endif
@ -1137,14 +1270,16 @@ function! s:Require(bang, echo, ns) abort
endtry
endfunction
function! s:setup_require() abort
function! s:set_up_require() abort
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
augroup fireplace_require
autocmd!
autocmd FileType clojure call s:setup_require()
autocmd FileType clojure call s:set_up_require()
augroup END
" Section: Go to source
@ -1154,6 +1289,8 @@ function! fireplace#info(symbol) abort
let response = fireplace#message({'op': 'info', 'symbol': a:symbol})[0]
if type(get(response, 'value')) == type({})
return response.value
elseif has_key(response, 'file')
return response
endif
endif
let cmd =
@ -1212,23 +1349,22 @@ 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>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
autocmd!
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
autocmd FileType clojure call s:set_up_source()
augroup END
" Section: Go to file
@ -1238,7 +1374,7 @@ function! fireplace#findfile(path) abort
if a:path !~# '/'
let path = tr(a:path, '.-', '/_')
else
let path = substitute(a:path, '^/', '')
let path = substitute(a:path, '^/', '', '')
endif
let resource = fireplace#findresource(path, fireplace#path(), 0, &suffixesadd)
if !empty(resource)
@ -1251,74 +1387,171 @@ function! fireplace#findfile(path) abort
return ''
endfunction
function! s:GF(cmd, file) abort
if a:file =~# '^[^/]*/[^/.]*$' && a:file =~# '^\k\+$'
let [file, jump] = split(a:file, "/")
if file !~# '\.'
try
let file = fireplace#evalparse('((ns-aliases *ns*) '.s:qsym(file).' '.s:qsym(file).')')
catch /^Clojure:/
endtry
endif
let s:iskeyword = '[[:alnum:]_=?!#$%&*+|./<>:-]'
let s:token = '^\%(#"\%(\\\@<!\%(\\\\\)*\\"\|[^"]\)*"\|"\%(\\.\|[^"]\)*"\|[[:space:],]\+\|\%(;\|#!\)[^'."\n".']*\|\~@\|#[[:punct:]]\|'.s:iskeyword.'\+\|\\\%(space\|tab\|newline\|return\|.\)\|.\)'
function! s:read_token(str, pos) abort
let pos = a:pos
let match = ' '
while match =~# '^[[:space:],;]'
let match = matchstr(a:str, s:token, pos)
let pos += len(match)
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
let file = a:file
return [token, pos]
endif
let file = fireplace#findfile(file)
if file ==# ''
let v:errmsg = "Couldn't find file for ".a:file
return 'echoerr v:errmsg'
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
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
return fnameescape(file)
endif
endfunction
function! s:Find(find, edit) abort
let cfile = fireplace#cfile()
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
return a:cmd .
\ (exists('jump') ? ' +sil!\ djump\ ' . jump : '') .
\ ' ' . fnameescape(file) .
\ '| let &l:path = ' . string(&l:path)
endfunction
augroup fireplace_go_to_file
autocmd!
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>
autocmd FileType clojure call s:set_up_go_to_file()
augroup END
" 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
try
let response = s:eval('('.a:ns.'/'.a:macro.' '.a:arg.')', {'session': 0})
@ -1361,7 +1594,7 @@ endfunction
function! s:K() abort
let word = expand('<cword>')
let java_candidate = matchstr(word, '^\%(\w\+\.\)*\u\l\w*\ze\%(\.\|\/\w\+\)\=$')
let java_candidate = matchstr(word, '^\%(\w\+\.\)*\u\l[[:alnum:]$]*\ze\%(\.\|\/\w\+\)\=$')
if java_candidate !=# ''
return 'Javadoc '.java_candidate
else
@ -1372,30 +1605,37 @@ endfunction
nnoremap <Plug>FireplaceK :<C-R>=<SID>K()<CR><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
autocmd!
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>)
autocmd FileType clojure call s:set_up_doc()
augroup END
" Section: Tests
function! fireplace#capture_test_run(expr, ...) abort
let expr = '(require ''clojure.test) '
\ . '(try '
\ . '(binding [clojure.test/report (fn [m]'
let expr = '(try'
\ . ' (require ''clojure.test)'
\ . ' (binding [clojure.test/report (fn [m]'
\ . ' (case (:type m)'
\ . ' (:fail :error)'
\ . ' (let [{file :file line :line test :name} (meta (last clojure.test/*testing-vars*))]'
\ . ' (clojure.test/with-test-out'
\ . ' (clojure.test/inc-report-counter (:type m))'
\ . ' (println (clojure.string/join "\t" [file line (name (:type m)) test]))'
\ . ' (when (seq clojure.test/*testing-contexts*) (println (clojure.test/testing-contexts-str)))'
\ . ' (when-let [message (:message m)] (println message))'
@ -1412,7 +1652,7 @@ function! fireplace#capture_test_run(expr, ...) abort
call setqflist(fireplace#quickfix_for(get(response, 'stacktrace', [])))
return s:output_response(response)
endif
for line in split(response.out, "\n")
for line in split(response.out, "\r\\=\n")
if line =~# '\t.*\t.*\t'
let entry = {'text': line}
let [resource, lnum, type, name] = split(line, "\t", 1)
@ -1446,27 +1686,57 @@ function! fireplace#capture_test_run(expr, ...) abort
endfor
endfunction
function! s:RunTests(bang, ...) abort
function! s:RunTests(bang, count, ...) abort
if &autowrite || &autowriteall
silent! wall
endif
let pre = ''
if a:bang && a:0
let expr = '(clojure.test/run-all-tests #"'.join(a:000, '|').'")'
elseif a:bang
let expr = '(clojure.test/run-all-tests)'
if a:count < 0
let pre = ''
if a:0
let expr = ['(clojure.test/run-all-tests #"'.join(a:000, '|').'")']
else
let expr = ['(clojure.test/run-all-tests)']
endif
else
let reqs = map(copy(a:000), '"''".v:val')
let pre = '(clojure.core/require '.join(empty(a:000) ? ["'".fireplace#ns()] : reqs, ' ').' :reload) '
let expr = join(['(clojure.test/run-tests'] + reqs, ' ').')'
if a:0 && a:000 !=# [fireplace#ns()]
let args = a:000
else
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
call fireplace#capture_test_run(expr, pre)
echo expr
call fireplace#capture_test_run(join(expr, ' '), pre)
echo join(expr, ' ')
endfunction
augroup fireplace_command
autocmd!
autocmd FileType clojure command! -buffer -bar -bang -nargs=*
function! s:set_up_tests() abort
command! -buffer -bar -bang -range=0 -nargs=*
\ -complete=customlist,fireplace#ns_complete RunTests
\ call s:RunTests(<bang>0, <f-args>)
\ 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 FileType clojure call s:set_up_tests()
augroup END

View File

@ -1,13 +1,13 @@
" fireplace/zip.vim: zip.vim monkey patch to allow access from quickfix
" Maintainer: Tim Pope <http://tpo.pe>
" Location: plugin/fireplace/zip.vim
if exists("g:loaded_zip") || &cp
if exists("g:loaded_zip") || &cp || v:version >= 704
finish
endif
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)
" call Dfunc("zip#Read(fname<".a:fname.">,mode=".a:mode.")")