ycm-core / YouCompleteMe

A code-completion engine for Vim
http://ycm-core.github.io/YouCompleteMe/
GNU General Public License v3.0
25.48k stars 2.81k forks source link

Need a way to temporarily halt autocompletion #1731

Closed krafczyk closed 2 years ago

krafczyk commented 9 years ago

I've been finding lately, that when I have a command to format a bunch of lines of code, and that code involves a class of some sort, YouCompleteMe will attempt to recompile and present a list of suggestions after getting to the end of a pointer or what-have-you.

Unfortuantely, this greatly slows down vim.

We need a way to temporarily disable the autocompletion features while a large command block executes.

(for instance I'm often doing 200@z or something like it, and it takes a while with all the recompiles and suggestion boxes popping up.)

I looked, but didn't see anything which would help me in the documents.

micbou commented 9 years ago

You just need to type

:let g:ycm_auto_trigger = 0

before the command and

:let g:ycm_auto_trigger = 1

after.

krafczyk commented 9 years ago

No, that just disables the completion suggestions.

The file is still compiled after every insert command as part of my command block, which seems to account for the majority of the time the command is executing.

mispencer commented 9 years ago

Try using the noautocmd command

vheon commented 9 years ago

you should use call youcompleteme#DisableCursorMovedAutocommand() and call youcompleteme#EnableCursorMovedAutocommand()

krafczyk commented 9 years ago

trying noautocmd doesn't work. I'm still getting updated error messages (compiler messages in the gutter) when my code passes through intermediate states.

When calling call youcompleteme#DisableCursorMovedAutocommand() I get: E117: Unknown function: youcompleteme#DisableCursorMovedAutocommand

krafczyk commented 9 years ago

On second glance, it seems the vim help claims that noautocmd is to be used with : style commands. When I do :noautocmd @a I get the following:

E492: Not an editor command: bye0v$hdi^Iptree->Branch("

Which of course is the content of my register.

micbou commented 9 years ago

This is kind of a hack but the command

:let b:ycm_largefile

should do the job. Use

:unlet b:ycm_largefile`

to revert it. I am confident this will work this time (or not?) because I tested it on an example.

When calling call youcompleteme#DisableCursorMovedAutocommand() I get: E117: Unknown function: youcompleteme#DisableCursorMovedAutocommand

A s at the end of the command is missing. You should be able to autocomplete those kind of commands.

vheon commented 9 years ago

A s at the end of the command is missing. You should be able to autocomplete those kind of commands.

Yeah, sorry. For me using those functions is the way to go. We put those there for compatibility with other plugins which would suffer for try to complete on every key stroke, so I think is appropriate.

krafczyk commented 9 years ago

Okay, we're closer, but not there yet.

with call youcompleteme#DisableCursorMovedAutocommands(),

It's not presenting the popup suggestions, however, it's still compiling and updating the warnings and errors whenever I go between insert and normal mode as part of the command in my register.

It's slightly faster though I think.

When I try :let b:ycm_largefile, I get the error: E121: Undefined variable: b:ycm_largefile

Suspecting that it should be g:ycm_largefile, I still get: E121: Undefined variable: g:ycm_largefile

micbou commented 9 years ago

My mistake. You need to set a value to the variable:

:let b:ycm_largefile = 1
krafczyk commented 9 years ago

Yes! I believe that's done it!

How do I go back? I tried let b:ycm_largefile = 0 but, it doesn't seem to be providing suggestions anymore.

micbou commented 9 years ago

You need to undefine the variable, that is:

:unlet b:ycm_largefile
krafczyk commented 9 years ago

Excellent. This does exactly what I want.

Thanks very much for your help everyone!

It would be good if this was mentioned somewhere in the Readme.

vheon commented 9 years ago

It would be good if this was mentioned somewhere in the Readme.

What you're doing is just a hack using is an internal detail and not part of a public API, so mention it in the README is not a good idea, since we could change how we manage large files and that will not longer work as you expect. What seems strange to me is that even after call youcompleteme#DisableCursorMovedAutocommands() you still have problems :S

krafczyk commented 9 years ago

Then perhaps I should reopen this issue and a more permanent solution should be developed.

On Wed, Oct 14, 2015 at 6:47 PM, Andrea Cedraro notifications@github.com wrote:

It would be good if this was mentioned somewhere in the Readme.

What you're doing is just a hack using is an internal detail and not part of a public API, so mention it in the README is not a good idea, since we could change how we manage large files and that will not longer work as you expect.

— Reply to this email directly or view it on GitHub https://github.com/Valloric/YouCompleteMe/issues/1731#issuecomment-148113200 .

micbou commented 9 years ago

What seems strange to me is that even after call youcompleteme#DisableCursorMovedAutocommands() you still have problems :S

This is because youcompleteme#DisableCursorMovedAutocommands() disables the youcompletemecursormove autocommands group but not the youcompleteme one. The function that takes time is s:OnInsertLeave and is part of the youcompleteme group (InsertLeave autocommand).

vheon commented 9 years ago

If we want to support halting YCM, I think that all we need to do is return 0 form s:AllowedToCompleteInCurrentFile, right?

so all we need is:

let s:halt_ycm = 0
function! youcompleteme#Halt()
  call youcompleteme#DisableCursorMovedAutocommands()
  let s:halt_ycm = 1
endfunction

function! youcompleteme#Resume()
  call youcompleteme#EnableCursorMovedAutocommands()
  let s:halt_ycm = 0
endfunction

and add the check to s:AllowedToCompleteInCurrentFile

if s:halt_ycm
  return 0
endif

The question here is if this is a valuable feature to implement and to support indefinitely.

mispencer commented 9 years ago

In all the use cases which I have personally wanted YCM to not run (for example, running something like :argdo %s/red/blue), I have also wanted all my other plugins to not run either. For my use case at least, the eventignore vim option or the noautocmd vim command is superior to anything YCM could possibly implement.

vheon commented 9 years ago

@mispencer thanks for sharing your experience. I didn't thought of using eventignore: so basically you let save_ei = &eventignore set eventignore=all do your stuff let &eventignore = save_ei, right?

mispencer commented 9 years ago

Yes, through I normally use the :noautocmd shortcut, which does that for a single command. I use :noautocmd a lot for command like :argdo, :windo, etc, since suppressing autocmds is a significant speedup. And YCM is not the only plugin in my setup which is a offender here.

vheon commented 9 years ago

My opinion on this is that we should keep things like they are and use :noautocmd or eventignore.

puremourning commented 9 years ago

Just weighing in on a slight tangent. I have long considered a :YcmDisable command which shuts off YCM for the current buffer. I have this need because some files (like 10,000 line test scripts) have disappointing performance (for good reason). I don't want to disable for all test scripts, just some. Eclim offers :EclimDisable which I also use. I know this is a different use case, but interested in your thoughts.

vheon commented 9 years ago

@puremourning then how would you remember in which buffer you have YCM disabled? I see it like a flag in the statusline, but then I see that I'm overengeering this too much :P

puremourning commented 9 years ago

I'd know because when I type I'd be disappointed that YCM wasn't working

krafczyk commented 9 years ago

@puremourning : Exactly, you don't really need to put it in the statusline

vheon commented 9 years ago

@puremourning IMHO if we do it like that we would have different scenarios:

that is because disabling YCM in a singular buffer without a way to mark it IMHO is not a great experience.

puremourning commented 9 years ago

i mean we could have YcmDebugInfo print a big old

YouCompleteMe is disabled. Type YcmEnable to enable.

Shrug. I think if I manually went to the trouble of disabling something I'd hope that I'd remember that I did so. But yeah, I'm not the sort to just raise a bug if I can't get sonething to work :)

sehe commented 8 years ago

I'm having this issue with very large diffs opened by vim-fugitive.

Browsing a commit, pressing "Enter" on a particular file will open the diff side-by-side. That is: you get two _new_ buffers with potentially large contents. What's more I don't think these buffers are backed by physical files, making the builting YCM protection for large files ineffective. This hangs up my vim for long periods of time (killed after 10 minutes) - seemingly even if the buffer contents is not a supported language by YCM.

All the above suggestions that center on "disabling YCM for the current buffer" work, because they are new buffers.

I've tried combining ideas above like :noautocmd normal <CR> instead of pressing Enter directly, but that just makes Fugitive unfunctional, leading to errors like

"fugitive:///home/sehe/WORK/.git//1604bd0d97fbd25f2b3c3cc52939272ea9a9b9b5/bla.py" [New DIRECTORY]
 E492: Not an editor command: Gdiff! 1604bd0d97fbd25f2b3c3cc52939272ea9a9b9b5^:bla.py

I suppose this is because Fugitive depends on autocommands to magically load the the diff if it detects the special filename.

I have no solution for this, other than removing YCM from my vim runtime environment and restarting Vim. I'd be very much in favour for a GLOBAL :YcmDisable or :YcmShutdown (the :YcmRestartServer already exists).

vheon commented 8 years ago

@sehe for your particular use case what you can do is to set manually the b:ycm_largefile to 1. So something like:

autocmd BufReadPre fugitive:///* let b:ycm_largefile = 1

I know is a hack but until we figure out something valid is all I can provide...

sehe commented 8 years ago

@vheon That's clever. Using the autocommands in our favour.

Sadly, it doesn't work, I just tested it. I can interrupt the long running operation (after several minutes), but then YCM is stuck in an error state spewing error messages all the time, so I have to kill -9 vim anyways.

(Running without YCM has slowness for this large diff, but interrupting makes the fugitive buffer responsive and functional, showing that YCM /can/ cope)

svandex commented 7 years ago

@Valloric make :YcmSuspend and :YcmResumecommand?

kgfly commented 6 years ago

:YcmSuspend and :YcmResumecommand should be useful

For some projects, I just want to turn off YCM. While in other prjs, keep it on.

I would like to turn off/on in .vimrc in runtime.

puremourning commented 2 years ago

I can't see us working on this any time soon, unless someone from the community contributes a PR and tests.