Tamas Kovacs avatar Tamas Kovacs committed 4d51a09

Version 0.9.2

Added option g:swank_log to enable swank debug log. Added options g:slimv_repl_name, g:slimv_sldb_name, g:slimv_inspect_name. Added option g:slimv_indent_maxlines. Changed Debug-Thread mapping to <leader>dT (g:slimv_keybindings=2) due to conflict with Generate-Tags. Label thread ID in thread list (by Philipp Marek). Set balloonexpr for all buffers (thanks to Philipp Marek). Connect swank server when needed instead of printing an error message (by Philipp Marek). Set expandtab for lisp and clojure files. Kill-Thread kills all threads in the selected range (by Philipp Marek). Bugfixes: Added missing parts of Set-Breakpoint introduced in 0.9.1. Test source lookup (upon pressing Enter) before testing fold toggle in SLDB (by Philipp Marek). Indentation of flet, labels, macrolet. Kill-Thread now really kills thread (by Philipp Marek). Inspect gensyms in frame (by Philipp Marek).

Comments (0)

Files changed (9)

     *  Toggle Trace
     *  Untrace All
     *  Disassemble
+    *  Set Breakpoint
     *  Inspect
     *  Abort
     *  Quit to Toplevel
-*slimv.txt*                    Slimv                 Last Change: 13 Oct 2011
+*slimv.txt*                    Slimv                 Last Change: 27 Oct 2011
 
 Slimv                                                                  *slimv*
-                               Version 0.9.1
+                               Version 0.9.2
 
 The Superior Lisp Interaction Mode for Vim.
 This plugin is aimed to help Lisp development by interfacing between Vim and
 |slimv-keyboard|             Keyboard mappings
 
 -------------------------------------------------------------------------------
-                                                                *slimv_options*
+                                                                *slimv-options*
 
 The list below contains an alphabetical collection of Slimv options.
 Below that list follows the detailed explanation on each option.
 
 |g:slimv_impl|               The Lisp implementation. Defaults to 'clisp'.
 
+|g:slimv_indent_maxlines|    Maximum number of lines searched backwards for
+                             indenting special forms
+
+|g:slimv_inspect_name|       Name of the Inspect buffer.
+
 |g:slimv_javadoc_root|       Base URL for the JavaDoc.
 
 |g:slimv_keybindings|        Predefined Slimv keybindings. Possible values:
 
 |g:slimv_python|             Path for the Python interpreter.
 
+|g:slimv_repl_name|          Name of the REPL buffer.
+
 |g:slimv_repl_split|         Open the Lisp REPL buffer in a split window
                              or in a separate buffer.
 
 
 |g:slimv_simple_compl|       Use simple completion instead of fuzzy completion.
 
+|g:slimv_sldb_name|          Name of the SLDB buffer.
+
 |g:slimv_sldb_wrap|          Set wrap mode for the SLDB buffer.
 
 |g:slimv_swank_clojure|      Command used to start the Clojure SWANK server.
 the .html extension (on Windows) or returned by the Python webbrowser package
 (on Linux) is used to start the browser.
 
+                                                            *g:slimv_repl_name*
+Name of the REPL buffer. Default is 'REPL'. Space and some other special
+characters need to be escaped (e.g. 'Slimv\ REPL', '\#REPL\#').
+Not all special characters are allowed, e.g. '*' does not work in Windows.
+
+                                                            *g:slimv_sldb_name*
+Name of the SLDB buffer. Default is 'SLDB'. Space and some other special
+characters need to be escaped (e.g. 'Slimv\ Debugger', '\#SLDB\#').
+Not all special characters are allowed, e.g. '*' does not work in Windows.
+
+                                                         *g:slimv_inspect_name*
+Name of the Inspect buffer. Default is 'INSPECT'. Space and some other special
+characters need to be escaped (e.g. 'Slimv\ Incpector', '\#INSPECT\#').
+Not all special characters are allowed, e.g. '*' does not work in Windows.
+
                                                            *g:slimv_repl_split*
 Open the Lisp REPL buffer in a split window or in a separate buffer in Vim.
 The default is to use split window. If you prefer having REPL being in a hidden
 If this option is set to zero then no line is echoed at all, if set to -1
 then all lines are always echoed.
 
+                                                      *g:slimv_indent_maxlines*
+Maximum number of lines searched backwards for indenting special forms, like
+flet, labels, macrolet. Setting it to a high value may slow down indenting.
+
                                                               *g:slimv_balloon*
 Specifies if describe tooltips are on (see |swank-describe|).
 
     let g:slimv_template_apropos = '(apropos "%1")'
 
 -------------------------------------------------------------------------------
-                                                               *slimv_keyboard*
+                                                               *slimv-keyboard*
 
 The default keybindings (|g:slimv_keybindings|=1) and another easy to remember
 built-in keybinding set (|g:slimv_keybindings|=2) for Slimv are the following.
     ,m      ,ma      Macroexpand All
     ,t      ,dt      Toggle Trace
     ,T      ,du      Untrace All
