Sitecustomize files can be slow or broken and might hang editor
startup. Since they aren't necessary for checking the python version,
disable them to get a small speed boost for everyone, and an editor
that doesn't hang indefinitely on startup if the sitecustomize gets
into an infinite loop (due to a bad NFS mount or similar).
[READY] Fix exception when response future is not set
An `AttributeError` exception is raised when `Done` is called before `Start` in the `CompletionRequest` and `EventNotification` classes because the `_response_future` attribute is not yet defined.
Fixes#2461.
<!-- Reviewable:start -->
---
This change is [<img src="https://reviewable.io/review_button.svg" height="34" align="absmiddle" alt="Reviewable"/>](https://reviewable.io/reviews/valloric/youcompleteme/2465)
<!-- Reviewable:end -->
[READY] Catch and log all server exceptions
A lot of different errors may occur when sending a request to ycmd and receiving its response:
- [any exception from the requests module](http://docs.python-requests.org/en/master/_modules/requests/exceptions/);
- exceptions from ycmd: `ServerError` and `UnknownExtraConf`;
- `RuntimeError` exception from invalid HMAC;
- and possibly others.
Thanks to PR #2430, we can now catch and log these exceptions.
I am marking this PR as WIP because I'd like to add tests but I am not sure on how to implement them. Should we use actual code for these tests or mock the response from the ycmd server?
Fixes#2216.
Fixes#2272.
<!-- Reviewable:start -->
---
This change is [<img src="https://reviewable.io/review_button.svg" height="34" align="absmiddle" alt="Reviewable"/>](https://reviewable.io/reviews/valloric/youcompleteme/2453)
<!-- Reviewable:end -->
[READY] Fix flake8 error
This fixes a new error detected by the last version of `pycodestyle` (2.2.0), which is a dependency of `flake8`:
```
C:\projects\youcompleteme\python\ycm\youcompleteme.py:69:1: E305 expected 2 blank lines after class or function definition, found 1
```
<!-- Reviewable:start -->
---
This change is [<img src="https://reviewable.io/review_button.svg" height="34" align="absmiddle" alt="Reviewable"/>](https://reviewable.io/reviews/valloric/youcompleteme/2441)
<!-- Reviewable:end -->
[READY] Move client tests to the main tests folder
This makes it possible to configure all tests at a package level by implementing the `setUpPackage` and `tearDownPackage` functions in `python/ycm/tests/__init__.py` file.
<!-- Reviewable:start -->
---
This change is [<img src="https://reviewable.io/review_button.svg" height="34" align="absmiddle" alt="Reviewable"/>](https://reviewable.io/reviews/valloric/youcompleteme/2394)
<!-- Reviewable:end -->
Implement ycm_quiet_messages options (See #2021)
# PR Prelude
- [x] I have read and understood YCM's [CONTRIBUTING][cont] document.
- [x] I have read and understood YCM's [CODE_OF_CONDUCT][code] document.
- [x] I have included tests for the changes in my PR. If not, I have included a
rationale for why I haven't.
- [x] **I understand my PR may be closed if it becomes obvious I didn't
actually perform all of these steps.**
# Why this change is necessary and useful
See issue #2021. This is a partial implementation based on the syntastic option referenced, supporting the `!` flag and filters of type `regex` and `level`. Also supports filetype specific filters using `ycm_<ft>_quiet_messages`, but I couldn't think of a great way to fall back to syntastic configs for this one.
In terms of usefulness: I've been playing with C# recently, which has a bunch of style warnings that I don't want to follow, and prefer to only have the gutter showing if there are actually errors, or warnings that I *do* want to follow.
<!-- Reviewable:start -->
---
This change is [<img src="https://reviewable.io/review_button.svg" height="34" align="absmiddle" alt="Reviewable"/>](https://reviewable.io/reviews/valloric/youcompleteme/2377)
<!-- Reviewable:end -->
We eagerly compile all the filters up front, then gather the
compiled filters into a DiagnosticFilter lazily, caching the
result to avoid garbage lists.
[READY] Add coverage support
There should not have anything to configure on codecov website.
I updated the `run_tests` script to behave exactly like the one in ycmd repository: when passing tests as arguments, you need to specify the path from the root project, not the `python` folder. For instance:
```
./run_tests.py --skip-build -- python/ycm/tests/event_notification_test.py
```
instead of
```
./run_tests.py --skip-build -- ycm/tests/event_notification_test.py
```
This way, you can now complete the path to the test.
<!-- Reviewable:start -->
---
This change is [<img src="https://reviewable.io/review_button.svg" height="34" align="absmiddle" alt="Reviewable"/>](https://reviewable.io/reviews/valloric/youcompleteme/2385)
<!-- Reviewable:end -->
Send the request as the unloaded buffer instead of the current buffer
for the BufferUnload event notification. This fixes the issue where
the filetype of the current buffer is not the same as the unloaded
buffer one, making the ycmd server uses the wrong completer when
handling the request.
When an error occurs during completions, a message is displayed on
the status line. If this message is longer than the width of the
current window, Vim will prompt the user to press enter or type a
command to hide the message, interrupting user workflow. We prevent
that by truncating the message to window width.
Merge PostMultiLineNotice, EchoText, and EchoTextVimWidth functions
into PostVimMessage.
When columns are clamped to not be past the contents of the line for
highlighting diagnostics, we need to account for the column end not
being included in the diagnostic range.
Use the following strategy to extract identifiers from syntax
highlighting:
- ignore match and region: they mostly contain arguments,
syntax groups and regular expressions;
- ignore "nextgroup=" if first word and subsequent arguments
"skipempty", "skipwhite", and "skipnl";
- ignore "contained" argument if first word;
- add remaining words to the list of identifiers.
Fix a bug where the word "match" was extracted while not being a keyword
of the syntax language.
Do not convert strings to bytes but instead use plain strings to mimic
Vim buffers returning a list of byte objects on Python 2 and unicode
objects on Python 3.
Open the quickfix window to full width at the bottom of the screen with
its height set to fit all entries. This behavior can be overridden by
using the YcmQuickFixOpened autocommand.
Add a new section for autocommands in the documentation.
Update GoTo and ReplaceChunks tests.
On Python 3, evaluating a Vim expression will raise a unicode exception
if it contains an invalid sequence of bytes for the current encoding.
We can't really do anything about it because this is the way Vim and
Python 3 interact. However, we can prevent this situation to occur by
not evaluating Vim data that we have no control over: in particular,
the Vim globals. This is done by:
- adding one by one the YCM default options instead of extending the
Vim globals with them;
- only evaluating the Vim global variable names (and not their values)
when building the YCM options for the ycmd server.
Display an error message to the user depending on the status code
returned by the ycmd server.
Remove ycm_core checks in plugin/youcompleteme.vim. These checks are
now done by the ycmd server.
Do not start a separate process to check the core version but rely on
ycmd returning a specific exit code. This slightly improves the Vim
startup time.
vim.eval returns a str() object on py2, but our internal strings are all unicode().
We use vimsupport.VimExpressionToPythonType to wrap the conversion complexities.
Do not send an "event_notification" request in OnFileReadyToParse
function if server process is terminated. Otherwise, it blocks Vim
for one second or results in a traceback each time the InsertLeave,
CursorMoved, CursorHold, and BufferVisit events are triggered.
On Windows and Python 2, the full exception message from IOError
in CheckFilename will contain the filepath formatted as a unicode
string. Since the filepath is already added in the RuntimeError
message, use the strerror attribute to only display the error.
Move PostComplete tests inside a class that defines setUp and tearDown
methods. Clean YCM object in tearDown method. This fixes the error
"OSError: [WinError 6] The handle is invalid" on Windows with
Python 3.5.
Python 3 is much stricter around mixing bytes with unicode (and by
"stricter," I mean it doesn't allow it at all) so we're making
vimsupport only return `unicode` objects (`str` on py3). The idea is
that YCM (and ycmd) internals only ever deal with unicode.
We simply apply the changes to each file in turn. The existing replacement
logic is unchanged, except that it now no longer implicitly assumes we are
talking about the current buffer.
If a buffer is not visible for the requested file name, we open it in
a horizontal split, make the edits, then hide the window. Because this
can cause UI flickering, and leave hidden, modified buffers around, we
issue a warning to the user stating the number of files for which we are
going to do this. We pop up the quickfix list at the end of applying
the edits to allow the user to see what we changed.
If the user opts to abort due to, say, the file being open in another
window, we simply raise an error and give up, as undoing the changes
is too complex to do programatically, but trivial to do manually in such
a rare case.
Now 'GoTo' and 'FixIt' commands don't need to start with those
prefixes. For 'FixIt' we can detect the response type by looking for
the 'fixits' entry in the response.
For 'GoTo' this is a touch harder, as there is no completely obvious
way to tell. However it is unique in this respect, so we can simply
fall back to it.
Completers returning other types of response are not supported by
this client.
Moved File parse request handling and diagnostic extraction flow into
python to simplify flow and allow easier addition of new parse request
handlers such as semantic highlighter.
Refactored base_test to patch separate vimsupport functions instead of
the whole module, and interfering the test results afterwards.
Added new tests for diagnostic sign place/unplace and error/warning
count extraction API.
[READY] Fix issue in EventNotification tests
While I was reviewing PR #1905, I found an issue with the `EventNotification` tests. It's easy to reproduce. You just need to comment [this line in `python/ycm/youcompleteme.py`](https://github.com/Valloric/YouCompleteMe/blob/master/python/ycm/youcompleteme.py#L508) and run the tests. With this change, the `EventNotification` tests should fail since the second call of `ValidateParseRequest` re-raises the warning. However, tests are still passing because `assert_has_calls` does not check if a call was not made. For example, if `functionA` is called twice, both `assert_has_calls( [ functionA ] )` and `assert_has_calls( [ functionA, functionA ] )` are successful.
To fix this, we just need to check the number of calls using `call_count`. This is done by creating a subclass of `MagicMock` implementing the `assert_has_exact_calls` method and using it in tests.
<!-- Reviewable:start -->
[<img src="https://reviewable.io/review_button.png" height=40 alt="Review on Reviewable"/>](https://reviewable.io/reviews/valloric/youcompleteme/1927)
<!-- Reviewable:end -->
[READY] Implement new strategy to find the Python interpreter path
See discussion in issue #1891 for details.
Implement a new strategy to find the Python interpreter path:
- if specified, use `g:ycm_path_to_python_interpreter` option.
- on UNIX platforms, use `sys.executable` as the path to Python interpreter;
- on Windows, deduce it from `os.__file__` path (it should always be in the parent folder).
In all cases, check the version (2.6 or 2.7) of the Python interpreter path by running it.
This PR may break things. It needs thorough testing.
<!-- Reviewable:start -->
[<img src="https://reviewable.io/review_button.png" height=40 alt="Review on Reviewable"/>](https://reviewable.io/reviews/valloric/youcompleteme/1896)
<!-- Reviewable:end -->
assert_has_calls is not enough to check if a call didn't raise a
warning. We also need to check the number of calls. This is done by
creating a subclass of MagicMock implementing the
assert_has_exact_calls method.
OmniCompletionRequest is missing the RawResponse method, so any attempt to call
it calls the base class method instead. However, since the data structures of
this class and base class are different, this causes an error.
Rename CheckPythonVersion to IsPythonVersionCorrect.
In embedders, sys.executable may contain a Vim path instead of a Python
one. To avoid starting a Vim instance in this case, we check that given
path ends with a Python 2.6 or 2.7 name using a regex.
Add tests for this regex.
If the check for available completers isn't run because the server isn't
alive, or the check request erred or times out, don't cache the result. Only
cache valid returns.
[READY] Update notifications when ycmd server crashed
Instead of printing the last 30 lines of the `stderr` logfile if the server crashed, we tell the user to run the `:YcmToggleLogs stderr` command to check the logs.
Remove `SERVER_CRASH_MESSAGE_SAME_STDERR` message because we are always using the `stderr` logfile since PR #1753. Also, console ouput cannot be used to see the logs.
Simplify `_NotifyUserIfServerCrashed` method by using `CheckFilename` function from `vimsupport` module.
<!-- Reviewable:start -->
[<img src="https://reviewable.io/review_button.png" height=40 alt="Review on Reviewable"/>](https://reviewable.io/reviews/valloric/youcompleteme/1875)
<!-- Reviewable:end -->
Vim's QuickFix lists require 1-based columns, which is what is returned
from ycmd's commands.
As noted in the comments, the Vim documentation for setqflist is
somewhat vague about this "byte offset", but it is confirmed to mean
"1-based column number" both in testing and in :help getqflist.
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 -->
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.
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
We display the detailed info text in the preview window. Vim's preview window is
designed to display actual files, not scratch data. Our approach is to open a
temporary file, even though that file is never written. This way, all of Vim's
existing settings for the preview window (and people's configured mappings) just
work. This is also consistent with showing the documentation in the preview
window during completion.
Other plugins have more complicated functions for this (such as eclim), or
Scratch.vim, but this approach is simple and doesn't require external
dependencies or additional settings.
Tests:
This required fixing a sort-of-bug in which the mock'd Vim module was always
only set once, and could not be changed outside of the module which created it.
This meant that it wasn't easy to have arbitrary tests, because it was dependent
on the order in which the tests execute as to whether the return from
MockVimModule() was actually the one in use.
The solution was to make the mock'd vim module a singleton, and use mock's
patch decorator to assign new MagicMock() instances to those methods in the vim
module which a particular test is interested in.