1

Is there a way for clicking on a Vim window to focus that window if inactive (without moving the cursor), then move the cursor if the window is already active?

Here's what I've got so far:

function IsWinFocused()
    return getmousepos().winid==win_getid()
endfunction
noremap <expr> <LeftMouse> IsWinFocused() ? '<LeftMouse>' : '<LeftMouse>`m'
augroup leftMouse
    autocmd!
    au BufLeave * mark m 
augroup end

Which leaves a marker behind as you leave a window, then comes back to it after rejoining the window.

But this isn't ideal as you have to have unfocused the window since opening it in order for focusing it to work properly, and if that's not the case it could yeet you into the depths of a file if marker m was in prior use.

Also I'm not a huge fan of seeing the window jump to where I clicked and back every time I focus a window

Edit: using Neovim wrapped in Nvy on Windows 11

5
  • The mousefocus option could be interesting for you. Could you tell us more about your use case such that we can propose you the correction solution? May 25 at 7:04
  • @VivianDeSmedt I use scrolloff to center my cursor in the screen, and I don't want the screen to jump around when I use my mouse to focus a window
    – thirstyice
    May 25 at 8:06
  • Does this answer your question? Focus-follows-mouse in Neovim? May 25 at 10:52
  • 1
    It tells me that mousefocus is not the answer, but it doesn't tell me what is the answer. I think I was able to figure out a solution, see my answer below.
    – thirstyice
    May 25 at 19:03
  • I agree :-) We use that formulation to link questions in order to not spread the answers. But with your answer we should probably link it the other way around ;-) May 25 at 20:10

2 Answers 2

1

Ok, I think I've figured it out. Here's the mappings I've come up with:

noremap <expr> <LeftMouse> getmousepos().winid==win_getid() ? '<LeftMouse>' : '<Cmd>call win_gotoid(getmousepos().winid)<CR>'
noremap! <expr> <LeftMouse> getmousepos().winid==win_getid() ? '<LeftMouse>' : '<Cmd>call win_gotoid(getmousepos().winid)<CR>'

It checks if the focused window is the one under the mouse, and if so it left clicks as normal. If the window under the mouse is not the one that is focused, it calls the function to change the the current window to the window under the mouse. This couldn't be done with a normal <exec> command because you can't change the cursor position from within the <exec>. It had to be called using <Cmd>.

2
  • If it works for you it would be good if you could accept it using the v button next to the arrows voting buttons. It allow the question to rest (you'll have wait two days for that) May 25 at 20:13
  • 1
    I will, but it won't let me until tomorrow
    – thirstyice
    May 26 at 0:53
1

You can set the option mousefocus

:set mousefocus

When you move the cursor on the window the window is activated but the cursor is not changed (not exactly what you ask but close).

You can use the mouse wheel to scroll the window.

Remark: It seems that it doesn't work yet in nvim-qt see the following answer for more details.

Remark: Although mousefocus is not working mousescroll is. This mean that you should be able to scroll your buffer by using the scroll button of your mouse when you move the mouse pointer over the corresponding window (again not what you ask but a consolation gift)

6
  • 1
    This seems like the way to go, but it doesn't do what it says it does. Will add my setup to the question
    – thirstyice
    May 25 at 7:51
  • Thanks for the feedback. Could you elaborate why you believe: it doesn't do what it says it does? May 25 at 9:17
  • As far as I can tell, it has no effect
    – thirstyice
    May 25 at 9:30
  • Did you tried with gVim -u NONE -i NONE? May 25 at 9:45
  • 1
    I'm not using gVim, I'm using Neovim with Nvy
    – thirstyice
    May 25 at 9:49

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.