vscode-neovim
vscode-neovim copied to clipboard
Issue Tracker: Refactor document change manager (remove dot-repeat hack)
We want to refactor two-way sync.
- [x] https://github.com/vscode-neovim/vscode-neovim/pull/992
- [x] https://github.com/vscode-neovim/vscode-neovim/issues/543
- [ ] if we send inputs using nvim_input, we can remove dot-repeat hack, composite escape, etc
- [x] https://github.com/vscode-neovim/vscode-neovim/issues/543
- [ ] https://github.com/vscode-neovim/vscode-neovim/issues/625
- [x] https://github.com/vscode-neovim/vscode-neovim/issues/644
- [x] https://github.com/vscode-neovim/vscode-neovim/issues/1056
- [x] https://github.com/vscode-neovim/vscode-neovim/issues/1068
- [x] https://github.com/vscode-neovim/vscode-neovim/issues/1187
- [ ] https://github.com/vscode-neovim/vscode-neovim/pull/948
Here are my new ideas for removing dot repeat. I had some old ones at https://github.com/vscode-neovim/vscode-neovim/pull/992#issuecomment-1228734888, but they mostly involved trying to send edits to nvim in a way that would be picked up by dot repeat. Directly writing to dot repeat is going to be added to nvim at some point according to @justinmk, but not yet iirc.
My new idea takes inspiration from the way that many nvim plugins handle dot repeat: https://www.reddit.com/r/neovim/comments/wkqkzf/adding_dotrepeat_to_plugins/
The challenge is that I need to construct a string to save in operatorfunc.
There are two strategies:
- bind vscode
type
event and record keystrokes before sending them back to vscode. This is a major design decision but the performance should be good with the new extension affinity settings. Whenever an arrow key or cursor is moved, dot repeat is reset. - construct a set of typed changes by parsing the sequential editor changes produced by vscode, and trying to calculate what the user actually typed based on document changes. This is tricky however due to things like auto bracket pairs and discontinuous edits.
This should delete a lot of code.
This effort might be a no-go :/
The current dot repeat workaround works by - keys trigger insert mode (ciw, o, etc) - nvim_buf_set_text adds text to the buffer without updating dot repeat - escape is pressed - a separate buffer is made - the recorded changes are replayed using nvim_input - escape is sent
However, the only thing we can reasonably record is what is pressed during insert mode - the way that insert mode was reached (for example ciw) is not recorded. Thus, I can't set operatorfunc
to repeat the whole sequence including whatever is used to enter insert mode.
Binding type
event seems like it would be a bad idea, but I'm not fully sure if my (negative) experiments were properly conducted.
However, as one door closes, another opens, and I have come across https://github.com/neovim/neovim/pull/3306, which should allow me to implement the ideas in https://github.com/vscode-neovim/vscode-neovim/pull/992#issuecomment-1228734888.
I have narrowed it down to two options:
bind vscode type
I have figured out how to not break completions, and the lag seems acceptable.
The challenge
Edits come in both with type
and onDocumentChanged
. How can I merge them together? Ideas:
- when type, wait for document changed, and cancel it out surgically
- after sending type, do a diff from document changed and apply the diff instead
- go back to syncing changes from a diff when leaving insert mode
parse documentChanges
and convert to nvim_insert when applicable
I worked on this last year, and made some good progress. The roadblock was situations where you needed arrows, but now I have a solution. The code is pretty complicated for this though.
Closed, most content may be outdated. If there are new ideas, it's best to start a new discussion.