Commits

Tamas Kovacs committed 547cda3

Search for text in REPL command history.
Multi-line commands are recalled in whole, not line-by-line.

Comments (0)

Files changed (2)

-*slimv.txt*                    Slimv                 Last Change: 02 Apr 2013
+*slimv.txt*                    Slimv                 Last Change: 21 Apr 2013
 
 Slimv                                                                  *slimv*
-                               Version 0.9.10
+                               Version 0.9.11
 
 The Superior Lisp Interaction Mode for Vim.
 This plugin is aimed to help Lisp development by interfacing between Vim and
 will be evaluated at the end of the REPL buffer.
 
 Another difference is the command line history, which can be activated by
-pressing <Up> or <Down> in the command line (also only in Insert mode).
+pressing <Up> or <Down> in the command line (only in Insert mode).
+When pressing <Up> or <Down> at an empty command prompt then each forms
+previously entered may be recalled from the history. If however some text
+is typed in the command line before pressing <Up> or <Down> then only forms
+beginning with the given searchtext are recalled from the history.
+In other words: text between the prompt and the cursor position is searched
+in command history. Leading whitespaces are ignored both in the searchtext
+and in the matching forms.
+
 Outside of the command line the <Up> and <Down> keys move the cursor,
 as usual.
 
 ===============================================================================
 CHANGE LOG                                                    *slimv-changelog*
 
+0.9.11 - Entering some text in REPL command history, then pressing <Up>/<Down>
+         searches for matching lines only.
+
 0.9.10 - Replaced 'readonly' flag with 'nomodifiable' for SLDB, Inspect,
          Threads buffers.
        - Restore window and buffer if SLDB is activated during completion.

ftplugin/slimv.vim

 
     if g:slimv_repl_simple_eval
         inoremap <buffer> <silent>        <CR>     <C-R>=pumvisible() ? "\<lt>CR>" : "\<lt>End>\<lt>C-O>:call SlimvSendCommand(0)\<lt>CR>"<CR>
-        inoremap <buffer> <silent>        <Up>     <C-R>=pumvisible() ? "\<lt>Up>" : "\<lt>C-O>:call SlimvHandleUp()\<lt>CR>"<CR>
-        inoremap <buffer> <silent>        <Down>   <C-R>=pumvisible() ? "\<lt>Down>" : "\<lt>C-O>:call SlimvHandleDown()\<lt>CR>"<CR>
+        inoremap <buffer> <silent>        <Up>     <C-R>=pumvisible() ? "\<lt>Up>"   : SlimvHandleUp()<CR>
+        inoremap <buffer> <silent>        <Down>   <C-R>=pumvisible() ? "\<lt>Down>" : SlimvHandleDown()<CR>
     else
         inoremap <buffer> <silent>        <CR>     <C-R>=pumvisible() ? "\<lt>CR>" : SlimvHandleEnterRepl()<CR><C-R>=SlimvArglistOnEnter()<CR>
-        inoremap <buffer> <silent>        <C-Up>   <C-R>=pumvisible() ? "\<lt>Up>" : "\<lt>C-O>:call SlimvHandleUp()\<lt>CR>"<CR>
-        inoremap <buffer> <silent>        <C-Down> <C-R>=pumvisible() ? "\<lt>Down>" : "\<lt>C-O>:call SlimvHandleDown()\<lt>CR>"<CR>
+        inoremap <buffer> <silent>        <C-Up>   <C-R>=pumvisible() ? "\<lt>Up>"   : SlimvHandleUp()<CR>
+        inoremap <buffer> <silent>        <C-Down> <C-R>=pumvisible() ? "\<lt>Down>" : SlimvHandleDown()<CR>
     endif
 
     if exists( 'g:paredit_loaded' )
     if len( line ) > promptlen
         let line = strpart( line, 0, promptlen )
     endif
-    let line = line . a:cmd
+
+    if s:GetPromptLine() < line( '$' )
+        " Delete extra lines after the prompt
+        let c = col( '.' )
+        execute (s:GetPromptLine()+1) . ',' . (line('$')) . 'd_'
+        call cursor( line('.'), c )
+    endif
+
+    let lines = split( a:cmd, '\n' )
+    if len(lines) > 0
+        let line = line . lines[0]
+    endif
     call setline( ".", line )
-    call SlimvEndOfReplBuffer()
+    if len(lines) > 1
+        call append( s:GetPromptLine(), lines[1:] )
+    endif
     set nomodified
 endfunction
 
         let g:slimv_cmdhistory = []
     endif
     let i = 0
