From 252cca6428848945fa0d651cc034f70581bfce36 Mon Sep 17 00:00:00 2001 From: Tamas Kovacs Date: Sat, 10 Mar 2012 00:00:00 +0000 Subject: [PATCH] Version 0.9.5 Use correct SLDB level when invoking restart. Autodetect tmux session on Linux (thanks to Brett Kosinski). Enable syntax only once to avoid reload of syntax plugins. Added option g:slimv_browser_cmd_suffix. Skip syntax and indent file for disabled filetypes. Check the presence of X on Linux. Indentation fixes: keywords, gap after '(', defsystem, defmacro, symbol-macrolet. Use winsaveview()/winrestview() for remembering current view when moving around (e.g. searching for package). Find package for arglist and completion. Ignore mapleader when it's . Print SLDB error description also into the REPL buffer. Evaluate keyword if using Eval-Defun outside of s-expression. Disable unsupported swank features for Scheme. Bugfixes: Paredit 'cw' at the end of line. Omit REPL prompt from Eval-Defun and Eval-Expression. Printing of '\n' and other escaped characters. Paredit delete and put corrupted the "0 register. --- doc/slimv.txt | 77 +++++++++-- ftplugin/scheme/slimv-scheme.vim | 12 +- ftplugin/slimv.vim | 171 ++++++++++++++++-------- ftplugin/swank.py | 37 +++-- indent/clojure.vim | 6 +- indent/lisp.vim | 13 +- indent/scheme.vim | 23 ++++ plugin/paredit.vim | 44 +++--- syntax/clojure/slimv-syntax-clojure.vim | 6 +- syntax/scheme/slimv-syntax-scheme.vim | 6 +- 10 files changed, 283 insertions(+), 112 deletions(-) create mode 100644 indent/scheme.vim diff --git a/doc/slimv.txt b/doc/slimv.txt index 2a94fd6..f375107 100644 --- a/doc/slimv.txt +++ b/doc/slimv.txt @@ -1,7 +1,7 @@ -*slimv.txt* Slimv Last Change: 23 Jan 2012 +*slimv.txt* Slimv Last Change: 10 Mar 2012 Slimv *slimv* - Version 0.9.4 + Version 0.9.5 The Superior Lisp Interaction Mode for Vim. This plugin is aimed to help Lisp development by interfacing between Vim and @@ -129,6 +129,8 @@ For the Swank options plese visit |swank-configuration|. |g:slimv_browser_cmd| If nonempty, this command is used to open the Common Lisp Hyperspec. +|g:slimv_browser_cmd_suffix| Optional suffix for |g:slimv_browser_cmd| + |g:slimv_clhs_root| Base URL for the Common Lisp Hyperspec. |g:slimv_clhs_user_db| User defined extension for Slimv's built-in @@ -346,9 +348,11 @@ plain socket communication is supported, no SSH or whatsoever. Please note that if the SWANK server is on a remote machine then Slimv is unable to start it, so you need to run the SWANK server manually. -Actually there is a workaround for this: run Vim inside a GNU screen session. -Slimv will autodetect this and modify the Swank command so that the Swank -server is run inside a newly opened virtual terminal in screen. +Actually there is a workaround for this on Linux: run Vim inside a GNU screen +session. Slimv will autodetect this and modify the Swank command so that the +Swank server is run inside a newly opened virtual terminal in screen. +Slimv also autodetects an existing tmux session, so you can use tmux instead +of GNU screen for the same purpose. *g:swank_port* The SWANK server is connected to port 4005 by default. This can be changed @@ -383,8 +387,10 @@ Other values mean no predefined keybinding is wanted. *g:slimv_leader* This option allows a custom setting for the Slimv keybindings. -By default it has the same value as |mapleader|. If neither g:slimv_leader nor -mapleader are defined then the default is "," in Slimv. +By default it has the same value as |mapleader|, except when |mapleader| is + which is currently not supported by Slimv. +If neither g:slimv_leader nor |mapleader| are defined or |mapleader| is +then the default is "," in Slimv. Example: let g:slimv_leader = '\' If this is set in the .vimrc then Eval-Defun will be mapped to \d instead of ,d. @@ -404,6 +410,16 @@ the .html extension (on Windows) or xdg-open (on Linux) is used to start the browser. If xdg-open is not installed then the Python webbrowser package is used to identify the default browser on Linux. + *g:slimv_browser_cmd_suffix* +When using option |g:slimv_browser_cmd| the Hyperspec page URL is appended to +the browser command. However sometimes it might be needed to add a suffix +at the end of the browser command. +Slimv automatically adds the "&" suffix in order to fork the browser and +return control immediately to Vim. If you don't want to fork the browser +then set |g:slimv_browser_cmd_suffix| to "". Also use this option if you want +to have extra parameters or commands in the browser command after the URL, +but in this case remember to add the "&" when forking is needed. + *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\#'). @@ -1288,11 +1304,12 @@ FAQ *slimv-faq* - Q: There is no SWANK server opened when I evaluate a form in Vim. - A: There may be many reasons for that. Try to run the SWANK server manually, Slimv detects if a SWANK server is running and is able to connect it. - Check if the port number matches in Slimv and the SWANK server. - Verify the SWANK server command autodetected by Slimv: + - Check if the port number matches in Slimv and the SWANK server and + :dont-close is set to 't'. + - Verify the SWANK server command autodetected by Slimv: :echo SlimvSwankCommand() - Also check the following Slimv variables in Vim, maybe they are not - correctly autodetected and you need to override them in your .vimrc: + - Also check the following Slimv variables in Vim, maybe they are not + correctly autodetected and you need to override them in your .vimrc: :echo g:slimv_lisp :echo g:slimv_swank_cmd (or g:slimv_swank_clojure for Clojure) @@ -1313,6 +1330,21 @@ FAQ *slimv-faq* Also make sure that no other ftplugin/lisp.vim is loaded that prevents loading of the Slimv scripts. +- Q: I experience weird problems when using the plugin, e.g. incorrect key + mappings, strange error messages, indentation missing, etc. +- A: You may have an installation problem, try to completely remove then + reinstall the plugin. + It may also cause problems when you have the Slimv repository checked + out directly into vimfiles. Checkout the project to somewhere else and + copy only the relevant Slimv files to vimfiles. + Most problems may be spot by enabling Vim's verbose mode and examining + the resulting logfile. Either run Vim this way: 'vim -V20test.log' or + enable verbose mode runtime just before the problem happens: + :set verbosefile=test.log + :set verbose=20 + It is also possible to save a log of the communication between Slimv and + the swank server by setting g:swank_log=1 in the .vimrc. + - Q: Why is SLIME functionality XYZ missing from Slimv? - A: Not all SLIME functions are implemented in the SWANK client, however the list of these functions keep growing. Maybe future releases will @@ -1358,6 +1390,26 @@ FAQ *slimv-faq* =============================================================================== CHANGE LOG *slimv-changelog* +0.9.5 - Use correct SLDB level when invoking restart. + - Autodetect tmux session on Linux (thanks to Brett Kosinski). + - Enable syntax only once to avoid reload of syntax plugins. + - Added option g:slimv_browser_cmd_suffix. + - Skip syntax and indent file for disabled filetypes. + - Check the presence of X on Linux. + - Indentation fixes: keywords, gap after '(', defsystem, defmacro, + symbol-macrolet. + - Use winsaveview()/winrestview() for remembering current view when + moving around (e.g. searching for package). + - Find package for arglist and completion. + - Ignore mapleader when it's . + - Print SLDB error description also into the REPL buffer. + - Evaluate keyword if using Eval-Defun outside of s-expression. + - Disable unsupported swank features for Scheme. + - Bugfix: Paredit 'cw' at the end of line. + - Bugfix: omit REPL prompt from Eval-Defun and Eval-Expression. + - Bugfix: printing of '\n' and other escaped characters. + - Bugfix: Paredit delete and put corrupted the "0 register. + 0.9.4 - Added highlighting of [] and {} for Clojure. - Added options to disable Slimv for specific filetypes: g:slimv_disable_clojure, g:slimv_disable_lisp, g:slimv_disable_scheme. @@ -1805,7 +1857,8 @@ Also thanks to Vlad Hanciuta, Marcin Fatyga, Dmitry Petukhov, Daniel Solano Gómez, Brian Kropf, Len Weincier, Andreas Salwasser, Jon Thacker, Andrew Hills, Jerome Baum, John Obbele, Andreas Fredriksson, Ömer Sinan Agacan, Tobias Pflug, Chris Cahoon, Mats Rauhala, Oleg Terenchuk, -Andrew Lyon, Andrew Smirnoff for additional notes and contributions. +Andrew Lyon, Andrew Smirnoff, Brett Kosinski for additional notes and +contributions. I would also like to say a big thank you to everyone donating to support development. This is a one-element list at the moment: :) diff --git a/ftplugin/scheme/slimv-scheme.vim b/ftplugin/scheme/slimv-scheme.vim index 7e0ed56..c57c9b1 100644 --- a/ftplugin/scheme/slimv-scheme.vim +++ b/ftplugin/scheme/slimv-scheme.vim @@ -1,7 +1,7 @@ " slimv-scheme.vim: " Scheme filetype plugin for Slimv -" Version: 0.9.4 -" Last Change: 07 Jan 2012 +" Version: 0.9.5 +" Last Change: 06 Mar 2012 " Maintainer: Tamas Kovacs " License: This file is placed in the public domain. " No warranty, express or implied. @@ -68,11 +68,17 @@ endfunction " Source Slimv general part runtime ftplugin/**/slimv.vim -endif "!exists( 'g:slimv_lisp_loaded' ) +endif "!exists( 'g:slimv_scheme_loaded' ) " ---------- End of part loaded once ---------- runtime ftplugin/**/lisp.vim +" The balloonexpr of MIT-Scheme is broken. Disable it. +let g:slimv_balloon = 0 + +" The fuzzy completion of MIT-Scheme is broken. Disable it. +let g:slimv_simple_compl = 1 + " Must be called for each lisp buffer call SlimvInitBuffer() diff --git a/ftplugin/slimv.vim b/ftplugin/slimv.vim index 385e7bd..9dd1ed5 100644 --- a/ftplugin/slimv.vim +++ b/ftplugin/slimv.vim @@ -1,6 +1,6 @@ " slimv.vim: The Superior Lisp Interaction Mode for VIM -" Version: 0.9.4 -" Last Change: 22 Jan 2012 +" Version: 0.9.5 +" Last Change: 07 Mar 2012 " Maintainer: Tamas Kovacs " License: This file is placed in the public domain. " No warranty, express or implied. @@ -92,10 +92,17 @@ function! SlimvSwankCommand() elseif g:slimv_osx return '!osascript -e "tell application \"Terminal\" to do script \"' . cmd . '\""' elseif $STY != '' - " GNU screen under Linux - return '! screen -X eval "title slimv" "screen ' . cmd . '" "select slimv"' + " GNU screen under Linux + return '! screen -X eval "title swank" "screen ' . cmd . '" "select swank"' + elseif $TMUX != '' + " tmux under Linux + return "! tmux new-window -d -n swank '" . cmd . "'" + elseif $DISPLAY == '' + " No X, no terminal multiplexer. Cannot run swank server. + call SlimvErrorWait( 'No X server. Run Vim from screen/tmux or start SWANK server manually.' ) + return '' else - " Must be Linux + " Must be Linux return '! xterm -iconic -e ' . cmd . ' &' endif endif @@ -229,7 +236,7 @@ endif " Custom for the Slimv plugin if !exists( 'g:slimv_leader' ) - if exists( 'mapleader' ) + if exists( 'mapleader' ) && mapleader != ' ' let g:slimv_leader = mapleader else let g:slimv_leader = ',' @@ -277,7 +284,7 @@ let s:swank_connected = 0 " Is the SWANK server let s:swank_package = '' " Package to use at the next SWANK eval let s:swank_form = '' " Form to send to SWANK let s:refresh_disabled = 0 " Set this variable temporarily to avoid recursive REPL rehresh calls -let s:debug_activated = 0 " Are we in the SWANK debugger? +let s:sldb_level = -1 " Are we in the SWANK debugger? -1 == no, else SLDB level let s:compiled_file = '' " Name of the compiled file let s:au_curhold_set = 0 " Whether the autocommand has been set let s:current_buf = -1 " Swank action was requested from this buffer @@ -285,7 +292,9 @@ let s:current_win = -1 " Swank action was req 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:spec_indent = 'flet\|labels\|macrolet' " List of symbols need special indenting +let s:spec_indent = 'flet\|labels\|macrolet\|symbol-macrolet' + " List of symbols need special indenting +let s:spec_param = 'defmacro' " List of symbols with special parameter list let s:binding_form = 'let\|let\*' " List of symbols with binding list " ===================================================================== @@ -381,7 +390,7 @@ function! SlimvEndUpdateRepl() call SlimvMarkBufferEnd() 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 + if repl_buf != s:current_buf && repl_win != -1 && s:sldb_level < 0 " Switch back to the caller buffer/window if g:slimv_repl_split if s:current_win == -1 @@ -711,7 +720,7 @@ function SlimvOpenSldbBuffer() execute 'noremap ' . g:slimv_leader.'dq :call SlimvDebugCommand("swank_throw_toplevel")' execute 'noremap ' . g:slimv_leader.'dn :call SlimvDebugCommand("swank_invoke_continue")' endif - + " Set folding parameters setlocal foldmethod=marker setlocal foldmarker={{{,}}} @@ -863,17 +872,25 @@ endfunction function! SlimvSelectForm() " Search the opening '(' if we are standing on a special form prefix character let c = col( '.' ) - 1 + let firstchar = getline( '.' )[c] while c < len( getline( '.' ) ) && match( "'`#", getline( '.' )[c] ) >= 0 normal! l let c = c + 1 endwhile + let p1 = getpos('.') normal! va(o - " Handle '() or #'() etc. type special syntax forms - let c = col( '.' ) - 2 - while c >= 0 && match( ' \t()', getline( '.' )[c] ) < 0 - normal! h - let c = c - 1 - endwhile + let p2 = getpos('.') + if firstchar != '(' && p1[1] == p2[1] && (p1[2] == p2[2] || p1[2] == p2[2]+1) + " Empty selection and no paren found, select current word instead + normal! aw + else + " Handle '() or #'() etc. type special syntax forms (but stop at prompt) + let c = col( '.' ) - 2 + while c >= 0 && match( ' \t()>', getline( '.' )[c] ) < 0 + normal! h + let c = c - 1 + endwhile + endif silent normal! "sy let sel = SlimvGetSelection() if sel == '' @@ -912,7 +929,7 @@ function! SlimvFindPackage() if !g:slimv_package || SlimvGetFiletype() == 'scheme' return endif - let oldpos = getpos( '.' ) + let oldpos = winsaveview() if SlimvGetFiletype() == 'clojure' let string = '\(in-ns\|ns\)' else @@ -939,15 +956,13 @@ function! SlimvFindPackage() let s:swank_package = '' endif endif - call setpos( '.', oldpos ) + call winrestview( oldpos ) endfunction " Execute the given SWANK command with current package defined function! SlimvCommandUsePackage( cmd ) - let oldpos = getpos( '.' ) call SlimvFindPackage() let s:refresh_disabled = 1 - call setpos( '.', oldpos ) call SlimvCommand( a:cmd ) let s:swank_package = '' let s:refresh_disabled = 0 @@ -1029,8 +1044,8 @@ function! SlimvConnectSwank() let cmd = cmd . " (make-string " . g:swank_block_size . ")) nil)" call SlimvSend( [cmd], 0, 1 ) endif - if exists( "*b:SlimvReplInit" ) - " Perform implementation specific REPL initialization if supplied + if exists( "*b:SlimvReplInit" ) + " Perform implementation specific REPL initialization if supplied call b:SlimvReplInit( s:lisp_version ) endif endif @@ -1211,7 +1226,7 @@ function! SlimvIndent( lnum ) " 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( '.' ) + let oldpos = winsaveview() let indent_keylists = g:slimv_indent_keylists " Find beginning of the innermost containing form normal! 0 @@ -1219,10 +1234,10 @@ function! SlimvIndent( lnum ) if l > 0 if SlimvGetFiletype() == 'clojure' " Is this a clojure form with [] binding list? - call setpos( '.', oldpos ) + call winrestview( oldpos ) let [lb, cb] = searchpairpos( '\[', '', '\]', 'bW', s:skip_sc, backline ) if lb >= l && (lb > l || cb > c) - call setpos( '.', oldpos ) + call winrestview( oldpos ) return cb endif endif @@ -1234,7 +1249,7 @@ function! SlimvIndent( lnum ) exe 'normal! %' if line('.') == pnum " We are indenting the first line after the end of the binding list - call setpos( '.', oldpos ) + call winrestview( oldpos ) return c + 1 endif endif @@ -1244,15 +1259,24 @@ function! SlimvIndent( lnum ) let [l2, c2] = searchpairpos( '(', '', ')', 'bW', s:skip_sc, backline ) if l2 > 0 let line2 = strpart( getline(l2), c2-1 ) + if match( line2, '\c^(\s*\('.s:spec_param.'\)\>' ) >= 0 + if search( '(' ) > 0 + if line('.') == l && col('.') == c + " This is the parameter list of a special form + call winrestview( oldpos ) + return c + endif + endif + endif if SlimvGetFiletype() != 'clojure' if l2 == l && match( line2, '\c^(\s*\('.s:binding_form.'\)\>' ) >= 0 " Is this a lisp form with binding list? - call setpos( '.', oldpos ) + call winrestview( oldpos ) return c endif if match( line2, '\c^(\s*cond\>' ) >= 0 && match( line, '\c^(\s*t\>' ) >= 0 " Is this the 't' case for a 'cond' form? - call setpos( '.', oldpos ) + call winrestview( oldpos ) return c endif if match( line2, '\c^(\s*defpackage\>' ) >= 0 @@ -1266,7 +1290,7 @@ function! SlimvIndent( lnum ) let line3 = strpart( getline(l3), c3-1 ) if match( line3, '\c^(\s*\('.s:spec_indent.'\)\>' ) >= 0 " This is the first body-line of a binding - call setpos( '.', oldpos ) + call winrestview( oldpos ) return c + 1 endif if match( line3, '\c^(\s*defsystem\>' ) >= 0 @@ -1284,7 +1308,7 @@ function! SlimvIndent( lnum ) endif endif " Restore all cursor movements - call setpos( '.', oldpos ) + call winrestview( oldpos ) endif " Check if the current form started in the previous nonblank line @@ -1307,7 +1331,13 @@ function! SlimvIndent( lnum ) let func = matchstr( form, '\<\k*\>' ) " If it's a keyword, keep the indentation straight if indent_keylists && strpart(func, 0, 1) == ':' - return c + if form =~ '^:\S*\s\+\S' + " This keyword has an associated value in the same line + return c + else + " The keyword stands alone in its line with no associated value + return c + 1 + endif endif if SlimvGetFiletype() == 'clojure' " Fix clojure specific indentation issues not handled by the default lisp.vim @@ -1315,7 +1345,7 @@ function! SlimvIndent( lnum ) return c + 1 endif else - if match( func, 'defgeneric$' ) >= 0 || match( func, 'aif$' ) >= 0 + if match( func, 'defgeneric$' ) >= 0 || match( func, 'defsystem$' ) >= 0 || match( func, 'aif$' ) >= 0 return c + 1 endif endif @@ -1339,6 +1369,12 @@ function! SlimvIndent( lnum ) set lisp let li = lispindent(a:lnum) set nolisp + let line = strpart( getline(a:lnum-1), li-1 ) + let gap = matchend( line, '^(\s\+\S' ) + if gap >= 0 + " Align to the gap between the opening paren and the first atom + return li + gap - 2 + endif return li endfunction @@ -1488,7 +1524,7 @@ endfunction " Handle normal mode 'Enter' keypress in the SLDB buffer function! SlimvHandleEnterSldb() let line = getline('.') - if s:debug_activated + if s:sldb_level >= 0 " 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\+\)$' ) @@ -1527,7 +1563,7 @@ function! SlimvHandleEnterSldb() if search( '^Restarts:', 'bnW' ) > 0 " Apply item-th restart call SlimvQuitSldb() - silent execute 'python swank_invoke_restart("' . s:debug_activated . '", "' . item . '")' + silent execute 'python swank_invoke_restart("' . s:sldb_level . '", "' . item . '")' return endif endif @@ -1603,7 +1639,7 @@ endfunction " Select a specific restart in debugger function! SlimvDebugCommand( cmd ) if SlimvConnectSwank() - if s:debug_activated + if s:sldb_level >= 0 if bufname('%') != g:slimv_sldb_name call SlimvOpenSldbBuffer() endif @@ -1682,6 +1718,7 @@ function! SlimvArglist() let arg = matchstr( line, '\<\k*\>', c0 ) if arg != '' " Ask function argument list from SWANK + call SlimvFindPackage() let msg = SlimvCommandGetResponse( ':operator-arglist', 'python swank_op_arglist("' . arg . '")', 0 ) if msg != '' " Print argument list in status line with newlines removed. @@ -1707,32 +1744,32 @@ function! SlimvArglist() return '' endfunction -" Start and connect slimv server -" This is a quite dummy function that just evaluates the empty string +" Start and connect swank server function! SlimvConnectServer() - call SlimvBeginUpdate() - 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() - endif if s:swank_connected python swank_disconnect() let s:swank_connected = 0 endif - call SlimvConnectSwank() + call SlimvBeginUpdate() + if SlimvConnectSwank() + 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() + endif + endif endfunction " Get the last region (visual block) function! SlimvGetRegion(first, last) - let oldpos = getpos( '.' ) + let oldpos = winsaveview() if a:first < a:last || ( a:first == line( "'<" ) && a:last == line( "'>" ) ) let lines = getline( a:first, a:last ) else " No range was selected, select current paragraph normal! vap execute "normal! \" - call setpos( '.', oldpos ) + call winrestview( oldpos ) let lines = getline( "'<", "'>" ) if lines == [] || lines == [''] call SlimvError( "No range selected." ) @@ -1750,7 +1787,7 @@ function! SlimvGetRegion(first, last) " Find and set package/namespace definition preceding the region call SlimvFindPackage() - call setpos( '.', oldpos ) + call winrestview( oldpos ) return lines endfunction @@ -1829,12 +1866,12 @@ endfunction " Evaluate and test top level form at the cursor pos function! SlimvEvalTestDefun( testform ) let outreg = v:register - let oldpos = getpos( '.' ) + let oldpos = winsaveview() if !SlimvSelectDefun() return endif call SlimvFindPackage() - call setpos( '.', oldpos ) + call winrestview( oldpos ) call SlimvEvalSelection( outreg, a:testform ) endfunction @@ -1851,7 +1888,7 @@ endfunction " Return frame number if we are in the Backtrace section of the debugger function! s:DebugFrame() - if s:swank_connected && s:debug_activated + if s:swank_connected && s:sldb_level >= 0 " Check if we are in SLDB let repl_buf = bufnr( g:slimv_sldb_name ) if repl_buf != -1 && repl_buf == bufnr( "%" ) @@ -1875,12 +1912,12 @@ endfunction " Evaluate and test current s-expression at the cursor pos function! SlimvEvalTestExp( testform ) let outreg = v:register - let oldpos = getpos( '.' ) + let oldpos = winsaveview() if !SlimvSelectForm() return endif call SlimvFindPackage() - call setpos( '.', oldpos ) + call winrestview( oldpos ) call SlimvEvalSelection( outreg, a:testform ) endfunction @@ -1965,6 +2002,10 @@ endfunction " Switch trace on for the selected function (toggle for swank) function! SlimvTrace() + if SlimvGetFiletype() == 'scheme' + call SlimvError( "Tracing is not supported by swank-scheme." ) + return + endif if SlimvConnectSwank() let s = input( '(Un)trace: ', SlimvSelectSymbol() ) if s != '' @@ -1976,6 +2017,10 @@ endfunction " Switch trace off for the selected function (or all functions for swank) function! SlimvUntrace() + if SlimvGetFiletype() == 'scheme' + call SlimvError( "Tracing is not supported by swank-scheme." ) + return + endif if SlimvConnectSwank() let s:refresh_disabled = 1 call SlimvCommand( 'python swank_untrace_all()' ) @@ -2140,9 +2185,9 @@ endfunction " Compile the current top-level form function! SlimvCompileDefun() - let oldpos = getpos( '.' ) + let oldpos = winsaveview() if !SlimvSelectDefun() - call setpos( '.', oldpos ) + call winrestview( oldpos ) return endif if SlimvConnectSwank() @@ -2234,6 +2279,7 @@ function! SlimvDescribe(arg) if !s:swank_connected return '' endif + call SlimvFindPackage() let arglist = SlimvCommandGetResponse( ':operator-arglist', 'python swank_op_arglist("' . arg . '")', 0 ) if arglist == '' " Not able to fetch arglist, assuming function is not defined @@ -2349,20 +2395,24 @@ function! SlimvLookup( word ) endif if exists( "g:slimv_browser_cmd" ) " We have an given command to start the browser - silent execute '! ' . g:slimv_browser_cmd . ' ' . page . ' &' + if !exists( "g:slimv_browser_cmd_suffix" ) + " Fork the browser by default + let g:slimv_browser_cmd_suffix = '&' + endif + silent execute '! ' . g:slimv_browser_cmd . ' ' . page . ' ' . g:slimv_browser_cmd_suffix else if g:slimv_windows " Run the program associated with the .html extension silent execute '! start ' . page else " On Linux it's not easy to determine the default browser - if executable( 'xdg-open' ) + if executable( 'xdg-open' ) silent execute '! xdg-open ' . page . ' &' - else + else " xdg-open not installed, ask help from Python webbrowser package let pycmd = "import webbrowser; webbrowser.open('" . page . "')" silent execute '! python -c "' . pycmd . '"' - endif + endif endif endif " This is needed especially when using text browsers @@ -2382,6 +2432,7 @@ function! SlimvComplete( base ) return [] endif if s:swank_connected + call SlimvFindPackage() if g:slimv_simple_compl let msg = SlimvCommandGetResponse( ':simple-completions', 'python swank_completions("' . a:base . '")', 0 ) else @@ -2613,5 +2664,7 @@ command! -complete=customlist,SlimvCommandComplete -nargs=* Lisp call SlimvEval( command! -complete=customlist,SlimvCommandComplete -nargs=* Eval call SlimvEval([]) " Switch on syntax highlighting -syntax on +if !exists("g:syntax_on") + syntax on +endif diff --git a/ftplugin/swank.py b/ftplugin/swank.py index 52aadaa..65007b1 100644 --- a/ftplugin/swank.py +++ b/ftplugin/swank.py @@ -4,8 +4,8 @@ # # SWANK client for Slimv # swank.py: SWANK client code for slimv.vim plugin -# Version: 0.9.4 -# Last Change: 17 Jan 2012 +# Version: 0.9.5 +# Last Change: 07 Mar 2012 # Maintainer: Tamas Kovacs # License: This file is placed in the public domain. # No warranty, express or implied. @@ -184,8 +184,18 @@ def unquote(s): if len(s) < 2: return s if s[0] == '"' and s[-1] == '"': - t = s[1:-1].replace('\\"', '"') - return t.replace('\\\\', '\\') + slist = [] + esc = False + for c in s[1:-1]: + if not esc and c == '\\': + esc = True + elif esc and c == 'n': + esc = False + slist.append('\n') + else: + esc = False + slist.append(c) + return "".join(slist) else: return s @@ -440,6 +450,8 @@ def swank_parse_debug(struct): vim.command('call SlimvEndUpdate()') vim.command("call search('^Restarts:', 'w')") vim.command('stopinsert') + # This text will be printed into the REPL buffer + return unquote(condition[0]) + "\n" + unquote(condition[1]) + "\n" def swank_parse_xref(struct): """ @@ -788,7 +800,7 @@ def swank_listen(): elif result == ':abort': debug_active = False - vim.command('let s:debug_activated=0') + vim.command('let s:sldb_level=-1') if len(r[1]) > 1: retval = retval + '; Evaluation aborted on ' + unquote(r[1][1]) + '\n' + prompt + '> ' else: @@ -798,19 +810,19 @@ def swank_listen(): swank_parse_inspect(r[1]) elif message == ':debug': - swank_parse_debug(r) + retval = retval + swank_parse_debug(r) elif message == ':debug-activate': debug_active = True debug_activated = True current_thread = r[1] sldb_level = r[2] - vim.command('let s:debug_activated=' + sldb_level) + vim.command('let s:sldb_level=' + sldb_level) frame_locals.clear() elif message == ':debug-return': debug_active = False - vim.command('let s:debug_activated=0') + vim.command('let s:sldb_level=-1') retval = retval + '; Quit to level ' + r[2] + '\n' + prompt + '> ' elif message == ':ping': @@ -932,15 +944,16 @@ def swank_describe_function(fn): swank_rex(':describe-function', cmd, get_package(), 't') def swank_op_arglist(op): - cmd = '(swank:operator-arglist "' + op + '" "' + package + '")' - swank_rex(':operator-arglist', cmd, get_package(), 't') + pkg = get_swank_package() + cmd = '(swank:operator-arglist "' + op + '" ' + pkg + ')' + swank_rex(':operator-arglist', cmd, pkg, 't') def swank_completions(symbol): - cmd = '(swank:simple-completions "' + symbol + '" "' + package + '")' + cmd = '(swank:simple-completions "' + symbol + '" ' + get_swank_package() + ')' swank_rex(':simple-completions', cmd, 'nil', 't') def swank_fuzzy_completions(symbol): - cmd = '(swank:fuzzy-completions "' + symbol + '" "' + package + '" :limit 200 :time-limit-in-msec 2000)' + cmd = '(swank:fuzzy-completions "' + symbol + '" ' + get_swank_package() + ' :limit 200 :time-limit-in-msec 2000)' swank_rex(':fuzzy-completions', cmd, 'nil', 't') def swank_undefine_function(fn): diff --git a/indent/clojure.vim b/indent/clojure.vim index 0553ad3..3b9e4fe 100644 --- a/indent/clojure.vim +++ b/indent/clojure.vim @@ -1,7 +1,7 @@ " clojure.vim: " Clojure indent plugin for Slimv -" Version: 0.9.2 -" Last Change: 21 Oct 2011 +" Version: 0.9.5 +" Last Change: 21 Feb 2012 " Maintainer: Tamas Kovacs " License: This file is placed in the public domain. " No warranty, express or implied. @@ -10,7 +10,7 @@ " ===================================================================== " " Load Once: -if exists("b:did_indent") +if exists("b:did_indent") || exists("g:slimv_disable_clojure") finish endif diff --git a/indent/lisp.vim b/indent/lisp.vim index 302c656..9723d69 100644 --- a/indent/lisp.vim +++ b/indent/lisp.vim @@ -1,7 +1,7 @@ " lisp.vim: " Lisp indent plugin for Slimv -" Version: 0.9.2 -" Last Change: 21 Oct 2011 +" Version: 0.9.5 +" Last Change: 21 Feb 2012 " Maintainer: Tamas Kovacs " License: This file is placed in the public domain. " No warranty, express or implied. @@ -14,6 +14,15 @@ if exists("b:did_indent") finish endif +" Handle cases when lisp dialects explicitly use the lisp indent plugins +if &ft == "clojure" && exists("g:slimv_disable_clojure") + finish +endif + +if &ft == "scheme" && exists("g:slimv_disable_scheme") + finish +endif + setlocal nolisp setlocal autoindent setlocal expandtab diff --git a/indent/scheme.vim b/indent/scheme.vim new file mode 100644 index 0000000..90be432 --- /dev/null +++ b/indent/scheme.vim @@ -0,0 +1,23 @@ +" scheme.vim: +" Scheme indent plugin for Slimv +" Version: 0.9.5 +" Last Change: 21 Feb 2012 +" Maintainer: Tamas Kovacs +" License: This file is placed in the public domain. +" No warranty, express or implied. +" *** *** Use At-Your-Own-Risk! *** *** +" +" ===================================================================== +" +" Load Once: +if exists("b:did_indent") || exists("g:slimv_disable_scheme") + finish +endif + +let b:did_indent = 1 + +setlocal nolisp +setlocal autoindent +setlocal expandtab +setlocal indentexpr=SlimvIndent(v:lnum) + diff --git a/plugin/paredit.vim b/plugin/paredit.vim index cc8015b..bdf16ce 100644 --- a/plugin/paredit.vim +++ b/plugin/paredit.vim @@ -1,7 +1,7 @@ " paredit.vim: " Paredit mode for Slimv -" Version: 0.9.3 -" Last Change: 30 Nov 2011 +" Version: 0.9.5 +" Last Change: 08 Feb 2012 " Maintainer: Tamas Kovacs " License: This file is placed in the public domain. " No warranty, express or implied. @@ -200,7 +200,7 @@ function! PareditOpfunc( func, type, visualmode ) let ve_save = &virtualedit set virtualedit=all let regname = v:register - let reg_save = @@ + let save_0 = getreg( '0' ) if a:visualmode " Invoked from Visual mode, use '< and '> marks. silent exe "normal! `<" . a:type . "`>" @@ -222,6 +222,10 @@ function! PareditOpfunc( func, type, visualmode ) else silent exe "normal! y" let putreg = getreg( '"' ) + if a:func == 'd' + " Register "0 is corrupted by the above 'y' command + call setreg( '0', save_0 ) + endif " Find and keep unbalanced matched characters in the region let endingwhitespace = matchstr(putreg, "\\s*$") @@ -233,7 +237,7 @@ function! PareditOpfunc( func, type, visualmode ) endif if matched == '' - silent exe "normal! gvx" + silent exe "normal! gvd" else silent exe "normal! gvc" . matched silent exe "normal! l" @@ -245,8 +249,12 @@ function! PareditOpfunc( func, type, visualmode ) let &selection = sel_save let &virtualedit = ve_save - let @@ = reg_save - call setreg( regname, putreg ) + if a:func == 'd' && regname == '"' + " Do not currupt the '"' register and hence the "0 register + call setreg( '1', putreg ) + else + call setreg( regname, putreg ) + endif endfunction " Set delete mode also saving repeat count @@ -266,8 +274,11 @@ endfunction " General change operator handling function! PareditChange( type, ... ) + let ve_save = &virtualedit + set virtualedit=all call PareditOpfunc( 'c', a:type, a:0 ) startinsert + let &virtualedit = ve_save endfunction " Delete v:count number of lines @@ -292,13 +303,20 @@ endfunction " Paste text from put register in a balanced way function! PareditPut( cmd ) - let reg_save = @@ - let putreg = getreg( v:register ) + let regname = v:register + let reg_save = getreg( regname ) + let putreg = reg_save " Find unpaired matched characters by eliminating paired ones let matched = s:GetMatchedChars( putreg, s:InsideString( '.' ), s:InsideComment( '.' ) ) let matched = s:Unbalanced( matched ) + if matched !~ '\S\+' + " Register contents is balanced, perform default put function + silent exe "normal! " . (v:count>1 ? v:count : '') . (regname=='"' ? '' : '"'.regname) . a:cmd + return + endif + " Replace all unpaired matched characters with a space in order to keep balance let i = 0 while i < len( putreg ) @@ -309,13 +327,9 @@ function! PareditPut( cmd ) endwhile " Store balanced text in put register and call the appropriate put command - call setreg( '"', putreg ) - if v:count > 1 - silent exe "normal! " . v:count . a:cmd - else - silent exe "normal! " . a:cmd - endif - let @@ = reg_save + call setreg( regname, putreg ) + silent exe "normal! " . (v:count>1 ? v:count : '') . (regname=='"' ? '' : '"'.regname) . a:cmd + call setreg( regname, reg_save ) endfunction " Toggle paredit mode diff --git a/syntax/clojure/slimv-syntax-clojure.vim b/syntax/clojure/slimv-syntax-clojure.vim index 1f2a19e..fd25182 100644 --- a/syntax/clojure/slimv-syntax-clojure.vim +++ b/syntax/clojure/slimv-syntax-clojure.vim @@ -1,7 +1,7 @@ " slimv-syntax-clojure.vim: " Clojure syntax plugin for Slimv -" Version: 0.9.4 -" Last Change: 26 Dec 2011 +" Version: 0.9.5 +" Last Change: 21 Feb 2012 " Maintainer: Tamas Kovacs " License: This file is placed in the public domain. " No warranty, express or implied. @@ -10,7 +10,7 @@ " ===================================================================== " " Load Once: -if exists("b:current_syntax") +if exists("b:current_syntax") || exists("g:slimv_disable_clojure") finish endif diff --git a/syntax/scheme/slimv-syntax-scheme.vim b/syntax/scheme/slimv-syntax-scheme.vim index 500d2ed..2b8320d 100644 --- a/syntax/scheme/slimv-syntax-scheme.vim +++ b/syntax/scheme/slimv-syntax-scheme.vim @@ -1,7 +1,7 @@ " slimv-syntax-scheme.vim: " Scheme syntax plugin for Slimv -" Version: 0.8.2 -" Last Change: 27 Apr 2011 +" Version: 0.9.5 +" Last Change: 21 Feb 2012 " Maintainer: Tamas Kovacs " License: This file is placed in the public domain. " No warranty, express or implied. @@ -10,7 +10,7 @@ " ===================================================================== " " Load Once: -if exists("b:current_syntax") +if exists("b:current_syntax") || exists("g:slimv_disable_scheme") finish endif