+    ,B      ,db      Set Breakpoint
     ,l      ,dd      Disassemble
     ,i      ,di      Inspect (inspects in frame when in SLDB)
     ,a      ,da      Abort
 There are various methods for evaluating an s-expression in the SWANK server.
 It is possible to eval the current top level form, the current subform, the
 visually selected area, or the whole buffer. Consult the "Evaluation commands"
-section in |slimv_keyboard| for the possible functions with their respective
+section in |slimv-keyboard| for the possible functions with their respective
 keyboard shortcuts.
 
 
   swank:frame-source-location
   swank:fuzzy-completions
   swank:init-inspector
+  swank:inspect-frame-var
   swank:inspect-in-frame
   swank:inspect-nth-part
   swank:inspector-call-nth-action
 ===============================================================================
 CHANGE LOG                                                    *slimv-changelog*
 
+0.9.2  - Added option g:swank_log to enable swank debug log.
+       - Added options g:slimv_repl_name, g:slimv_sldb_name, g:slimv_inspect_name.
+       - Added option g:slimv_indent_maxlines.
+       - Changed Debug-Thread mapping to <leader>dT (g:slimv_keybindings=2)
+         due to conflict with Generate-Tags.
+       - Label thread ID in thread list (by Philipp Marek).
+       - Set balloonexpr for all buffers (thanks to Philipp Marek).
+       - Connect swank server when needed instead of printing an error message
+         (by Philipp Marek).
+       - Set expandtab for lisp and clojure files.
+       - Kill-Thread kills all threads in the selected range (by Philipp Marek).
+       - Bugfix: added missing parts of Set-Breakpoint introduced in 0.9.1.
+       - Bugfix: test source lookup (upon pressing Enter) before testing
+         fold toggle in SLDB (by Philipp Marek).
+       - Bugfix: indentation of flet, labels, macrolet.
+       - Bugfix: Kill-Thread now really kills thread (by Philipp Marek).
+       - Bugfix: inspect gensyms in frame (by Philipp Marek).
+
 0.9.1  - Improved frame number identification in SLDB buffer.
        - Moved frame source location above frame locals in SLDB.
        - Fold frame source location if more than 2 lines.
 - Needs the same Python version that Vim is compiled against
 - It is not possible to run separate Lisp and Clojure REPL in the same
   Slimv session.
+- Recent macvim (OS X) versions seem to have a Python 2.7 binding problem
+  causing segmentation faults when Slimv tries to connect to the Swank server.
+  One possible solution is to rebuild macvim with Python binding changed to 2.6.
 
 
 ===============================================================================
 - Add missing SLIME functions to the SWANK client.
 - Continue separating other buffers (e.g. Threads) from the REPL buffer.
 - Allow connecting remote SWANK server (outside of localhost) via SSH.
+- Allow multiple REPL buffers in the same Vim session.
+- Allow multiple inferior lisps (e.g. one REPL to CLISP, another one to SBCL).
 
 ===============================================================================
 CREDITS                                                         *slimv-credits*

ftplugin/clojure/slimv-clojure.vim

 " slimv-clojure.vim:
 "               Clojure filetype plugin for Slimv
-" Version:      0.9.1
-" Last Change:  07 Oct 2011
+" Version:      0.9.2
+" Last Change:  20 Oct 2011
 " Maintainer:   Tamas Kovacs <kovisoft at gmail dot com>
 " License:      This file is placed in the public domain.
 "               No warranty, express or implied.
     return 'clojure'
 endfunction
 
-" Filename for the REPL buffer file
-function! b:SlimvREPLFile()
-    return 'Slimv.REPL.clj'
+" Filetype specific initialization for the REPL buffer
+function! b:SlimvInitRepl()
+    set filetype=clojure
 endfunction
 
 " Lookup symbol in the list of Clojure Hyperspec symbol databases

ftplugin/lisp/slimv-lisp.vim

 " slimv-lisp.vim:
 "               Lisp filetype plugin for Slimv
-" Version:      0.8.4
-" Last Change:  28 May 2011
+" Version:      0.9.2
+" Last Change:  20 Oct 2011
 " Maintainer:   Tamas Kovacs <kovisoft at gmail dot com>
 " License:      This file is placed in the public domain.
 "               No warranty, express or implied.
     return 'clisp'
 endfunction
 
-" Filename for the REPL buffer file
-function! b:SlimvREPLFile()
-    return 'Slimv.REPL.lisp'
+" Filetype specific initialization for the REPL buffer
+function! b:SlimvInitRepl()
+    set filetype=lisp
 endfunction
 
 " Lookup symbol in the list of Lisp Hyperspec symbol databases

ftplugin/scheme/slimv-scheme.vim

 " slimv-scheme.vim:
 "               Scheme filetype plugin for Slimv
-" Version:      0.8.4
-" Last Change:  28 May 2011
+" Version:      0.9.2
+" Last Change:  20 Oct 2011
 " Maintainer:   Tamas Kovacs <kovisoft at gmail dot com>
 " License:      This file is placed in the public domain.
 "               No warranty, express or implied.
     return 'mit'
 endfunction
 
