Hello Vim developers,

I've written a user defined completion (via 'completefunc') that uses
     normal y{motion}
to capture the completion matches. (I have some other completions that can use 
getline() to extract the text; in those, the crash doesn't happen.)
If I use a straightforward mapping like
     inoremap ... <C-o>:set completefunc=<SID>MotionComplete<CR><C-x><C-u>
to trigger the completion, everything is working fine. I've now appended some 
<C-r>=pumvisible() ? "\<lt>Down>" : ""<CR> fragment to modify the popup menu 
selection, and now observe Vim crashes whenever I invoke the augmented mapping. 
In fact, any text after the <C-x><C-u> causes buffer corruptions and eventual 
crashes.

I've whittled down my completion script to the attached version. With that, I 
can reproduce crashes on the default (G)VIM 7.1 and 7.2 on Windows XP (but not 
with 7.0, which works fine), and with the latest Vim 7.2.197 (Big version with 
GTK2 GUI) on Ubuntu 8.04.

To reproduce (the completion is mapped to <F11>):
     vim -N -u NONE -n -S CompleteAndTextMappingCrash.vim
     ifoobar<CR>
     foo<F11><CR> " No crash yet, but the '+' char after the mapping is lost
     foo<F11>
     Vim: Caught deadly signal SEGV
     Vim: Finished.
     Segmentation fault

You can check the original, correct behavior with:
     vim -N -u NONE -n --cmd 'let nobug=1' -S CompleteAndTextMappingCrash.vim

Please let me know if you need any additional information.

-- regards, ingo
-- 
   -- Ingo Karkat -- /^-- /^-- /^-- /^-- /^-- /^-- http://ingo-karkat.de/ --
   --      http://vim.sourceforge.net/account/profile.php?user_id=9713    --

--~--~---------~--~----~------------~-------~--~----~
You received this message from the "vim_dev" maillist.
For more information, visit http://www.vim.org/maillist.php
-~----------~----~----~----~------~----~------~--~---

function! s:FindMatchesInCurrentWindow( matches, pattern, matchTemplate, 
options, isInCompletionBuffer )
    let l:isBackward = has_key(a:options, 'backward_search')

    let l:save_cursor = getpos('.')

    let l:firstMatchPos = [0,0]
    while ! complete_check()
        let l:matchPos = searchpos( a:pattern, 'w' . (l:isBackward ? 'b' : '') )
        if l:matchPos == [0,0] || l:matchPos == l:firstMatchPos
            break
        endif
        if l:firstMatchPos == [0,0]
            let l:firstMatchPos = l:matchPos
        endif

        let l:matchEndPos = searchpos( a:pattern, 'cen' )
        if a:isInCompletionBuffer && (l:matchEndPos == l:save_cursor[1:2])
            continue
        endif

        let l:matchObj = copy(a:matchTemplate)
        let l:matchText = a:options.extractor(l:matchPos, l:matchEndPos, 
l:matchObj)

        let l:matchObj.word = l:matchText

        if ! empty(l:matchText) && index(a:matches, l:matchObj) == -1
            call add( a:matches, l:matchObj )
        endif
    endwhile
    
    call setpos('.', l:save_cursor)
endfunction

function! MotionComplete_ExtractText( startPos, endPos, matchObj )
    let l:save_cursor = getpos('.')
    let @@ = ''
    call setpos('.', [0, a:startPos[0], a:startPos[1], 0])
    execute 'silent! normal y' . s:motion
    let l:text = @@
    call setpos('.', l:save_cursor)
    return l:text
endfunction

function! s:LocateStartCol()
    let l:startCol = searchpos('\k\+\%(\...@!.\)*\%#', 'bn', line('.'))[1]
    if l:startCol == 0
        let l:startCol = col('.')
    endif
    return l:startCol
endfunction 

function! s:MotionComplete( findstart, base )
    if a:findstart
        return s:LocateStartCol() - 1 " Return byte index, not column. 
    else
        let l:options = {}
        let l:options.extractor = function('MotionComplete_ExtractText')
        let l:matches = []
        call s:FindMatchesInCurrentWindow( l:matches, '\V\<' . escape(a:base, 
'\'), {}, l:options, 1 )
        return l:matches
    endif
endfunction

let s:motion = 'w'

inoremap <silent> <Plug>MotionComplete <C-o>:set 
completefunc=<SID>MotionComplete<CR><C-x><C-u>

" The original mapping that caused the crash. 
" In combination with an expression to select the first match in the popup menu
" (this is useful in combination with :set completeopt=menu,longest), Vim
" crashes. 
"imap <F11> <Plug>MotionComplete<C-r>=pumvisible() ? "\<lt>Down>" : ""<CR>

" A simplified mapping that still causes the crash. 
imap <F11> <Plug>MotionComplete+Some-More-Text

" The bare mapping works fine. 
if exists('nobug')
    imap <F11> <Plug>MotionComplete
endif

Raspunde prin e-mail lui