-
Notifications
You must be signed in to change notification settings - Fork 305
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Implement linkedEditingRange (experimental) #1022
Conversation
@prabirshrestha If we can't accept external vital module dependencies, feel free to close this PR. |
f01d0bb
to
59469e5
Compare
64948a6
to
e5f975e
Compare
Hm... CI failed by vital files... |
@hrsh7th I don't mind external dependencies as long it ships with vim-lsp so that for a consumer there is only one plugin. There are few requirements.
vim-lsp was one of my first plugins and was the plugin I learnt to built vim plugins. So I'm all for better refactors as the code was written long time back as long we don't break others. We should avoid breaking changes if possible. I do like how vim-lamp organizes so we could slowly migrate to that style but I'm not sure what your plans are for vim-lamp. One big difference is I do want to use callbag instead of promises as they are more powerful to expose async apis. I have been trying to add popup from vitial.vim too. vim-jp/vital.vim#748 One open question would be is where is the source of truth for lsp vital.vim be? by the way these are awesome changes! I will be looking at the PR over the next few days. |
Thank you for your comments.
Thank you. I will update the license.
The reasons why I wrote vim-lamp is that the below.
I agree with you. To ship LSP related features with original vital.vim will be an ideal solution. Another point. For example, the If we provide an API as below, it would be very flexible.
If you interest it, it can be including vim-lsp 2021. |
I found the way to support vim/nvim both. The way is using |
34d81d2
to
4545247
Compare
4545247
to
7db44b6
Compare
8b6f9c6
to
71b1c56
Compare
…n instead of LSP position)
Even I'm not fan of callback. Hence instead of adding more features I spent my time working on observable style apis with callbag. +1 for LSP/Editor features. I have always wanted easier unit testing and better separation. I didn't completely understand the provider refactor your proposed so a sample PR even if it doesn't work but just with comments might help here. For example how would one register a documentSymbol provider. I would want to support the current mechanism by showing it in the quickfix but also want to add other featurs such as show in treeview so can navigate differntly, support custom operators so can do something like select inside function, select around function, select inside class, select inside block and so on, implement something like goto type that is similar to vscode but uses quickpick. What does registering a provider mean for documentsymbol? performance seems the number one feature request for 2021 so we need to make sure new pattern allows us to swap certain bottlenecks with lua. I know autocomplete is a huge bottleneck so we could start with refactoring completion as an example for provider. some language servers uses utf-8 while by default most support utf-16. does it make sense to have utils functions aware of this so it picks the right offset? At least I haven't seen utf-16 being the botteleneck currently. As for vital I was thinking if the source of truth should be in vim-lsp instead of vim-lamp but that would depend the goals of vim-lamp. |
I haven't advertised vim-lamp at this time because it's just my sandbox/experimental environment (it often has a destructive change and probably won't work on windows). But I think https://github.com/hrsh7th/vim-vital-vs can be our source of truth.
I think The UI uses the features. The features does not depends on LSP but LSP can be connected to the features.
OK. I will try to refactor the completion as the provider pattern. |
@hrsh7th looking for the new refactors. One thing we should try to do is add proper license to vital-vs. In some countries public domain and other license are not valid. So using a well known such as mit or apache is better. Once you have contributors and you modify the license you need to reach out to old contributors and it is a hassle to change the license so would be good to get this right in the first go. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
added comments.
@@ -29,6 +29,38 @@ function! lsp#utils#range#_get_current_line_range() abort | |||
return l:range | |||
endfunction | |||
|
|||
" Returns the range contains specified position or not. | |||
function! lsp#utils#range#_contains(range, position) abort |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
seems like this can be used to solve this issue now. #888
\ lsp#callbag#pipe( | ||
\ lsp#callbag#fromEvent(['InsertEnter']), | ||
\ lsp#callbag#filter({ -> g:lsp_linked_editing_range_enabled }), | ||
\ lsp#callbag#flatMap({ -> s:request_sync() }), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
is there a reason it needs to be sync?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I afraid to lost keypress if the user presses quickly. So I'm choosing it to be sync.
But if text-prop/extmark is working correct, we can choose debouncing it.
\ lsp#callbag#subscribe({ -> s:clear() }) | ||
\ ), | ||
\ lsp#callbag#pipe( | ||
\ lsp#callbag#fromEvent(['TextChanged', 'TextChangedI', 'TextChangedP']), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
i think for now it is ok. but TextChangedP
is not available in all versions. One easy fix would be to check for TextChangedP
support in s:enabled
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this will also hopefully encourage folks to migrate to newer versions.
|
||
function! s:sync() abort | ||
let l:bufnr = bufnr('%') | ||
if s:state['bufnr'] != l:bufnr |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
for callbags this is usually not preferred. you can instead use switchMap
and takeUntil
similar to this https://github.com/prabirshrestha/vim-lsp/blob/master/autoload/lsp/internal/document_highlight.vim
Feel free to change or ignore it for now and I can refactor it later when it is merged.
I usually use RxJS or other Rx libraries does to understand callbag.
High level these are what it means.
- switchMap -> when ever you have a next, cancel the existing one and start a new one. Good example for this is autocomplete where if I type
he
and then typehello
I want to cancelhe
and automatically starthello
. - takeUntil -> this is use for cancellation. basically it means when a next is called in takeuntil cancel the stream.
But since you are using wait what you have should be ok.
Some good reading here. https://medium.com/@benlesh/rxjs-dont-unsubscribe-6753ed4fda87
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you. I learned a lot.
Thank you for your review. I will update it later. |
- Use lsp#callbag#filter - s:request_sync returns value instead of stream - Add workaround for extmark - Update vital modules
nmap <buffer> d <Plug>(lsp-linked-editing-range-prepare)<Plug>(vimrc-d) | ||
xmap <buffer> d <Plug>(lsp-linked-editing-range-prepare)<Plug>(vimrc-d) | ||
nmap <buffer> c <Plug>(lsp-linked-editing-range-prepare)<Plug>(vimrc-c) | ||
xmap <buffer> c <Plug>(lsp-linked-editing-range-prepare)<Plug>(vimrc-c) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry. I noticed it does not work.
But "nnoremap d lsp#internal#linked_editing_range#prepare() . 'd'" is works fine.
I don't know how to expose mapping function in vim-lsp. (lsp#mapping#linked_editing_range_prepare()?
)
neovim's extmark has bug (may be). |
This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions. |
This PR aims to support
textDocument/linkedEditingRange
.This implementations uses
nvim_buf_set_extmarks
in neovim andprop_add
in vim (this is polyfilled byvim-vital-vs
).Notable changes
Replace
TextEdit
implementation tovim-vital-vs
's one.This change is needed to preserve
extmarks
ortext-props
because the current implementation always appliesline-wise
changes.The extmarks and text-props are shifted to follow other text changes automatically so we should apply
TextEdit
aschar-wise
changes.Currently,vim-vital-vs
will supportchar-wise
implementation only when availablenvim_buf_set_text
.I sent an issue to vim for supporting it... vim/vim#7617Now,
vim-vital-vs
supports vim/nvim both.Use
vim-vital-vs
'sTextMark
implementation.It is polyfill fornvim_buf_set_extmarks
andprop_add
and it respects theRange
defined in LSP.Now,
vim-vital-vs
use vim's position instead ofRange
.How to test this?
npm install -g vscode-langservers-extracted
vscode-html-language-server
bylsp#register
.foo.html
and edit tag name.TODO
d
andc
normal-mode commandsDEMO
Kapture.2021-01-05.at.19.30.50.mp4