-" Filename for the REPL buffer file
-function! b:SlimvREPLFile()
-    return 'Slimv.REPL.scm'
+" Filetype specific initialization for the REPL buffer
+function! b:SlimvInitRepl()
+    set filetype=scheme
 endfunction
 
 " Lookup symbol in the Hyperspec

ftplugin/slimv.vim

 " slimv.vim:    The Superior Lisp Interaction Mode for VIM
-" Version:      0.9.1
-" Last Change:  12 Oct 2011
+" Version:      0.9.2
+" Last Change:  25 Oct 2011
 " Maintainer:   Tamas Kovacs <kovisoft at gmail dot com>
 " License:      This file is placed in the public domain.
 "               No warranty, express or implied.
     let g:slimv_impl = b:SlimvImplementation()
 endif
 
-" Filename for the REPL buffer file
-if !exists( 'g:slimv_repl_file' )
-    let g:slimv_repl_file = b:SlimvREPLFile()
+" REPL buffer name
+if !exists( 'g:slimv_repl_name' )
+    let g:slimv_repl_name = 'REPL'
+endif
+
+" SLDB buffer name
+if !exists( 'g:slimv_sldb_name' )
+    let g:slimv_sldb_name = 'SLDB'
+endif
+
+" INSPECT buffer name
+if !exists( 'g:slimv_inspect_name' )
+    let g:slimv_inspect_name = 'INSPECT'
 endif
 
 " Shall we open REPL buffer in split window?
     endif
 endif
 
+" Maximum number of lines searched backwards for indenting special forms
+if !exists( 'g:slimv_indent_maxlines' )
+    let g:slimv_indent_maxlines = 20
+endif
+
 
 " =====================================================================
 "  Template definitions
 let s:prompt = ''                                         " Lisp prompt in the last line
 let s:indent = ''                                         " Most recent indentation info
 let s:last_update = 0                                     " The last update time for the REPL buffer
-let s:last_size = 0                                       " The last size of the REPL buffer
 let s:save_updatetime = &updatetime                       " The original value for 'updatetime'
 let s:save_showmode = &showmode                           " The original value for 'showmode'
 let s:python_initialized = 0                              " Is the embedded Python initialized?
 let s:skip_sc = 'synIDattr(synID(line("."), col("."), 0), "name") =~ "[Ss]tring\\|[Cc]omment"'
                                                           " Skip matches inside string or comment 
 let s:frame_def = '^\s\{0,2}\d\{1,3}:'                    " Regular expression to match SLDB restart or frame identifier
-let s:sldb_name      = 'Slimv.SLDB'                       " Name of the SLDB buffer
-let s:inspect_name   = 'Slimv.INSPECT'                    " Name of the Inspect buffer
+let s:spec_indent = 'flet\|labels\|macrolet'              " List of symbols need special indenting
 
 " =====================================================================
 "  General utility functions
 " Stop updating the REPL buffer and switch back to caller
 function! SlimvEndUpdateRepl()
     call SlimvMarkBufferEnd()
-    let repl_buf = bufnr( g:slimv_repl_file )
+    let repl_buf = bufnr( g:slimv_repl_name )
     let repl_win = bufwinnr( repl_buf )
     if repl_buf != s:current_buf && repl_win != -1 && !s:debug_activated
         " Switch back to the caller buffer/window
         return
     endif
 
-    let repl_buf = bufnr( g:slimv_repl_file )
+    let repl_buf = bufnr( g:slimv_repl_name )
     if repl_buf == -1
         " REPL buffer not loaded
         return
         " Put '<Insert>' twice into the typeahead buffer, which should not do anything
         " just switch to replace/insert mode then back to insert/replace mode
         " But don't do this for readonly buffers
-        if bufname('%') != s:sldb_name && bufname('%') != s:inspect_name
+        if bufname('%') != g:slimv_sldb_name && bufname('%') != g:slimv_inspect_name
             call feedkeys("\<insert>\<insert>")
         endif
     else
 " Called when entering REPL buffer
 function! SlimvReplEnter()
     call SlimvAddReplMenu()
-    execute "au FileChangedRO " . g:slimv_repl_file . " :call SlimvRefreshModeOff()"
+    execute "au FileChangedRO " . g:slimv_repl_name . " :call SlimvRefreshModeOff()"
     call SlimvRefreshModeOn()
 endfunction
 
 
 " Open a new REPL buffer
 function! SlimvOpenReplBuffer()
-    call SlimvOpenBuffer( g:slimv_repl_file )
+    call SlimvOpenBuffer( g:slimv_repl_name )
+    call b:SlimvInitRepl()
+    call PareditInitBuffer()
     if !g:slimv_repl_syntax
         set syntax=
     endif
     hi SlimvCursor term=reverse cterm=reverse gui=reverse
 
     " Add autocommands specific to the REPL buffer
