Load stack traces into location list.

Closes #20.
This commit is contained in:
Tim Pope 2013-01-07 22:41:04 -05:00
parent 84168b7c5e
commit fbfc6e09b4
3 changed files with 57 additions and 1 deletions

View File

@ -66,6 +66,9 @@ file), `:Require` requires a namespace with `:reload` (`:Require!` does
operator that evaluates a given motion (`cpp` for the expression under the operator that evaluates a given motion (`cpp` for the expression under the
cursor). cursor).
Any failed evaluation loads the stack trace into the location list, which
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'm new to Clojure, so stuff that helps me understand code is a top priority.

View File

@ -97,7 +97,8 @@ EVALUATING CODE *foreplay-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
necessary. If the current file sits outside the class path (project.clj, for necessary. If the current file sits outside the class path (project.clj, for
example), the user namespace is used instead. example), the user namespace is used instead. If an exception occurs, the
stack trace is loaded into the |location-list|. Use |:lopen| to view it.
*foreplay-:Require* *foreplay-:Require*
:Require [ns] Require :reload the given/current namespace. :Require [ns] Require :reload the given/current namespace.

View File

@ -347,6 +347,54 @@ function! foreplay#local_client(...)
throw ':Connect to a REPL or install classpath.vim to evaluate code' throw ':Connect to a REPL or install classpath.vim to evaluate code'
endfunction endfunction
function! foreplay#findresource(resource) abort
if a:resource ==# ''
return ''
endif
try
let path = foreplay#local_client().path()
catch /^:Connect/
return ''
endtry
let file = findfile(a:resource, escape(join(path, ','), ' '))
if !empty(file)
return file
endif
for jar in path
if fnamemodify(jar, ':e') ==# 'jar' && index(foreplay#jar_contents(jar), a:resource) >= 0
return 'zipfile:' . jar . '::' . a:resource
endif
endfor
return ''
endfunction
function! foreplay#quickfix_for(stacktrace) abort
let qflist = []
for line in a:stacktrace
let match = matchlist(line, '\(.*\)(\(.*\):\(\d\+\))')
let entry = {'text': line}
let [_, class, file, lnum; __] = match
let entry.lnum = lnum
let truncated = substitute(class, '\.[A-Za-z0-9_]\+\%($.*\)$', '', '')
if file == 'NO_SOURCE_FILE'
let entry.resource = ''
else
let entry.resource = tr(truncated, '.', '/').'/'.file
endif
let qflist += [entry]
endfor
let paths = map(copy(qflist), 'foreplay#findresource(v:val.resource)')
let i = 0
for i in range(len(qflist))
if !empty(paths[i])
let qflist[i].filename = paths[i]
else
call remove(qflist[i], 'lnum')
endif
endfor
return qflist
endfunction
function! s:output_response(response) abort function! s:output_response(response) abort
if get(a:response, 'err', '') !=# '' if get(a:response, 'err', '') !=# ''
echohl ErrorMSG echohl ErrorMSG
@ -375,6 +423,10 @@ function! foreplay#eval(expr) abort
call s:output_response(response) call s:output_response(response)
if !empty(get(response, 'stacktrace', []))
call setloclist(0, foreplay#quickfix_for(response.stacktrace))
endif
if get(response, 'ex', '') !=# '' if get(response, 'ex', '') !=# ''
let err = 'Clojure: '.response.ex let err = 'Clojure: '.response.ex
elseif has_key(response, 'value') elseif has_key(response, 'value')