Tamas Kovacs avatar Tamas Kovacs committed d2b2ba5

Version 0.7.4

Added autodetection for simple 'clojure' command on Linux, removed duplicates from history of commands entered in REPL buffer (those recallable with <Up>), bugfixes: infinite loop during eval when 'in-package' or 'in-ns' was in comment, Lisp prompt identification problems in REPL buffer, input line duplication in SBCL on Linux (assigned "*debug-io*" to stdin), Eval Defun sometimes missed last ")".

Comments (0)

Files changed (4)

-*slimv.txt*                    Slimv                 Last Change: 05 Dec 2010
+*slimv.txt*                    Slimv                 Last Change: 14 Dec 2010
 
 Slimv                                                                  *slimv*
-                               Version 0.7.3
+                               Version 0.7.4
 
 The Superior Lisp Interaction Mode for Vim.
 This plugin is aimed to help Lisp development by interfacing between Vim and
 ===============================================================================
 CHANGE LOG                                                    *slimv-changelog*
 
+0.7.4  - Added autodetection for simple 'clojure' command on Linux.
+       - Removed duplicates from history of commands entered in REPL buffer
+         (those recallable with <Up> and <Down>).
+       - Bugfix: infinite loop during eval when 'in-package' or 'in-ns'
+         was in comment.
+       - Bugfix: Lisp prompt identification problems in REPL buffer.
+       - Bugfix: input line duplication in SBCL on Linux
+         (assigned "*debug-io*" to stdin).
+       - Bugfix: Eval Defun missed last ")" if form contained "'('".
+
 0.7.3  - Added compatibility with Python 3.x.
        - Bugfix: input lines for REPL were doubled on Linux (thanks to
          Andrew Hills), however not yet fixed for SBCL.

ftplugin/clojure/slimv-clojure.vim

 " slimv-clojure.vim:
 "               Clojure filetype plugin for Slimv
-" Version:      0.7.2
-" Last Change:  14 Nov 2010
+" Version:      0.7.4
+" Last Change:  13 Dec 2010
 " Maintainer:   Tamas Kovacs <kovisoft at gmail dot com>
 " License:      This file is placed in the public domain.
 "               No warranty, express or implied.
 " Returns list [Clojure executable, Clojure implementation]
 function! b:SlimvAutodetect()
     " Firts try the most basic setup: everything in the path
+    if executable( 'clojure' )
+        return ['clojure', 'clojure']
+    endif
     let lisps = []
     if executable( 'clojure.jar' )
         let lisps = ['clojure.jar']

ftplugin/slimv.py

 #
 # Client/Server code for Slimv
 # slimv.py:     Client/Server code for slimv.vim plugin
-# Version:      0.7.3
-# Last Change:  04 Dec 2010
+# Version:      0.7.4
+# Last Change:  06 Dec 2010
 # Maintainer:   Tamas Kovacs <kovisoft at gmail dot com>
 # License:      This file is placed in the public domain.
 #               No warranty, express or implied.
 mswindows = (sys.platform == 'win32')
 darwin = (sys.platform == 'darwin')
 
-if not (mswindows or darwin):
-    import pty
-
 def log( s, level ):
     """Print diagnostic messages according to the actual debug level.
     """
     cmd = shlex.split( lisp_exp )
 
     # Start Lisp
-    if mswindows or darwin or lisp_path.lower().find( 'sbcl' ) < 0:
-        repl = Popen( cmd, stdin=PIPE, stdout=PIPE, stderr=STDOUT )
-        repl_stdin = repl.stdin
-        repl_stdout = repl.stdout
-        repl_pid = repl.pid
-    else:
-        # Special handling for SBCL on Linux
-        repl_pid, repl_fd = pty.fork()
-        if repl_pid == 0:
-            os.execvp( cmd[0], cmd )
-            os._exit(1)
-        repl_stdin = repl_stdout = os.fdopen( repl_fd )
+    repl = Popen( cmd, stdin=PIPE, stdout=PIPE, stderr=STDOUT )
 
     buffer = repl_buffer( sys.stdout )
 
     # Create and start helper threads
-    sl = socket_listener( repl_stdin, buffer, repl_pid )
+    sl = socket_listener( repl.stdin, buffer, repl.pid )
     sl.start()
-    ol = output_listener( repl_stdout, buffer )
+    ol = output_listener( repl.stdout, buffer )
     ol.start()
 
     # Allow Lisp to start, confuse it with some fancy Slimv messages
     sys.stdout.write( ";;; Slimv server is started on port " + str(PORT) )
     sys.stdout.write( "\n;;; Slimv is spawning REPL...\n\n" )