-    execute "au FileChangedShell " . g:slimv_repl_file . " :call SlimvRefreshReplBuffer()"
-    execute "au FocusGained "      . g:slimv_repl_file . " :call SlimvRefreshReplBuffer()"
-    execute "au BufEnter "         . g:slimv_repl_file . " :call SlimvReplEnter()"
-    execute "au BufLeave "         . g:slimv_repl_file . " :call SlimvReplLeave()"
-
-    filetype on
-    redraw
-    let s:last_size = 0
+    execute "au FileChangedShell " . g:slimv_repl_name . " :call SlimvRefreshReplBuffer()"
+    execute "au FocusGained "      . g:slimv_repl_name . " :call SlimvRefreshReplBuffer()"
+    execute "au BufEnter "         . g:slimv_repl_name . " :call SlimvReplEnter()"
+    execute "au BufLeave "         . g:slimv_repl_name . " :call SlimvReplLeave()"
 
     call SlimvRefreshReplBuffer()
 endfunction
 
 " Open a new Inspect buffer
 function SlimvOpenInspectBuffer()
-    call SlimvOpenBuffer( s:inspect_name )
+    call SlimvOpenBuffer( g:slimv_inspect_name )
 
     " Add keybindings valid only for the Inspect buffer
     noremap  <buffer> <silent>        <CR>   :call SlimvHandleEnterInspect()<CR>
 
 " Open a new SLDB buffer
 function SlimvOpenSldbBuffer()
-    call SlimvOpenBuffer( s:sldb_name )
+    call SlimvOpenBuffer( g:slimv_sldb_name )
 
     " Add keybindings valid only for the SLDB buffer
     noremap  <buffer> <silent>        <CR>   :call SlimvHandleEnterSldb()<CR>
         " Hit the start of the file, use zero indent.
         return 0
     endif
-    " Find start of current form
-    let [l, c] = searchpairpos( '(', '', ')', 'nbW', s:skip_sc, pnum )
-    if l == pnum
-        let line = getline( l )
-        let parent = strpart( line, 0, c )
-        if match( parent, '\c(\s*\(flet\|labels\|macrolet\)\s*(\s*(\s*$' ) >= 0
-            " Handle special indentation style for flet, labels, etc.
-            return c + 1
+
+    " Handle special indentation style for flet, labels, etc.
+    " When searching for containing forms, don't go back
+    " more than g:slimv_indent_maxlines lines.
+    let backline = max([pnum-g:slimv_indent_maxlines, 1])
+    let oldpos = getpos( '.' )
+    " Find beginning of the innermost containing form
+    let [l, c] = searchpairpos( '(', '', ')', 'bW', s:skip_sc, backline )
+    if l > 0
+        " Is this a form with special indentation?
+        if match( getline(l), '\c^(\s*\('.s:spec_indent.'\)\>', c-1 ) >= 0
+            " Search for the binding list and jump to its end
+            if search( '(' ) > 0
+                exe 'normal! %'
+                if line('.') == pnum
+                    " We are indenting the first line after the end of the binding list
+                    call setpos( '.', oldpos )
+                    return c + 1
+                endif
+            endif
+        elseif l == pnum
+            " If the containing form starts above this line then find the
+            " second outer containing form (possible start of the binding list)
+            let [l2, c2] = searchpairpos( '(', '', ')', 'bW', s:skip_sc, backline )
+            if l2 > 0
+                " Go one level higher and check if we reached a special form
+                let [l3, c3] = searchpairpos( '(', '', ')', 'bW', s:skip_sc, backline )
+                if l3 > 0
+                    " Is this a form with special indentation?
+                    if match( getline(l3), '\c^(\s*\('.s:spec_indent.'\)\>', c3-1 ) >= 0
+                        " This is the first body-line of a binding
+                        call setpos( '.', oldpos )
+                        return c + 1
+                    endif
+                endif
+            endif
         endif
+        " Restore all cursor movements
+        call setpos( '.', oldpos )
+    endif
+
+    " Check if the current form started in the previous nonblank line
+    if l == pnum
         " Found opening paren in the previous line, let's find out the function name
-        let func = matchstr( line, '\<\k*\>', c )
+        let func = matchstr( getline(l), '\<\k*\>', c )
         " If it's a keyword, keep the indentation straight
         if strpart(func, 0, 1) == ':'
             return c
     let line = getline('.')
     if s:debug_activated
         " Check if Enter was pressed in a section printed by the SWANK debugger
+        " The source specification is within a fold, so it has to be tested first
+        let mlist = matchlist( line, '^\s\+in "\(.*\)" \(line\|byte\) \(\d\+\)$' )
+        if len(mlist)
+            if g:slimv_repl_split
+                " Switch back to other window
+                execute "wincmd w"
+            endif
+            " Jump to the file at the specified position
+            if mlist[2] == 'line'
+                exec ":edit +" . mlist[3] . " " . mlist[1]
+            else
+                exec ":edit +" . mlist[3] . "go " . mlist[1]
+            endif
+            return
+        endif
         if foldlevel('.')
             " With a fold just toggle visibility
             normal za
                 return
             endif
         endif
