-
-
Notifications
You must be signed in to change notification settings - Fork 6.3k
[RDY] API: Implement nvim_win_set_buf #9100
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
Conversation
The current implementation does change the buffer, but the user needs to switch to another window first to see the changes. I'm certain that just changing the buffer the window points to cannot be all there is to it. The I have looked into the implementation of As a side-note, function! nvim_set_current_buf(buffer)
call nvim_win_set_buf(nvim_get_current_win(), a:buffer)
endfunction Opinions on this by the Neovim maintainers? |
For better and worse, a lot of API (and recent vimL functionality) is implemented by changing curwin and/or curbuf, call an existing function that assumes curwin/curbuf, and then restoring the old current values. So I wouldn't be this quick to conclude that |
Most likely that indirectly runs do_buffer, accidentally doing the necessary fixups.
Why not set the current window temporarily, then unwind it? That's the usual way. Disabling autocommands etc makes it fast. |
And for a moment there I though I could get away from Vim's ritualistic code by going to the actual source. It's rituals all the way down, isn't it? |
(oops) Well, the insides can be ugly, but we hide the ugly behind a nice API. Better to get it right before worrying about elegance. One could change do_buffer to take a buf_T parameter in the future, perhaps. |
You are right. My problem with ritualistic code is that it is easy to miss part of the ritual and have things work fine for the most part, but not always. Take for example the updated code I just pushed, it works well, but the error handling is messed up. Looking at the function, it would have been better if I had just written it straight up in VimScript instead. function! nvim_win_set_buf(win, buf)
let old_win = nvim_get_current_win();
call nvim_set_current_win(a:win)
call nvim_set_current_buf(a:buf)
call nvim_set_current_win(old_win)
endfunction I had hoped that writing this directly in the source would avoid triggering fifty side effects from switching windows, but that would require digging even deeper into Neovim's core code and going down to the bare bytes. At this point I'm not sure if there is even a point in continuing with this anymore. |
No need to be so defeatist this quickly. "Ritual" or not, other API functions have managed to avoid filthy side effects without too much raw byte banging. If we look at |
@bfredl You are right, I guess I'm just in a bad mood and threw in the towel too early. |
Much better! Just needs a couple tests and address the TODO. Might want to add another sentence or two in the docstring explaining the motivation or an example. |
I noticed something weird: " There are two windows: 1000 and 1001, I am in window 1001 at the moment
call nvim_win_set_option(1000, 'stl', 'Hello world')
" The above changes the status line in the other window, as expected
call nvim_win_set_buf(1000, 2)
" The above changes the buffer, as expected Now both windows show the same status line. Switching back to the original buffer restores my
Sure thing, I just wanted to get this to work before applying the polish. What should be the API level? 6? |
Not sure. How does it behave with VimL?
See NVIM_API_LEVEL in CMakeLists.txt |
That was VimL. Nevermind anyway, I looked into how options are set: // File src/nvim/private/helpers.c
// Omitting irrelevant code
static void set_option_value_for(char *key,
int numval,
char *stringval,
int opt_flags,
int opt_type,
void *from,
Error *err)
{
switch (opt_type)
{
case SREQ_WIN:
switch_win(&save_curwin, &save_curtab, (win_T *)from, win_find_tabpage((win_T *)from), false)
set_option_value_err(key, numval, stringval, opt_flags, err);
restore_win(save_curwin, save_curtab, true);
break;
case SREQ_BUF:
switch_buffer(&save_curbuf, (buf_T *)from);
set_option_value_err(key, numval, stringval, opt_flags, err);
restore_buffer(&save_curbuf);
break;
}
} There is not really such a thing as a "window-local" option, |
Note the docs claim |
I tried it and I see the same behaviour: the "window-local" options switches along with the buffer. It makes sense if you look at the code in my previous post: in both cases (I hate how Vim as taught me to press CTRL-W to delete the current word, I always end up closing a browser window after having almost finished a post) |
Ahyes, it likely behaves like |
The old code could lead to a memory error in the following situation: 0. The previous cursor position was row 50 since before, on a grid larger than 50 rows. 1. grid_resize changes the grid height to 40, and invalidly assumes the resize moved the physical cursor to row 0 2. Some event used a operation that could move the cursor (such as clear), and then reset the cursor to the "true" position row 50 (pointless after #8221, but I forgot to remove it) 3. raw_line/cheap_to_print is invoked, and tries to inspect the grid at row 50 (memory error) 4. grid_cursor_goto would have been called at this point, and set a valid cursor position 0-39.
This was caused by cursor position being invalid right after tui_grid_resize, which is now fixed
Problem: Function to set terminal name is too long. Solution: Refactor the function. Fix typo in test. vim/vim@69e0569
Problem: resolve() was not tested with a symlink cycle. Solution: Add a test. (Dominique Pelle, closes vim/vim#3513) vim/vim@2610990
Problem: MS-Windows: executable() is not reliable. Solution: Use $PATHEXT properly. (Yasuhiro Matsumoto, closes vim/vim#3412) vim/vim@8295666
Windows has "Read and execute" permission via ACL but nvim and libuv do not support ACL. Windows does not support the executable bit in chmod-style permissions but it is safe to assume that if the file exists and is readable, then it is most likely executable. This means that win.ini and shell32.dll are "executable" because they exist, are readable, and are in PATH. PATHEXT does not affect the executable permission of a file; it exists to run files on the shell while omitting the file extension. Assume that PATHEXT is intended for cmd.exe only because powershell can execute powershell files (ie. *.ps1) without changing PATHEXT or related cmd.exe environment variable. In the future, nvim should check the outputs of 'assoc' and 'ftype', cmd.exe internal commands, or check the registry. Powershell can be used for ACL if C++/C# API is too difficult to use.
…system Problem: Test_executable fails when there is a dog in the system. Solution: Rename the dog. (Hirohito Higashi) vim/vim@a05a0d3
Problem: "simalt ~x" in .vimrc blocks swap file prompt. Solution: Flush buffers before prompting. (Yasuhiro Matsumoto, closes vim/vim#3518, closes vim/vim#2192) vim/vim@798184c
Problem: Autocmd test fails. Solution: Do call inchar() when flushing typeahead. vim/vim@6a2633b
) Problem: Deleting in a block selection causes problems. Solution: Check the length of the line before adding bd.textcol and bd.textlen. (Christian Brabandt, closes vim/vim#2825) vim/vim@35e802e
Problem: Error in return not caught by try/catch. Solution: Call update_force_abort(). (Yasuhiro Matsomoto, closes vim/vim#2483) vim/vim@fabaf75
…after '<,'> Problem: One character cmdline abbreviation not triggered after '<,'>. Solution: Skip over the special range. (Christian Brabandt, closes vim/vim#2320) vim/vim@5e3423d
…#9104) Problem: Cannot cleanup before loading another colorscheme. Solution: Add the ColorSchemePre autocommand event. vim/vim@60a6836
I have now written a test for the new function and cleaned up linter complaints. Requesting consideration for merging. |
This new API method allows setting the buffer of a window based on the window ID. It complements the existing `nvim_win_get_buf`.
History looks a bit weird. perhaps rebase the latest commit on master? |
@@ -113,7 +113,7 @@ set(NVIM_VERSION_PATCH 2) | |||
set(NVIM_VERSION_PRERELEASE "-dev") # for package maintainers | |||
|
|||
# API level | |||
set(NVIM_API_LEVEL 5) # Bump this after any API change. | |||
set(NVIM_API_LEVEL 6) # Bump this after any API change. |
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.
No need to bump this, 5 is already pre-release. One can always just use the latest level in a PR; if it needs to be bumped, CI (or make functionaltest
locally) will tell you.
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 wasn't fixed. Did so in the merge.
Is the history better now? GitHub shows all those other commits from |
I think you merged instead, which doesn't remove these commits. Reset to |
I followed the instructions, but the history is still messed up. Could it be that I have messed up my git reset --hard 384770556ba02433904baf78f499b9bb48010040 on the |
@HiPhish I force-pushed to your branch. I used
|
@justinmk Thank you. What is the Right Way™ of keeping up to data with git checkout master
git pull upstream master # upstream is the official repository
git checkout my-feature-branch
git rebase master |
@HiPhish No need to Here's my habit:
Could also use the
|
api_set_error(err, | ||
kErrorTypeException, | ||
"Failed to switch to window %d", | ||
window); |
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.
Should also test the failure modes (including the !win || !buf
case above). In the past we've had hidden bugs until we added test cases for failure modes.
(Edit: I'm not sure when Failed to switch to window %
error would happen, it might not be possible to test that.)
It's easy to test the error cases using expect_err()
. See for example:
neovim/test/functional/api/vim_spec.lua
Line 28 in 8fd092f
expect_err('Invalid method: bogus$', |
Example:
expect_err('error message', window, 'set_buf', 99942, 23423)
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 have added tests for invalid window- and buffer ID, but as you said, I have no idea how to make the swap intentionally fail.
This new API method allows setting the buffer of a window based on the window ID. It complements the existing `nvim_win_get_buf`.
bump Anything else that needs to be done? |
Merged after fixing indentation and API level. Thanks @HiPhish ,! |
Besides the "visible" improvements, this release features numerous internal improvements to the UI/screen code and test infrastructure. Numerous patches were merged from Vim, which are not mentioned below. FEATURES: 07ad5d7 clipboard: Support custom VimL functions neovim#9304 725da1f neovim#9401 win/TUI: Improve terminal/console support 7a8dadb neovim#9077 startup: Use $XDG_CONFIG_DIRS/nvim/sysinit.vim if it exists feec926 neovim#9299 support <cmd> mapping in more places 0653ed6 neovim#9028 diff/highlight: Show underline for low-priority CursorLine bddcbbb signs: Add "numhl" argument neovim#9113 05f9c7c clipboard: support Wayland (neovim#9230) 14ae394 neovim#9052 TUI: add support for undercurl and underline color 4fa3492 neovim#9023 man.vim: soft (dynamic) wrap neovim#9023 API: 8b39e4e neovim#6920 API: implement object namespaces b1aaa0a API: Implement nvim_win_set_buf() neovim#9100 8de87c7 neovim#8180 API: virtual text annotations (nvim_buf_set_virtual_text) 2b9fc9a neovim#8660 API: add nvim_buf_is_loaded() API: buf_get_lines, buf_line_count handle unloaded buffers 88f77c2 API: nvim_buf_get_offset_for_line 94841e5 API/UI: neovim#8221 ext_newgrid, ext_hlstate (use line-based rather than char-based updates) UI b5cfac0 neovim#8806 TUI: use BCE again more often, (smoother resizes/scrolling) 77b5e9a neovim#9315 screen: add missing status redraw when redraw_later(CLEAR) was used 5f15788 TUI: clip invalid regions on resize (neovim#8779), fixes neovim#8774 c936ae0 neovim#9193 TUI: improvements for scrolling and clearing f204274 neovim#9143 UI: disable clearing almost everywhere f4b2b66 neovim#9079 TUI: always use safe cursor movement after resize d36afaf neovim#9211 ui_options: also send when starting or from OptionSet 67f80d4 TUI: Avoid reset_cursor_color in old VTE neovim#9191 e55ebae neovim#9021 don't erase screen on `:hi Normal` during startup c5790d9 neovim#8915 TUI: Hint wrapped lines to terminals. FIXES: 231de72 RPC: turn errors from async calls into notifications 907ad92 TUI: Restore terminal title via "title stacking" (neovim#9407) cb76a8a genappimage: Unset $ARGV0 at invocation neovim#9376 b48efd9 neovim#9347 TUI: FreeBSD: Improve support for BSD vt console c16529a TUI: Konsole 18.07.70 supports DECSCUSR (neovim#9364) aec096f os/lang: use the correct LC_NUMERIC also for OS X 5fee0be provider: improve error message (neovim#9344) 3c42d7a TUI: alacritty supports set_cursor_color neovim#9353 7bff9a5 TUI: Alacritty supports DECSCUSR (neovim#9048) 57acfce macOS: infer primary language if $LANG is empty neovim#9345 bc132ae runtime/syntax: Fix highlighting of augroup contents (neovim#9328) 715fdfe neovim#9297 VimL/confirm(): Show dialog even if :silent 799d9c3 clipboard: Prefer xclip (neovim#9302) 6dae777 provider/nodejs: fix npm,yarn detection 16bc1e9 neovim#9218 channel: avoid buffering output when only terminal and no callbacks are active 72fecad neovim#8804 Fix crash in lang_init() on macOS if lang_region = NULL d581398 ruby: detect rbenv shims for other versions (neovim#8733) e568ac7 neovim#9123 third-party/unibilium: Fix parsing of extended capability entries c4c74c3 jobstart(): Fix hang on non-executable cwd neovim#9204 1cf50cb provider/nodejs: Simultaneously query npm and yarn neovim#9054 6c496db undo: Fix infinite loop if undo_read_byte returns EOF neovim#2880 f8f8357 neovim#9034 'swapfile: always show dialog' CHANGES: c236e80 neovim#9024 --embed: wait for UI unless --headless 180b50d neovim#9248 python: 'neovim' module was renamed to 'pynvim' 2000b6a neovim#8589 VimL: Remove legacy aliases "v:errmsg", "v:shell_error", "v:this_session" deb18a0 defaults: background=dark neovim#2894 (neovim#9205) c1187d4 defaults: win: 'shellpipe' for cmd.exe (neovim#8827)
Besides the "visible" improvements, this release features numerous internal improvements to the UI/screen code and test infrastructure. Numerous patches were merged from Vim, which are not mentioned below. FEATURES: 07ad5d7 clipboard: Support custom VimL functions neovim#9304 725da1f neovim#9401 win/TUI: Improve terminal/console support 7a8dadb neovim#9077 startup: Use $XDG_CONFIG_DIRS/nvim/sysinit.vim if it exists feec926 neovim#9299 support <cmd> mapping in more places 0653ed6 neovim#9028 diff/highlight: Show underline for low-priority CursorLine bddcbbb signs: Add "numhl" argument neovim#9113 05f9c7c clipboard: support Wayland (neovim#9230) 14ae394 neovim#9052 TUI: add support for undercurl and underline color 4fa3492 neovim#9023 man.vim: soft (dynamic) wrap neovim#9023 API: 8b39e4e neovim#6920 API: implement object namespaces b1aaa0a API: Implement nvim_win_set_buf() neovim#9100 8de87c7 neovim#8180 API: virtual text annotations (nvim_buf_set_virtual_text) 2b9fc9a neovim#8660 API: add nvim_buf_is_loaded() API: buf_get_lines, buf_line_count handle unloaded buffers 88f77c2 API: nvim_buf_get_offset_for_line 94841e5 API/UI: neovim#8221 ext_newgrid, ext_hlstate (use line-based rather than char-based updates) UI b5cfac0 neovim#8806 TUI: use BCE again more often, (smoother resizes/scrolling) 77b5e9a neovim#9315 screen: add missing status redraw when redraw_later(CLEAR) was used 5f15788 TUI: clip invalid regions on resize (neovim#8779), fixes neovim#8774 c936ae0 neovim#9193 TUI: improvements for scrolling and clearing f204274 neovim#9143 UI: disable clearing almost everywhere f4b2b66 neovim#9079 TUI: always use safe cursor movement after resize d36afaf neovim#9211 ui_options: also send when starting or from OptionSet 67f80d4 TUI: Avoid reset_cursor_color in old VTE neovim#9191 e55ebae neovim#9021 don't erase screen on `:hi Normal` during startup c5790d9 neovim#8915 TUI: Hint wrapped lines to terminals. FIXES: 231de72 RPC: turn errors from async calls into notifications 907ad92 TUI: Restore terminal title via "title stacking" (neovim#9407) cb76a8a genappimage: Unset $ARGV0 at invocation neovim#9376 b48efd9 neovim#9347 TUI: FreeBSD: Improve support for BSD vt console c16529a TUI: Konsole 18.07.70 supports DECSCUSR (neovim#9364) aec096f os/lang: use the correct LC_NUMERIC also for OS X 5fee0be provider: improve error message (neovim#9344) 3c42d7a TUI: alacritty supports set_cursor_color neovim#9353 7bff9a5 TUI: Alacritty supports DECSCUSR (neovim#9048) 57acfce macOS: infer primary language if $LANG is empty neovim#9345 bc132ae runtime/syntax: Fix highlighting of augroup contents (neovim#9328) 715fdfe neovim#9297 VimL/confirm(): Show dialog even if :silent 799d9c3 clipboard: Prefer xclip (neovim#9302) 6dae777 provider/nodejs: fix npm,yarn detection 16bc1e9 neovim#9218 channel: avoid buffering output when only terminal and no callbacks are active 72fecad neovim#8804 Fix crash in lang_init() on macOS if lang_region = NULL d581398 ruby: detect rbenv shims for other versions (neovim#8733) e568ac7 neovim#9123 third-party/unibilium: Fix parsing of extended capability entries c4c74c3 jobstart(): Fix hang on non-executable cwd neovim#9204 1cf50cb provider/nodejs: Simultaneously query npm and yarn neovim#9054 6c496db undo: Fix infinite loop if undo_read_byte returns EOF neovim#2880 f8f8357 neovim#9034 'swapfile: always show dialog' CHANGES: c236e80 neovim#9024 --embed: wait for UI unless --headless 180b50d neovim#9248 python: 'neovim' module was renamed to 'pynvim' 2000b6a neovim#8589 VimL: Remove legacy aliases "v:errmsg", "v:shell_error", "v:this_session" deb18a0 defaults: background=dark neovim#2894 (neovim#9205) c1187d4 defaults: win: 'shellpipe' for cmd.exe (neovim#8827)
The implementation is extremely crude and certainly missing tons of cleanup, but it works on paper.