+
+    # SBCL on Linux takes input from *debug-io* when in the debugger
+    # let't tie this to the standard input
+    if not mswindows and not darwin and lisp_path.lower().find( 'sbcl' ) >= 0:
+        text = "(setf *debug-io* (make-two-way-stream *standard-input* *standard-output*))\n"
+        os.write( repl.stdin.fileno(), str2stream( text ) )
+        buffer.write( text, True )
+
     time.sleep(0.5)             # wait for Lisp to start
 
     # Main server loop
                 text = raw_input()
             else:
                 text = input()
-            os.write( repl_stdin.fileno(), str2stream( text + "\n" ) )
+            os.write( repl.stdin.fileno(), str2stream( text + "\n" ) )
             buffer.write( text + "\n", True )
         except EOFError:
             # EOF (Ctrl+Z on Windows, Ctrl+D on Linux) pressed?
     # Send exit command to child process and
     # wake output listener up at the same time
     try:
-        repl_stdin.close()
+        repl.stdin.close()
     except:
         # We don't care if this above fails, we'll exit anyway
         pass

ftplugin/slimv.vim

 " slimv.vim:    The Superior Lisp Interaction Mode for VIM
-" Version:      0.7.3
-" Last Change:  27 Nov 2010
+" Version:      0.7.4
+" Last Change:  14 Dec 2010
 " Maintainer:   Tamas Kovacs <kovisoft at gmail dot com>
 " License:      This file is placed in the public domain.
 "               No warranty, express or implied.
 
 " Position the cursor at the end of the REPL buffer
 " Optionally mark this position in Vim mark 's'
-function! SlimvEndOfReplBuffer( markpos, insert )
+function! SlimvEndOfReplBuffer()
     if !g:slimv_repl_open
         " User does not want to display REPL in Vim
         return
     endif
     normal! G$
-    if a:markpos
-        " Remember the end of the buffer: user may enter commands here
-        " Also remember the prompt, because the user may overwrite it
-        call setpos( "'s", [0, line('$'), col('$'), 0] )
-        let s:prompt = getline( "'s" )
-        if a:insert
-            " We are in insert mode, so we end up appending to the last line
-            startinsert!
-        endif
-    endif
-    set nomodified
+endfunction
+
+" Remember the end of the REPL buffer: user may enter commands here
+" Also remember the prompt, because the user may overwrite it
+function! SlimvMarkBufferEnd()
+    call setpos( "'s", [0, line('$'), col('$'), 0] )
+    let s:prompt = getline( "'s" )
 endfunction
 
 " Reload the contents of the REPL buffer from the output file if changed
         endif
         return
     endif
-    let s:last_size = size
     let this_buf = bufnr( "%" )
     if repl_buf != this_buf
         " Switch to the REPL buffer/window
     if g:slimv_updatetime > 0
         let &updatetime = g:slimv_updatetime
     endif
-    let s:last_update = localtime()
 
     try
         execute "silent view! " . s:repl_name
+        let s:last_size = size
+        let s:last_update = localtime()
     catch /.*/
         " Oops, something went wrong, the buffer will not be refreshed this time
     endtry
     syntax on
     setlocal autoread
-    let insert = 0
-    if mode() == 'i' || mode() == 'I'
-        let insert = 1
-    endif
-    call SlimvEndOfReplBuffer( 0, insert )
+    call SlimvEndOfReplBuffer()
+    set nomodified
 
     if repl_buf != this_buf
         " Switch back to the caller buffer/window
     execute "au! CursorHold"
     execute "au! CursorHoldI"
     set noreadonly
-
-    " Remember the end of the buffer and the actual prompt
-    call setpos( "'s", [0, line('$'), col('$'), 0] )
-    let s:prompt = getline( "'s" )
 endfunction
 
 " Called when entering REPL buffer
     call SlimvAddReplMenu()
     execute "au FileChangedRO " . g:slimv_repl_file . " :call SlimvRefreshModeOff()"
     call SlimvRefreshModeOn()
-    call SlimvEndOfReplBuffer( 1, 0 )
+    call SlimvRefreshReplBuffer()
+    call SlimvMarkBufferEnd()
 endfunction
 
 " Called when leaving REPL buffer
         " REPL menu not found, we cannot remove it
     endtry
     call SlimvRefreshModeOn()
-    call SlimvEndOfReplBuffer( 1, 0 )
+    call SlimvRefreshReplBuffer()
+    call SlimvMarkBufferEnd()
 endfunction
 
 " Open a new REPL buffer or switch to the existing one
 function! SlimvOpenReplBuffer()