-        let mlist = matchlist( line, '^\s\+in "\(.*\)" \(line\|byte\) \(\d\+\)$' )
-        if len(mlist)
-            if g:slimv_repl_split
-                " Switch back to other window
-                execute "wincmd w"
-            endif
-            " Jump to the file at the specified position
-            if mlist[2] == 'line'
-                exec ":edit +" . mlist[3] . " " . mlist[1]
-            else
-                exec ":edit +" . mlist[3] . "go " . mlist[1]
-            endif
-            return
-        endif
     endif
 
     " No special treatment, perform the original function
 
 " Select a specific restart in debugger
 function! SlimvDebugCommand( cmd )
-    if s:swank_connected
+    if SlimvConnectSwank()
         if s:debug_activated
-            if bufname('%') != s:sldb_name
+            if bufname('%') != g:slimv_sldb_name
                 call SlimvOpenSldbBuffer()
             endif
             call SlimvQuitSldb()
         else
             call SlimvError( "Debugger is not activated." )
         endif
-    else
-        call SlimvError( "Not connected to SWANK server." )
     endif
 endfunction
 
 " List current Lisp threads
 function! SlimvListThreads()
-    if s:swank_connected
+    if SlimvConnectSwank()
         call SlimvCommand( 'python swank_list_threads()' )
         call SlimvRefreshReplBuffer()
-    else
-        call SlimvError( "Not connected to SWANK server." )
     endif
 endfunction
 
-" Kill thread selected from the Thread List
-function! SlimvKillThread()
-    if s:swank_connected
-        let line = getline('.')
-        let item = matchstr( line, '\d\+' )
-        let item = input( 'Thread to kill: ', item )
-        if item != ''
-            call SlimvCommand( 'python swank_debug_thread(' . item . ')' )
+" Kill thread(s) selected from the Thread List
+function! SlimvKillThread() range
+    if SlimvConnectSwank()
+        if a:firstline == a:lastline
+            let line = getline('.')
+            let item = matchstr( line, '\d\+' )
+            let item = input( 'Thread to kill: ', item )
+            if item != ''
+                call SlimvCommand( 'python swank_kill_thread(' . item . ')' )
+                call SlimvRefreshReplBuffer()
+            endif
+        else
+            for line in getline(a:firstline, a:lastline)
+                let item = matchstr( line, '\d\+' )
+                if item != ''
+                    call SlimvCommand( 'python swank_kill_thread(' . item . ')' )
+                endif
+            endfor
             call SlimvRefreshReplBuffer()
         endif
-    else
-        call SlimvError( "Not connected to SWANK server." )
     endif
 endfunction
 
 " Debug thread selected from the Thread List
 function! SlimvDebugThread()
-    if s:swank_connected
+    if SlimvConnectSwank()
         let line = getline('.')
         let item = matchstr( line, '\d\+' )
         let item = input( 'Thread to debug: ', item )
             call SlimvCommand( 'python swank_debug_thread(' . item . ')' )
             call SlimvRefreshReplBuffer()
         endif
-    else
-        call SlimvError( "Not connected to SWANK server." )
     endif
 endfunction
 
 " This is a quite dummy function that just evaluates the empty string
 function! SlimvConnectServer()
     call SlimvBeginUpdate()
-    let repl_buf = bufnr( g:slimv_repl_file )
+    let repl_buf = bufnr( g:slimv_repl_name )
     let repl_win = bufwinnr( repl_buf )
     if repl_buf == -1 || ( g:slimv_repl_split && repl_win == -1 )
         call SlimvOpenReplBuffer()
 function! s:DebugFrame()
     if s:swank_connected && s:debug_activated
         " Check if we are in SLDB
-        let repl_buf = bufnr( s:sldb_name )
+        let repl_buf = bufnr( g:slimv_sldb_name )
         if repl_buf != -1 && repl_buf == bufnr( "%" )
             let bcktrpos = search( '^Backtrace:', 'bcnw' )
             let framepos = line( '.' )
 
 " Macroexpand-1 the current top level form
 function! SlimvMacroexpand()
-    if s:swank_connected
+    if SlimvConnectSwank()
         if !SlimvSelectForm()
             return
         endif
 
 " Macroexpand the current top level form
 function! SlimvMacroexpandAll()
-    if s:swank_connected
+    if SlimvConnectSwank()
         if !SlimvSelectForm()
             return
         endif
         let s:swank_form = SlimvGetSelection()
         call SlimvCommandUsePackage( 'python swank_macroexpand_all("s:swank_form")' )
-    else
-        call SlimvError( "Not connected to SWANK server." )
     endif
 endfunction
 
 " Set a breakpoint on the beginning of a function
 function! SlimvBreak()
-    if s:swank_connected
+    if SlimvConnectSwank()
         let s = input( 'Set breakpoint: ', SlimvSelectSymbol() )
         if s != ''
             call SlimvCommandUsePackage( 'python swank_set_break("' . s . '")' )
             redraw!
         endif
