[READY] Apply chunks from bottom to top
Without the proposed fix, the test included in that PR fails as follows
```
FAIL: ycm.tests.vimsupport_test.ReplaceChunksInBuffer_LineOverlappingChunks_test
----------------------------------------------------------------------
Traceback (most recent call last):
File "C:\Python36\lib\site-packages\nose\case.py", line 198, in runTest
self.test(*self.arg)
File "C:\Users\micbou\projects\YouCompleteMe\python\ycm\tests\vimsupport_test.py", line 768, in ReplaceChunksInBuffer_LineOverlappingChunks_test
AssertBuffersAreEqualAsBytes( expected_buffer, result_buffer )
File "C:\Users\micbou\projects\YouCompleteMe\python\ycm\tests\vimsupport_test.py", line 86, in AssertBuffersAreEqualAsBytes
eq_( ToBytes( result_line ), ToBytes( expected_line ) )
AssertionError: b' third line' != b' third '
```
Found the issue while trying to add code formatting support to the language server completer. The test is based on a real-world scenario when formatting with jdt.ls (for some reason, jdt.ls is including the newline of the previous line when fixing indentation).
<!-- 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/2898)
<!-- Reviewable:end -->
This implements an asynchronous message system using a long-poll request
to the server.
The server provides an endpoint /receive_messages which blocks until
either a timeout occurs or we receive a batch of asynchronous messages.
We send this request asynchronously and poll it 4 times a second to see
if we have received any messages.
The messages may either be simply for display (such as startup progress)
or diagnostics, which override the diagnostics returned by
OnFileReqdyToParse.
In the former case, we simply display the message, accepting that this
might be overwritten by any other message (indeed, requiring this), and
for the latter we fan out diagnostics to any open buffer for the file in
question.
Unfortunately, Vim has bugs related to timers when there is something
displayed (such as a "confirm" prompt or other), so we suspend
background timers when doing subcommands to avoid vim bugs. NOTE: This
requires a new version of Vim (detected by the presence of the
particular functions used).
When the message is exactly as wide as the vim window, vim still
displays "press enter..." message.
Wen we want to avoid that we need to cut the message one character
shorter.
Reduce the time spent to build the request when there are a lot of buffers by:
- using the options property on the buffer object to get the mod variable
instead of evaluating getbufvar;
- not computing the buffer filepath if the buffer is not modified;
- passing the number of the unloaded buffer instead of its filepath on the
BufferUnload event. Getting the Python buffer object from its number is
easier than from its filepath.
When no argument is given to the YcmToggleLogs command, instead of displaying
the list of available logfiles, prompt the user to open (or close if already
open) one of them.
On Windows, Vim returns buffer filepaths with forward slashes instead of
backward ones if the shellslash option is set. Since we always expect backward
slashes from the server, we normalize these paths.
The VimExpressionToPythonType function automatically convert a number
represented as a string to an integer. This causes an error when used to
evaluate a filetype set to a number as the result is split on the dot character
to get a list of filetypes and an integer cannot be split. Use vim.eval and
ToUnicode instead.
If no buffer exists for a given filename, the GetBufferNumberForFilename
function will create a buffer for that file by default. This behavior is
unexpected given the name of that function and may lead to performance issues
when ycmd returns diagnostics for a lot of files with no corresponding buffers.
The default behavior for that function should be to not create a buffer.
Calling directly the omnifunc may move the cursor position. This is the case
with the default Vim omnifunc for C-family languages (ccomplete#Complete) which
calls searchdecl to find a declaration. This function is supposed to move the
cursor to the found declaration but it doesn't when called through the omni
completion mapping (CTRL-X CTRL-O). So, we restore the cursor position after
calling the omnifunc.
The 'hidden' option is a global option, not a buffer one. If this option is
false, we should check if the 'bufhidden' option, which is local to the buffer,
is set to 'hide'. If so, the buffer can be hidden despite the 'hidden' option
being false.
[READY] Use codepoint offsets in identifier functions
`CurrentIdentifierFinished` and `LastEnteredCharIsIdentifierChar` incorrectly use byte offsets with unicode lines (`CurrentColumn` returns a byte offset and `CurrentLineContents` a unicode string). This leads to weird bugs when there is a non-ASCII character on the current line:
![unicode-identifier-bug](https://user-images.githubusercontent.com/10026824/27256590-34b27c8c-53ba-11e7-8032-b98f0c7e0b14.gif)
This is fixed by converting byte offsets to codepoint ones through the `ByteOffsetToCodepointOffset` function.
This changes the behavior of these two functions when the current column position is invalid. Both functions returned false in that case. They now return as if the current column were at the end of the line. In practice, this doesn't really matter since the position of the current column should always be valid.
<!-- 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/2690)
<!-- Reviewable:end -->
CurrentIdentifierFinished and LastEnteredCharIsIdentifierChar incorrectly use
byte offsets with unicode lines. Convert those offsets to codepoint offsets.
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.
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.
vim.eval returns a str() object on py2, but our internal strings are all unicode().
We use vimsupport.VimExpressionToPythonType to wrap the conversion complexities.