Shougo / neocomplete.vim

Next generation completion framework after neocomplcache
2.74k stars 203 forks source link

Error with neocomplete due to hack to remember position before undo #552

Closed lervag closed 8 years ago

lervag commented 8 years ago

Problems summary

I've implemented a formatexpr for vimtex. Unfortunately, such a function requires a hack in order for undo to restore the previous cursor position, see here.

However, it seems that such a hack does not work well with neocomplete. This was first discovered here.

Note: I am aware of the possibility to use NeoCompleteLock, but that adds a very noticable lag.

Steps to reproduce

USe the below vimrc file, then do:

  1. Open vim with vim -Nu minivimrc
  2. Do gqip

The following error message appears:

Error detected while processing function <SNR>50_complete_delay[3]..<SNR>50_do_a
uto_complete[12]..neocomplete#context_filetype#set:
line    2:
E117: Unknown function: context_filetype#get_filetype
E15: Invalid expression: s:exists_context_filetype ? context_filetype#get_filety
pe() : &filetype

Minimal vimrc file

let &rtp  = '~/.vim/bundle/neocomplete,' . &rtp
filetype plugin on

let g:neocomplete#enable_at_startup = 1

set formatexpr=Format()

function! Format()
  let l:top = v:lnum
  let l:bottom = v:lnum + v:count - 1

  if mode() !=# 'i'
    normal! ix
    normal! x
  endif

  execute 'normal!' l:top . 'Ggw' . l:bottom . 'G'
endfunction

System information

I'm on Arch Linux and use Vim version 7.4.1910.

Shougo commented 8 years ago

@lervag Your runtimepath seems broken. Because, cannot load context_filetype#get_filetype() from your error messages. neocomplete checks if context_filetype exists and load it.

let &rtp  = '~/.vim/bundle/neocomplete,' . &rtp

This is not minimal vimrc. Because, it does not load context_filetype plugin. But it loads context_filetype plugin from your error messages. Please upload the correct minimal vimrc.

I think....

  1. neocomplete want to load context_filetype plugin.
  2. context_filetype plugin is broken or your runtimepath is broken.
  3. This error.
Shougo commented 8 years ago

I cannot reproduce your error. Did you test it with minimal vimrc?

Shougo commented 8 years ago

You can read the context_filetype check implementation. It is not complex and it seems not related your changes.

https://github.com/Shougo/neocomplete.vim/blob/master/autoload/neocomplete/context_filetype.vim

lervag commented 8 years ago

I don't understand why the supplied minmal vimrc file is not a minimal vimrc file. How would you suggest a minimal vimrc file for testing neocomplete should look? Considering this, I can't understand what about the supplied example is wrong.

let &rtp  = '~/.vim/bundle/neocomplete,' . &rtp
filetype plugin on

let g:neocomplete#enable_at_startup = 1

set formatexpr=Format()

function! Format()
  let l:top = v:lnum
  let l:bottom = v:lnum + v:count - 1

  if mode() !=# 'i'
    normal! ix
    normal! x
  endif

  execute 'normal!' l:top . 'Ggw' . l:bottom . 'G'
endfunction

The only thing I see that could be different from what you suggest is that I could use set runtimepath+=~/.vim/bundle/neocomplete, but that shouldn't make a difference.

Shougo commented 8 years ago

@lervag I have tested it. But I don't reproduce the error. I don't think it is neocomplete bug. So, I cannot support it.

You can read the context_filetype check implementation. It is not complex and it seems not related your changes. https://github.com/Shougo/neocomplete.vim/blob/master/autoload/neocomplete/context_filetype.vim

Please do it.

Shougo commented 8 years ago

@lervag I don't think your minimal .vimrc is wrong. But I cannot reproduce it(context_filetype error). I think you have missed the reproduce way. If you can reproduce the problem with your minimal vimrc, please tell me another reproduce-able person.

Shougo commented 8 years ago

This is my minimal vimrc.

set nocompatible
set runtimepath+=~/work/neocomplete.vim/

let g:neocomplete#enable_at_startup = 1

set formatexpr=Format()

function! Format()
  let l:top = v:lnum
  let l:bottom = v:lnum + v:count - 1

  if mode() !=# 'i'
    normal! ix
    normal! x
  endif

  execute 'normal!' l:top . 'Ggw' . l:bottom . 'G'
endfunction

Please tell me if I am wrong.

lervag commented 8 years ago

Ok, I'll investigate this further and let you know. Perhaps I've been to quick. I'll also check against a more recent version of Vim; which version are you one? And I'll look into the context_filetype script.

Shougo commented 8 years ago

Vim 7.4.2198

lervag commented 8 years ago

I've looked at neocomplete/context_filetype.vim. It seems, for some reason, that the initial try/catch block does not work as it should. context_filetype#version() does not exist on my end, and so the catch block should be reached. However, for some reason, the block returns s:exists_context_filetype = 1, which in part explains the issue.

By the way: To reproduce the issue, you need to do gqip as the first action after opening with vim -u minivimrc. At the moment, my Vim version is 7.4.2143; I'll compile and test the most recent version to see if this might be a bug in Vim that has been fixed.

lervag commented 8 years ago

If I load the neocomplete/context_filetype.vim file manually, it works. This only happens when it is loaded implicitly from neocomplete.

lervag commented 8 years ago

I can reproduce the problem with latest Vim compiled from source (with huge features and --enable-luainterp).

lervag commented 8 years ago

I'm curious, can one not use exists('*context_filetype#version') to test? I guess this will not work if the context_filetype plugin has not been loaded already, but perhaps this will always be the case anyway?

lervag commented 8 years ago

Ok, I found a workaround that works for me:

" context_filetype.vim installation check.
if !exists('s:exists_context_filetype')
  try
    call context_filetype#version()
  catch
  endtry
  let s:exists_context_filetype = exists('*context_filetype#version')
endif

Here the try/catch block only ensures that the context_filetype plugin is loaded if it exists. Then we check if the function(s) are available afterwords. With this change, my issue is solved.

However, it is a little bit unsatisfying not to understand why the issue occurs in the first place. I hope that you might try again to reproduce it. As I said, with my minimal vimrc file, you simply load an empty buffer vim -u vimrc, then do gqip. Please, though, ensure that you do not have the context_filetype plugin actually available, e.g. in your .vim/autoload directory. If you do, then of course this will not be reproducible.

Shougo commented 8 years ago

Thanks. Fixed.

lervag commented 8 years ago

Great, thanks!