-    else
-        call SlimvError( "Not connected to SWANK server." )
     endif
 endfunction
 
 " Switch trace on for the selected function (toggle for swank)
 function! SlimvTrace()
-    if s:swank_connected
+    if SlimvConnectSwank()
         let s = input( '(Un)trace: ', SlimvSelectSymbol() )
         if s != ''
             call SlimvCommandUsePackage( 'python swank_toggle_trace("' . s . '")' )
             redraw!
         endif
-    else
-        call SlimvError( "Not connected to SWANK server." )
     endif
 endfunction
 
 " Switch trace off for the selected function (or all functions for swank)
 function! SlimvUntrace()
-    if s:swank_connected
+    if SlimvConnectSwank()
         let s:refresh_disabled = 1
         call SlimvCommand( 'python swank_untrace_all()' )
         let s:refresh_disabled = 0
         call SlimvRefreshReplBuffer()
-    else
-        call SlimvError( "Not connected to SWANK server." )
     endif
 endfunction
 
 " Disassemble the selected function
 function! SlimvDisassemble()
-    let s = input( 'Disassemble: ', SlimvSelectSymbol() )
-    if s != ''
-        if s:swank_connected
+    if SlimvConnectSwank()
+        let s = input( 'Disassemble: ', SlimvSelectSymbol() )
+        if s != ''
             call SlimvCommandUsePackage( 'python swank_disassemble("' . s . '")' )
-        else
-            call SlimvError( "Not connected to SWANK server." )
         endif
     endif
 endfunction
 
 " Inspect symbol under cursor
 function! SlimvInspect()
+    if !SlimvConnectSwank()
+        return
+    endif
     let frame = s:DebugFrame()
     if frame != ''
         " Inspect selected for a frame in the debugger's Backtrace section
     else
         let s = input( 'Inspect: ', SlimvSelectSymbolExt() )
         if s != ''
-            if s:swank_connected
-                call SlimvBeginUpdate()
-                call SlimvCommandUsePackage( 'python swank_inspect("' . s . '")' )
-            else
-                call SlimvError( "Not connected to SWANK server." )
-            endif
+            call SlimvBeginUpdate()
+            call SlimvCommandUsePackage( 'python swank_inspect("' . s . '")' )
         endif
     endif
 endfunction
 
 " Cross reference: who calls
 function! SlimvXrefBase( text, cmd )
-    if s:swank_connected
+    if SlimvConnectSwank()
         let s = input( a:text, SlimvSelectSymbol() )
         if s != ''
             call SlimvCommandUsePackage( 'python swank_xref("' . s . '", "' . a:cmd . '")' )
         endif
-    else
-        call SlimvError( "Not connected to SWANK server." )
     endif
 endfunction
 
 
 " Switch or toggle profiling on for the selected function
 function! SlimvProfile()
-    if s:swank_connected
+    if SlimvConnectSwank()
         let s = input( '(Un)profile: ', SlimvSelectSymbol() )
         if s != ''
             call SlimvCommandUsePackage( 'python swank_toggle_profile("' . s . '")' )
             redraw!
         endif
-    else
-        call SlimvError( "Not connected to SWANK server." )
     endif
 endfunction
 
 " Switch profiling on based on substring
 function! SlimvProfileSubstring()
-    if s:swank_connected
+    if SlimvConnectSwank()
         let s = input( 'Profile by matching substring: ', SlimvSelectSymbol() )
         if s != ''
             let p = input( 'Package (RET for all packages): ' )
             call SlimvCommandUsePackage( 'python swank_profile_substring("' . s . '","' . p . '")' )
             redraw!
         endif
-    else
-        call SlimvError( "Not connected to SWANK server." )
     endif
 endfunction
 
 " Switch profiling completely off
 function! SlimvUnprofileAll()
-    if s:swank_connected
+    if SlimvConnectSwank()
         call SlimvCommandUsePackage( 'python swank_unprofile_all()' )
-    else
-        call SlimvError( "Not connected to SWANK server." )
     endif
 endfunction
 
 " Display list of profiled functions
 function! SlimvShowProfiled()
-    if s:swank_connected
+    if SlimvConnectSwank()
         call SlimvCommandUsePackage( 'python swank_profiled_functions()' )
-    else
-        call SlimvError( "Not connected to SWANK server." )
     endif
 endfunction
 
 " Report profiling results
 function! SlimvProfileReport()
-    if s:swank_connected
+    if SlimvConnectSwank()
         call SlimvCommandUsePackage( 'python swank_profile_report()' )
-    else
-        call SlimvError( "Not connected to SWANK server." )
     endif
 endfunction
 
 " Reset profiling counters
 function! SlimvProfileReset()
-    if s:swank_connected
+    if SlimvConnectSwank()
         call SlimvCommandUsePackage( 'python swank_profile_reset()' )