-    "TODO: check if this works without 'set hidden'
     let repl_buf = bufnr( s:repl_name )
     if repl_buf == -1
         " Create a new REPL buffer
 " Select bottom level form the cursor is inside and copy it to register 's'
 function! SlimvSelectForm()
     " Search the opening '(' if we are standing on a special form prefix character
+    let save_cpo = &cpoptions
     let c = col( '.' ) - 1
     while match( "'`#", getline( '.' )[c] ) >= 0
         normal! l
         let c = c + 1
     endwhile
+    set cpoptions+=%    " Needed for correct () handling
     normal! va(o
     " Handle '() or #'() etc. type special syntax forms
     let c = col( '.' ) - 2
         let c = c - 1
     endwhile
     normal! "sy
+    let &cpoptions = save_cpo
 endfunction
 
 " Select top level form the cursor is inside and copy it to register 's'
 function! SlimvFindAddSel( string )
     normal ms
     let found = 0
-    while search( '(\s*' . a:string . '\s', 'bcW' )
+    let searching = search( '(\s*' . a:string . '\s', 'bcW' )
+    while searching
         " Search for the previos occurrence
         if synIDattr( synID( line('.'), col('.'), 0), 'name' ) !~ '[Ss]tring\|[Cc]omment'
             " It is not inside a comment or string
             let found = 1
             break
         endif
+        let searching = search( '(\s*' . a:string . '\s', 'bW' )
     endwhile
     if found
         " Put the form just found at the beginning of the selection
         let sel = SlimvGetSelection()
         normal! v%"sy
         call setreg( '"s', SlimvGetSelection() . "\n" . sel )
-        normal `s
     endif
+    normal `s
 endfunction
 
 " Find and add language specific package/namespace definition before the
     endif
     let line = line . a:cmd
     call setline( ".", line )
-    call SlimvEndOfReplBuffer( 0, 0 )
+    call SlimvEndOfReplBuffer()
+    set nomodified
 endfunction
 
 " Add command list to the command history
     while i < len( a:cmd )
         " Trim trailing whitespaces from the command
         let command = substitute( a:cmd[i], "\\(.*[^ ]\\)\\s*", "\\1", "g" )
-        call add( g:slimv_cmdhistory, command )
+        if len( a:cmd ) > 1 || len( g:slimv_cmdhistory ) == 0 || command != g:slimv_cmdhistory[-1]
+            " Add command only if differs from the last one
+            call add( g:slimv_cmdhistory, command )
+        endif
         let i = i + 1
     endwhile
     let g:slimv_cmdhistorypos = len( g:slimv_cmdhistory )
                     let i = i - 1
                 endwhile
                 call setline( ".", indent )
-                call SlimvEndOfReplBuffer( 0, 0 )
+                call SlimvEndOfReplBuffer()
             endif
         endif
     else
         call append( '$', "Slimv error: previous EOF mark not found, re-enter last form:" )
         call append( '$', "" )
-        call SlimvEndOfReplBuffer( 1, 0 )
+        call SlimvEndOfReplBuffer()
+        call SlimvMarkBufferEnd()
+        set nomodified
     endif
 endfunction
 
 " Handle insert mode 'Up' keypress in the REPL buffer
 function! SlimvHandleUp()
     if line( "." ) >= line( "'s" )
+        if exists( 'g:slimv_cmdhistory' ) && g:slimv_cmdhistorypos == len( g:slimv_cmdhistory )
+            call SlimvRefresh()
+            call SlimvEndOfReplBuffer()
+            call SlimvMarkBufferEnd()
+            startinsert!
+        endif
         call s:PreviousCommand()
     else
         normal! gk
 
 " Go to command line and recall previous command from command history
 function! SlimvPreviousCommand()
-    call SlimvEndOfReplBuffer( 0, 0 )
+    call SlimvEndOfReplBuffer()
     if line( "." ) >= line( "'s" )
         call s:PreviousCommand()
     endif
 
 " Go to command line and recall next command from command history
 function! SlimvNextCommand()
-    call SlimvEndOfReplBuffer( 0, 0 )
+    call SlimvEndOfReplBuffer()
     if line( "." ) >= line( "'s" )
         call s:NextCommand()
     endif
     else
         try
             execute "silent view! " . s:repl_name
+            let s:last_size = getfsize( s:repl_name )
+            let s:last_update = localtime()
         catch /.*/
             " Oops, something went wrong, the buffer will not be refreshed this time
         endtry
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.