[READY] Raise warnings on FileReadyToParse for completers not supporting diagnostics
Fixes#1829
## Background
Detailed analysis is available on [the issue](https://github.com/Valloric/YouCompleteMe/issues/1829). But principally: if the filetype being edited is not a filetype suporting YCM native diagnostics, then warnings, errors, etc. (including the "unknown extra conf" warning/prompt) are not displayed after the "FileReadyToParse" `event_notification`
## Resolution
The approach is: for filetypes which do not support diagnostics, rather than ignoring all `FileReadyToParse` event responses, simply call the `Response` method, which raises the appropriate error or handles the "confirm extra-conf" behaviour. Any other data returned by the completer (such as diagnostics!), are simply ignored.
## Manual Testing
Tested with tern completer which raises an error if the `.tern-project` file is not found.
Tested with a modified tern completer with the following `OnFileReadyToParse`:
```python
def OnFileReadyToParse( self, request_data ):
self._WarnIfMissingTernProject()
module = extra_conf_store.ModuleForSourceFile( request_data[ 'filepath' ] )
if not module:
if not self._raised_extra_conf_warning:
self._raised_extra_conf_warning = True
raise NoExtraConfDetected
return
# use module!
```
Results all as expected:
- with no `.tern-config`: tern config warning (once)
- with `.tern-config`, but no `.ycm_extra_conf`: no extra conf warning (once)
- with `.tern-config` and `.ycm_extra_conf`: confirmation prompt (once)
## Automated Testing
This was a marathon. Or a mockathon, I suppose.
Briefly:
- I wrote a `event_notification_test.py` which tests these new `YouCompleteMe` object behaviours, via a complex series of mocking
- I had to refactor the `postcomplete_tests.py` to prevent it from leaving `MagicMock` instances all over the place because this lead to the above test failing (apparently) randomly
- In order to debug the above shenanigans I updated `run_tests.py` to allow passing arguments to nosetests, like we do in `ycmd`
There are more comments in the code and on the various commit messages, explaining what's going on.
With regard to style, there is quite a lot of:
```python
@contextlib.contextmanager
def something():
with patch(this):
with patch(that):
with patch(the_other):
yield
@patch( foo )
def do_a_test( foo ):
with something():
do_a_thing()
assert foo.called()
```
The reason for this relative ugliness is that there is a lot of boilerplate mocking code. Because of a number of foibles of `mock` and the versions of python we support, I found this to be the least hacky way of ensuring that everything was cleaned up and was relatively sane to read and maintain.
Explanation for the `with`-ception that is going on:
- @patch is my preferred method, but it is more difficult to comment well and doesn't work when used with `@contextlib.contextmanager`, so you have to use `with`
- multiple managers in a single `with` statement is not supported in Python 2.6
- `contextlib.nested` is deprecated and buggy (apparently)
<!-- Reviewable:start -->
[<img src="https://reviewable.io/review_button.png" height=40 alt="Review on Reviewable"/>](https://reviewable.io/reviews/valloric/youcompleteme/1848)
<!-- Reviewable:end -->
- Fix some subordinate clause gymnastics
- Signpost the tern configuration advice better
- Signpost the link to the Tern docs better
- Sort out some bullet-list issues
Like we do in ycmd, allow additional arguments of run_tests to be passed
directly to nosetests.
In order to maintain the existing behaviour, and not require fiddly command
lines, always run nosetests in the python directory (using the -w - working
directory) switch.
Previously, running postcomplete_tests.py could lead to MagicMock objects being
left around within the ycm modules. This lead to random test failures in other
modules.
Further, by using mock.patch appropriately, tests withing postcomplete_tests.py
no longer rely on mocking performed by previous tests (and can be successfully
run individually)
Set buffer filetypes for UltiSnips
Currently, only `all` snippets are displayed by YCM because UltiSnips is called without setting the buffer filetypes. See issue #1818.
This is fixed by using UltiSnips methods `reset_buffer_filetypes` and `add_buffer_filetypes`.
<!-- Reviewable:start -->
[<img src="https://reviewable.io/review_button.png" height=40 alt="Review on Reviewable"/>](https://reviewable.io/reviews/valloric/youcompleteme/1821)
<!-- Reviewable:end -->
Handle canonical response from subcommands
In continuation to PR #1805, when the ycmd server returns a canonical type (boolean, number, string, etc.), we should print it to the user.
For example, this applies to the `SolutionFile` C♯ subcommand which only returns a string (actually, this could be improved in the completer).
This also fixes a thrown exception when the response is not iterable (a number for example).
<!-- Reviewable:start -->
[<img src="https://reviewable.io/review_button.png" height=40 alt="Review on Reviewable"/>](https://reviewable.io/reviews/valloric/youcompleteme/1807)
<!-- Reviewable:end -->
Handle boolean responses from ycmd subcommands
`ServerReady`, `ServerRunning`, and `ServerTerminated` C♯ subcommands could return a traceback or nothing in Vim because ycmd returns a boolean as the response of these commands.
Fix this by echoing `Yes` when the response is `True`, `No` otherwise.
Refactor the `RunPostCommandActionsIfNeeded` function to improve readability.
<!-- Reviewable:start -->
[<img src="https://reviewable.io/review_button.png" height=40 alt="Review on Reviewable"/>](https://reviewable.io/reviews/valloric/youcompleteme/1805)
<!-- Reviewable:end -->
Introducing :YcmToggleLogs command
Two approaches were proposed in PR #1753:
- open the stdout and stderr logfiles in Vim windows or close them if already opened: `:YcmToggleLogs`;
- open one of the logfiles in the preview window by specifying it as an argument in the command: `:YcmShowLog <stdout|stderr>`.
This PR merges both approaches by adding an optional argument (`Stdout` or `Stderr`) to the first approach. When no argument is given, both logfiles are opened (or closed if already opened).
With this approach, we cannot use the preview window because only one such window is allowed by Vim. So, we simulate it by adding properties specific to the preview window (horizontal split, height, etc.)
Since they are multiple ways to open a file in Vim, I added a generic function `OpenFilename` for this. It makes easy to customize the way logfiles are opened and could be useful for new features.
Tests were a pain to add and I am not sure of the way I implemented them. If someone could review them. There is some refactoring of the Vim mock.
I updated the documentation and the contribution guidelines. I added a new instruction when creating an issue: adding the output of the `:YcmDebugInfo` command. We often ask it in the issues.
I suggest fetching the `ycm-toggle-logs` branch of my repository to test yourself this command.
<!-- Reviewable:start -->
[<img src="https://reviewable.io/review_button.png" height=40 alt="Review on Reviewable"/>](https://reviewable.io/reviews/valloric/youcompleteme/1760)
<!-- Reviewable:end -->
If already opened logfiles are not visible (hidden buffers or in another
tab), close them and open new ones. It fixes the issue where the command
seems to do nothing even though it actually close the non-visible logfiles.
Mock buffers as a list of buffers where each buffer is represented
as a dictionary containing its filename, its number, and optionally
its associated window.
Test buffer visibility instead of existence.
Mock Vim wipeout command.
Refactor Vim mocks.
Run tests on OS X
There should be no difference between the behaviour on OS X and the behaviour on other platforms as all of the tests are python. However, running them is cheap and proves that there are no differences.
The approach is to import the scripts from `ycmd` with a couple of modifications:
- don't set `YCM_CORES=1` as we didn't before, and this makes the build a lot faster
- don't install `gcc-4.8` as we didn't before
- install `argparse` for the tests as it is not available in python2.6
<!-- Reviewable:start -->
[<img src="https://reviewable.io/review_button.png" height=40 alt="Review on Reviewable"/>](https://reviewable.io/reviews/valloric/youcompleteme/1762)
<!-- Reviewable:end -->
We import the scripts from ycmd with a couple of modifications:
- don't set YCM_CORES=1 as we didn't before, and this makes the build a lot faster
- don't install gcc-4.8 as we didn't before
- install argparse as it is not available in python2.6
Fix AppVeyor configuration
AppVeyor certainly made some changes to their infrastructures because the `run_tests.py` script is not properly executed anymore. We now need to specifically call it with python.
This is already done in the `ycmd` repository so no changes needed there.
<!-- Reviewable:start -->
[<img src="https://reviewable.io/review_button.png" height=40 alt="Review on Reviewable"/>](https://reviewable.io/reviews/valloric/youcompleteme/1761)
<!-- Reviewable:end -->
Remove g:ycm_server_use_vim_stdout option
The `g:ycm_server_use_vim_stdout` option is not working like expected. ycmd logs are not written to the console when using the gui client with this option enabled. This is the case on Windows and I think @puremourning can confirm this on other platforms. Worse, it also makes the ycmd server unresponsive on Windows.
It's a big issue because we recommend to use this option in [CONTRIBUTING.md](https://github.com/Valloric/YouCompleteMe/blob/master/CONTRIBUTING.md).
This PR removes the option and updates the contribution guidelines by asking the user to put the `let g:ycm_server_keep_logfiles = 1` option instead.
To further improve the debugging process, I would like to add a new command `:YcmToggleLogs` (thanks to @puremourning for the idea) that automatically open or close the ycmd stdout and stderr logs as windows in Vim. If you agree, I'll send another PR adding the command.
Note: if you are wondering why the ycmd stdout logs are always empty while you are adding print statements in the ycmd code, this is because the output needs to be flushed: `sys.stdout.flush()`.
<!-- Reviewable:start -->
[<img src="https://reviewable.io/review_button.png" height=40 alt="Review on Reviewable"/>](https://reviewable.io/reviews/valloric/youcompleteme/1753)
<!-- Reviewable:end -->