-    else
-        call SlimvError( "Not connected to SWANK server." )
     endif
 endfunction
 
         call setpos( '.', oldpos ) 
         return
     endif
-    if s:swank_connected
+    if SlimvConnectSwank()
         let s:swank_form = SlimvGetSelection()
         call SlimvCommandUsePackage( 'python swank_compile_string("s:swank_form")' )
-    else
-        call SlimvError( "Not connected to SWANK server." )
     endif
 endfunction
 
             write
         endif
     endif
-    if s:swank_connected
+    if SlimvConnectSwank()
         let s:compiled_file = ''
         call SlimvCommandUsePackage( 'python swank_compile_file("' . filename . '")' )
         let starttime = localtime()
             call SlimvCommandUsePackage( 'python swank_load_file("' . s:compiled_file . '")' )
             let s:compiled_file = ''
         endif
-    else
-        call SlimvError( "Not connected to SWANK server." )
     endif
 endfunction
 
             write
         endif
     endif
-    if s:swank_connected
+    if SlimvConnectSwank()
         call SlimvCommandUsePackage( 'python swank_compile_file("' . filename . '")' )
-    else
-        call SlimvError( "Not connected to SWANK server." )
     endif
 endfunction
 
         return
     endif
     let region = join( lines, "\n" )
-    if s:swank_connected
+    if SlimvConnectSwank()
         let s:swank_form = region
         call SlimvCommandUsePackage( 'python swank_compile_string("s:swank_form")' )
-    else
-        call SlimvError( "Not connected to SWANK server." )
     endif
 endfunction
 
 
 " Describe the selected symbol
 function! SlimvDescribeSymbol()
-    if s:swank_connected
+    if SlimvConnectSwank()
         call SlimvCommandUsePackage( 'python swank_describe_symbol("' . SlimvSelectSymbol() . '")' )
-    else
-        call SlimvError( "Not connected to SWANK server." )
     endif
 endfunction
 
     if a:arg == ''
         let arg = expand('<cword>')
     endif
+    " We don't want to try connecting here ... the error message would just 
+    " confuse the balloon logic
     if !s:swank_connected
         return ''
     endif
     endif
 endfunction
 
-" Setup balloonexp to display symbol description
-if g:slimv_balloon && has( 'balloon_eval' )
-    "setlocal balloondelay=100
-    setlocal ballooneval
-    setlocal balloonexpr=SlimvDescribe(v:beval_text)
-endif
-
 " Apropos of the selected symbol
 function! SlimvApropos()
     call SlimvEvalForm1( g:slimv_template_apropos, SlimvSelectSymbol() )
 
 " Set current package
 function! SlimvSetPackage()
-    if s:swank_connected
+    if SlimvConnectSwank()
         call SlimvFindPackage()
         let pkg = input( 'Package: ', s:swank_package )
         if pkg != ''
             let s:refresh_disabled = 0
             call SlimvRefreshReplBuffer()
         endif
-    else
-        call SlimvError( "Not connected to SWANK server." )
     endif
 endfunction
 
     au InsertLeave * :let &showmode=s:save_showmode
     inoremap <silent> <buffer> <C-X>0     <C-O>:call SlimvCloseForm()<CR>
     inoremap <silent> <buffer> <Tab>      <C-R>=pumvisible() ? "\<lt>C-N>" : "\<lt>C-X>\<lt>C-O>"<CR>
+
+    " Setup balloonexp to display symbol description
+    if g:slimv_balloon && has( 'balloon_eval' )
+        "setlocal balloondelay=100
+        setlocal ballooneval
+        setlocal balloonexpr=SlimvDescribe(v:beval_text)
+    endif
 endfunction
 
 " Edit commands
 call s:MenuMap( 'Slim&v.De&bugging.-ThreadSep-',                '',                  '',                   ':' )
 call s:MenuMap( 'Slim&v.De&bugging.List-T&hreads',              g:slimv_leader.'H',  g:slimv_leader.'dl',  ':call SlimvListThreads()<CR>' )
 call s:MenuMap( 'Slim&v.De&bugging.&Kill-Thread\.\.\.',         g:slimv_leader.'K',  g:slimv_leader.'dk',  ':call SlimvKillThread()<CR>' )
-call s:MenuMap( 'Slim&v.De&bugging.&Debug-Thread\.\.\.',        g:slimv_leader.'G',  g:slimv_leader.'dg',  ':call SlimvDebugThread()<CR>' )
+call s:MenuMap( 'Slim&v.De&bugging.&Debug-Thread\.\.\.',        g:slimv_leader.'G',  g:slimv_leader.'dT',  ':call SlimvDebugThread()<CR>' )
 
 
 " Compile commands

ftplugin/swank.py

 #
 # SWANK client for Slimv
 # swank.py:     SWANK client code for slimv.vim plugin
