VIM version
NVIM v0.4.0-756-ge882460e5
Operating System:
PRETTY_NAME="Debian GNU/Linux 9 (stretch)"
NAME="Debian GNU/Linux"
VERSION_ID="9"
VERSION="9 (stretch)"
Python Language Server completion is not working when triggered manually in the middle of the word.
Expected behavior:
https://monosnap.com/file/Otc4gIn4f3FAPrx6mvpQjjZWQ2eAsh
Actual behavior:
No completions found.
I'm not sure but the issue reason might be in the following line:
https://github.com/w0rp/ale/blob/ca0cdd26fc4c29378b37bd214868050c61e0735d/autoload/ale/completion.vim#L527
Deletion of the "+ 1" solves the issue and completion works fine.
https://github.com/w0rp/ale/blob/ca0cdd26fc4c29378b37bd214868050c61e0735d/autoload/ale/completion.vim#L266
Function getpos in the case described above returns "2". That's why we don't have to do "+ 1" in this case. I'm not sure maybe it's neovim's bug.
let g:ale_completion_enabled = 0
let g:ale_completion_max_suggestions = v:null
let g:ale_echo_cursor = 1
let g:ale_echo_msg_error_str = 'Error'
let g:ale_echo_msg_format = '%code: %%s'
let g:ale_echo_msg_info_str = 'Info'
let g:ale_echo_msg_warning_str = 'Warning'
let g:ale_enabled = 1
let g:ale_fix_on_save = 0
let g:ale_fixers = {}
let g:ale_history_enabled = 1
let g:ale_history_log_output = 1
let g:ale_keep_list_window_open = 0
let g:ale_lint_delay = 200
let g:ale_lint_on_enter = 1
let g:ale_lint_on_filetype_changed = 1
let g:ale_lint_on_insert_leave = 0
let g:ale_lint_on_save = 1
let g:ale_lint_on_text_changed = 'never'
let g:ale_linter_aliases = {}
let g:ale_linters = {'python': ['pyls']}
let g:ale_linters_explicit = 0
let g:ale_list_vertical = 0
let g:ale_list_window_size = 10
let g:ale_loclist_msg_format = '%code: %%s'
let g:ale_lsp_root = {}
let g:ale_max_buffer_history_size = 20
let g:ale_max_signs = -1
let g:ale_maximum_file_size = v:null
let g:ale_open_list = 0
let g:ale_pattern_options = v:null
let g:ale_pattern_options_enabled = v:null
let g:ale_set_balloons = 0
let g:ale_set_highlights = 0
let g:ale_set_loclist = 1
let g:ale_set_quickfix = 0
let g:ale_set_signs = 1
let g:ale_sign_column_always = 0
let g:ale_sign_error = '◆'
let g:ale_sign_info = '●'
let g:ale_sign_offset = 1000000
let g:ale_sign_style_error = '◆'
let g:ale_sign_style_warning = '▲'
let g:ale_sign_warning = '▲'
let g:ale_statusline_format = v:null
let g:ale_type_map = {}
let g:ale_use_global_executables = v:null
let g:ale_virtualtext_cursor = 0
let g:ale_warn_about_trailing_blank_lines = 1
let g:ale_warn_about_trailing_whitespace = 1
Command History:
(executable check - success) pyls
(started) ['sh', '-c', '''pyls''']
Note that simply deleting + 1 will also break integration with other language servers, so the solution isn't so simple. We'll have to detect where the completion position ought to be based on the characters near the cursor instead, like using one character lower when your cursor is just before an open parenthesis, and one higher in other cases.
I'd like something similar to be tested with other Python language servers, because it might be pyls that's at fault. The only reason the max function call is there is because pyls breaks when you send character positions beyond the length of the line.
I agree that the solution is not so simple. Deleting +1 is just a quick fix for me because I only use pyls at the moment. The issue could be in the getpos function because it returns 2 in the case when the cursor placed in the position like on the screenshot below:
https://take.ms/typGz
LSP specification says:
Character offset on a line in a document (zero-based). Assuming that the line is
represented as a string, the character value represents the gap between the
character and character + 1.
As you can see on this screenshot cursor position, in this case, is 2. I mean that nvim calculates this position as 2.
Cursor position calculated by the following steps:
As a result, in this case, we will get the value 2. However, the specification says that we have to pass zero-based value 1 in this case. So I think this is a common issue, not only pyls related.
Okay, I'll take it away again, because it seems to work with rls, and wait for someone to report a bug about it not working because it was removed.
Removing both the use of min() and + 1 does seem to make completion better for rls. The only reason min() was being used is because Jedi via pyls was throwing errors when you send positions beyond the length of the line, which is correct in some cases. If completion at the end of lines in pyls stops working, get the pyls people to fix it because their code is wrong. It works perfectly with rls, and using min() makes it worse for rls.
https://github.com/palantir/python-language-server/pull/198/files It does look like they have since fixed that, so it should be fine.
I've just tested without min() and + 1 and it works perfectly with pyls.
Okay, thank you for the bug report. The issue here is that the code I wrote for LSP completion initially was tooled around working around bugs in pyls. Now pyls works properly, this should hopefully work well for everything.
Are you going to remove min() and + 1 in the future commits? Just interesting because I'm using a fork at the moment.
git pull, it's on master now.
Thank you!
Btw in my opinion ale's completion is the best. Thank you for doing this man!
Thanks for pointing this out. I think a few people have had someone issues, and until now no one has really done enough digging to figure it out.