-    while i < len( a:cmd )
-        " Trim trailing whitespaces from the command
-        let command = substitute( a:cmd[i], "\\(.*[^ ]\\)\\s*", "\\1", "g" )
-        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 form = join( a:cmd, "\n" )
+    " Trim leading and trailing whitespaces from the command
+    let form = substitute( form, '^\s*\(.*[^ ]\)\s*', '\1', 'g' )
+    if len( form ) > 1 || len( g:slimv_cmdhistory ) == 0 || form != g:slimv_cmdhistory[-1]
+        " Add command only if differs from the last one
+        call add( g:slimv_cmdhistory, form )
+    endif
     let g:slimv_cmdhistorypos = len( g:slimv_cmdhistory )
 endfunction
 
 " Recall command from the command history at the marked position
-function! SlimvRecallHistory()
-    if g:slimv_cmdhistorypos >= 0 && g:slimv_cmdhistorypos < len( g:slimv_cmdhistory )
-        call SlimvSetCommandLine( g:slimv_cmdhistory[g:slimv_cmdhistorypos] )
+function! SlimvRecallHistory( direction )
+    let searchtext = ''
+    let l = line( '.' )
+    let c = col( '.' )
+    let set_cursor_pos = 0
+    if line( '.' ) == s:GetPromptLine() && c > b:repl_prompt_col
+        " Search for lines beginning with the text up to the cursor position
+        let searchtext = strpart( getline('.'), b:repl_prompt_col-1, c-b:repl_prompt_col )
+        let searchtext = substitute( searchtext, '^\s*\(.*[^ ]\)', '\1', 'g' )
+    endif
+    let historypos = g:slimv_cmdhistorypos
+    let g:slimv_cmdhistorypos = g:slimv_cmdhistorypos + a:direction
+    while g:slimv_cmdhistorypos >= 0 && g:slimv_cmdhistorypos < len( g:slimv_cmdhistory )
+        let cmd = g:slimv_cmdhistory[g:slimv_cmdhistorypos]
+        if len(cmd) >= len(searchtext) && strpart(cmd, 0, len(searchtext)) == searchtext
+            call SlimvSetCommandLine( g:slimv_cmdhistory[g:slimv_cmdhistorypos] )
+            return
+        endif
+        let g:slimv_cmdhistorypos = g:slimv_cmdhistorypos + a:direction
+    endwhile
+    if searchtext == ''
+        call SlimvSetCommandLine( "" )
     else
-        call SlimvSetCommandLine( "" )
+        let g:slimv_cmdhistorypos = historypos
     endif
 endfunction
 
 " Recall previous command from command history
 function! s:PreviousCommand()
     if exists( 'g:slimv_cmdhistory' ) && g:slimv_cmdhistorypos > 0
-        let g:slimv_cmdhistorypos = g:slimv_cmdhistorypos - 1
-        call SlimvRecallHistory()
+        call SlimvRecallHistory( -1 )
     endif
 endfunction
 
 " Recall next command from command history
 function! s:NextCommand()
     if exists( 'g:slimv_cmdhistory' ) && g:slimv_cmdhistorypos < len( g:slimv_cmdhistory )
-        let g:slimv_cmdhistorypos = g:slimv_cmdhistorypos + 1
-        call SlimvRecallHistory()
+        call SlimvRecallHistory( 1 )
     else
         call SlimvSetCommandLine( "" )
     endif
 
 " Handle insert mode 'Up' keypress in the REPL buffer
 function! SlimvHandleUp()
+    let save_ve = &virtualedit
+    set virtualedit=onemore
     if line( "." ) >= s:GetPromptLine()
-        if exists( 'g:slimv_cmdhistory' ) && g:slimv_cmdhistorypos == len( g:slimv_cmdhistory )
-            call SlimvMarkBufferEnd()
-            startinsert!
-        endif
         call s:PreviousCommand()
     else
         normal! gk
     endif
+    let &virtualedit=save_ve
+    return ''
 endfunction
 
 " Handle insert mode 'Down' keypress in the REPL buffer
 function! SlimvHandleDown()
+    let save_ve = &virtualedit
+    set virtualedit=onemore
     if line( "." ) >= s:GetPromptLine()
         call s:NextCommand()
     else
         normal! gj
     endif
+    let &virtualedit=save_ve
+    return ''
 endfunction
 
 " Make a fold at the cursor point in the current buffer
 
 " Go to command line and recall previous command from command history
 function! SlimvPreviousCommand()
+    let save_ve = &virtualedit
+    set virtualedit=onemore
     call SlimvEndOfReplBuffer()
     if line( "." ) >= s:GetPromptLine()
         call s:PreviousCommand()
     endif
+    let &virtualedit=save_ve
 endfunction
 
 " Go to command line and recall next command from command history
 function! SlimvNextCommand()
+    let save_ve = &virtualedit
+    set virtualedit=onemore
     call SlimvEndOfReplBuffer()
     if line( "." ) >= s:GetPromptLine()
         call s:NextCommand()
     endif
+    let &virtualedit=save_ve
 endfunction
 
 " Handle interrupt (Ctrl-C) keypress in the REPL buffer