-# Version:      0.9.1
-# Last Change:  12 Oct 2011
+# Version:      0.9.2
+# Last Change:  26 Oct 2011
 # Maintainer:   Tamas Kovacs <kovisoft at gmail dot com>
 # License:      This file is placed in the public domain.
 #               No warranty, express or implied.
 package         = 'COMMON-LISP-USER' # Current package
 actions         = dict()        # Swank actions (like ':write-string'), by message id
 indent_info     = dict()        # Data of :indentation-update
+frame_locals    = dict()        # Map frame variable names to their index
 
 
 ###############################################################################
     logprint(str(lst))
     idx = 0
     for t in lst:
-        buf = buf + "\n%3d. %3d: %-22s %s" % (idx, int(t[0]), unquote(t[2]), unquote(t[1]))
+        buf = buf + "\n%3d. ID%3d: %-22s %s" % (idx, int(t[0]), unquote(t[2]), unquote(t[1]))
         idx = idx + 1
     return buf
 
     """
     Parse frame locals output
     """
-    vim.command('call SlimvGotoFrame(' + action.data + ')')
+    frame_num = action.data
+    vim.command('call SlimvGotoFrame(' + frame_num + ')')
     buf = vim.current.buffer
     win = vim.current.window
     line = win.cursor[0]
     if type(struct) == list:
         lines = '    Locals:'
+        num = 0
         for f in struct:
             name  = parse_plist(f, ':name')
             id    = parse_plist(f, ':id')
             value = parse_plist(f, ':value')
             lines = lines + '\n      ' + name + ' = ' + value
+            # Remember variable index in frame
+            frame_locals[str(frame_num) + " " + name] = num
+            num = num + 1
     else:
         lines = '    No locals'
     buf[line:line] = lines.split("\n")
                             to_ignore = [':frame-call', ':quit-inspector']
                             to_nodisp = [':describe-symbol']
                             to_prompt = [':undefine-function', ':swank-macroexpand-1', ':swank-macroexpand-all', ':disassemble-form', \
-                                         ':load-file', ':toggle-profile-fdefinition', ':profile-by-substring', ':swank-toggle-trace']
+                                         ':load-file', ':toggle-profile-fdefinition', ':profile-by-substring', ':swank-toggle-trace', 'sldb-break']
                             if action and action.name in to_ignore:
                                 # Just ignore the output for this message
                                 pass
                     current_thread = r[1]
                     sldb_level = r[2]
                     vim.command('let s:debug_activated=' + sldb_level)
+                    frame_locals.clear()
 
                 elif message == ':debug-return':
                     debug_active = False
 ###############################################################################
 
 def swank_connection_info():
+    global log
     actions.clear()
     indent_info.clear()
+    frame_locals.clear()
     debug_activated = False
+    if vim.eval('exists("g:swank_log") && g:swank_log') != '0':
+        log = True
     swank_rex(':connection-info', '(swank:connection-info)', 'nil', 't')
 
 def swank_create_repl():
     swank_rex(':inspector-pop', '(swank:inspector-pop)', 'nil', 't')
 
 def swank_inspect_in_frame(symbol, n):
-    cmd = '(swank:inspect-in-frame "' + symbol + '" ' + str(n) + ')'
+    key = str(n) + " " + symbol
+    if frame_locals.has_key(key):
+        cmd = '(swank:inspect-frame-var ' + str(n) + " " + str(frame_locals[key]) + ')'
+    else:
+        cmd = '(swank:inspect-in-frame "' + symbol + '" ' + str(n) + ')'
     swank_rex(':inspect-in-frame', cmd, get_swank_package(), current_thread, str(n))
 
 def swank_quit_inspector():
     swank_rex(':quit-inspector', '(swank:quit-inspector)', 'nil', 't')
 
+def swank_set_break(symbol):
+    cmd = '(swank:sldb-break"' + symbol + '")'
+    swank_rex(':sldb-break', cmd, get_package(), 't')
+
 def swank_toggle_trace(symbol):
     cmd = '(swank:swank-toggle-trace "' + symbol + '")'
     swank_rex(':swank-toggle-trace', cmd, get_package(), 't')

indent/clojure.vim

 " clojure.vim:
 "               Clojure indent plugin for Slimv
-" Version:      0.8.6
-" Last Change:  13 Aug 2011
+" Version:      0.9.2
+" Last Change:  21 Oct 2011
 " Maintainer:   Tamas Kovacs <kovisoft at gmail dot com>
 " License:      This file is placed in the public domain.
 "               No warranty, express or implied.
 
 setlocal nolisp
 setlocal autoindent
+setlocal expandtab
 setlocal indentexpr=SlimvIndent(v:lnum)
 
 " lisp.vim:
 "               Lisp indent plugin for Slimv
-" Version:      0.8.3
-" Last Change:  14 May 2011
+" Version:      0.9.2
+" Last Change:  21 Oct 2011
 " Maintainer:   Tamas Kovacs <kovisoft at gmail dot com>
 " License:      This file is placed in the public domain.
 "               No warranty, express or implied.
 
 setlocal nolisp
 setlocal autoindent
+setlocal expandtab
 setlocal indentexpr=SlimvIndent(v:lnum)
 
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.