3

I am trying to fix a bug that goes like this:

  • [cursor in ordinary window] open preview window and move to it
  • [cursor in preview window] close preview window
  • expected: cursor moves to where it was in step 1
  • actual: cursor ends up in another window

I always thought that when you're in a window and you close it, whether or not it's the preview window, the cursor moves to whichever window it was in before that window. Is that correct? If not, how does Vim decide which window to put the cursor in?

It doesn't seem to be related to the window's alternate file, nor to 'splitbelow' and 'splitright'.

It does seem to be related to whether the preview window is opened with a "position modifier", e.g. :bo pedit x vs :pedit x. The position modifier seems to cause the unexpected behaviour.

1
  • 1
    Great question; I've had this issue with coqtail, too, even just when switching tabs.
    – D. Ben Knoble
    Mar 15, 2021 at 20:44

1 Answer 1

3

When the cursor is in the preview window, and the preview window is closed, vim follows the same logic to re-place the cursor as for any other window being closed.

I always thought that when you're in a window and you close it, whether or not it's the preview window, the cursor moves to whichever window it was in before that window.

Actually, this isn't true. You can try it with regular splits. The "previous" window is not considered.

The strategy vim uses is as follows, assuming a single tab page;

  1. Try the the window "that received the screen space."

    a. In the simple case, this is the "other part" of a split tuple of windows. The exact direction does depend somewhat on splitbelow and splitright.

    b. If you're crossing a frame boundary (e.g., when there's a horizontal split inside a vertical split), then it's no longer the other "split," but the other "frame." Inside that other frame, we just choose the left-upper window.

  2. If the window in 1. is a preview window or holds a quickfix buffer, then go to the next window, repeating 2. as many times as necessary.

  3. If this fails, just use window from 1 (even if it's a preview or quickfix).

Note that it is allowed that autocmds changes the window when this is happening.

Preview win and previous win

An interesting quirk about the preview window is that it becomes the previous window upon creation. For example, if you do :pedit x|wincmd p you'll wind up in the preview window. Another side-effect of this is :pedit x|wincmd z will leave the previous window in an invalid state.

5
  • 1
    Thanks for this detailed answer! It's more involved than I expected. I have also found it depends on whether a "position command" is in the mix, e.g. :bo pedit x|wincmd z. Mar 16, 2021 at 12:11
  • 1
    @AndyStewart can you give a full example of :bo making a difference, as I can add this detail to the answer?
    – Mass
    Mar 16, 2021 at 16:54
  • I've updated the question; I hope that's a sufficient example. Mar 17, 2021 at 10:26
  • 1
    @AndyStewart I think I decoded it. I dug into the code a bit more and realized that my answer only covered the most simple cases where the preview window is an ordinary split of some other stack (no perpendiculars). When the "other window in the split" is actually a frame (i.e., consisting of a perpendicular split direction), then vim merely chooses the top left window of that frame!
    – Mass
    Mar 19, 2021 at 0:26
  • The plot thickens :) I think that explains why using :bo pedit x | wincmd P | pclose differs from :pedit x | wincmd P | pclose: :bo opens a window across the full width of the Vim window, spanning any vertical splits / frames. Mar 19, 2021 at 16:13

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.