0

I want to go to the search result in the right-window, identified after performing a /urllib search in the left window.

Pressing n\N doesn't proceed to search results in other windows. How can I proceed to search results in other windows?

enter image description here

Shuzheng
  • 1,235
  • 8
  • 21

2 Answers2

1

If you really want to do this...

function! CycleWindowsSearch(direction) abort   
    " set forward to set variables accordingly
    let forward = a:direction
    if ! v:searchforward
        let forward = forward ? '0' : '1'
    endif
    " search forward / backward
    let searchflags = forward ? 'W' : 'Wb'
    " next or previous window
    let winmove = forward ? 'w' : 'W'
    " cursor at top or bottom
    let curmove = forward ? '1' : '$'

    " save first window ID
    let firstwin=winnr()
    " try to search
    if ! search(@/, searchflags)
        " move to next (or previous) window
        execute('wincmd ' . winmove)
        " save cursor position
        let savepos = getcurpos()
        " move to top (or bottom)
        call cursor(curmove, curmove)
        " redo for each window untill back to first
        while ! search(@/, searchflags) && firstwin != winnr()
            call setpos('.', savepos)
            execute('wincmd ' . winmove)
            call cursor(curmove, curmove)
        endwhile
    endif
endfunction

nnoremap <silent> n :call CycleWindowsSearch('1')<cr>
nnoremap <silent> N :call CycleWindowsSearch('0')<cr>

Update:

  • go to first (or last) match of buffer when switching window (not depending on cursor position)
  • skips windows where pattern is not found, without losing their position
  • courtesy to @filbranden for all his suggestions

Caveat:

  • the "hit bottom" or "hit top" message is obliterated.
  • pressing 'n' when a pattern is not found anywhere (e.g after it was replaced with something else) will move the cursor to top (or bottom)
Biggybi
  • 2,740
  • 9
  • 29
  • Why \%#? Doesn't that match only at the cursor position? Why force \c? Also, N is not always backward, when the original search was performed with ? instead of /, then N is actually forward... – filbranden May 10 '20 at 02:33
  • 1
    Yeah... At least I tried. Will update it later with your comment in mind.If you can tell me how I can check whether we're in / or ?, I'll take it, thanks! – Biggybi May 10 '20 at 06:31
  • 1
    I recently got into a rabbit hole like this too. This is yet another case where the Vimscript solution will be super hard to get right, with all corner cases... And the problem is so trivial that it's almost a non-issue at all (I mean, just change windows yourself, right?) Anyways, if you want to go down this route, I hope at least you get something out of it, should be an interesting learning experience. – filbranden May 10 '20 at 06:40
  • See v:searchforward for the direction of the last search – filbranden May 10 '20 at 06:41
  • 1
    I think I'd also recommend fully implementing this using the search() function, not using the normal!s. Remove the 'n' flag so it does move the cursor. If it doesn't find it, move to the next window and repeat the same(?) search command. Instead of having two branches, simply store the flags in a variable and set it to 'b' or '' depending on which way you're going. – filbranden May 10 '20 at 06:44
  • One interesting corner case is when the next window doesn't have any matches for the pattern... Should you keep rotating windows then? How do you know you've been through all windows and back to the first one? What if you have a single window on the screen? – filbranden May 10 '20 at 06:46
  • Also... When you move to the next window, should you start the search at the cursor position, or at the top of the buffer? (So that you actually cycle through all matches in all windows?) – filbranden May 10 '20 at 06:47
  • 1
    A lot to answer here. First, I indeed mainly implemented this for personal training, but I still want it to work fine. This implementation does not seem to affect the default behavior when there's only one window (which is good). I expected you to mention corner cases (thanks for that). This function cycles windows even if they don't match, that's a flaw. I think it should skip them, and focus the first match if there's one (I may have to gg or G the window then). Thanks for your comments, as I mentioned I'll update my answer later when I have enough time to work on it. – Biggybi May 10 '20 at 07:01
  • 1
    @filbranden It's done! I think it's pretty consistent now, and less complex than I feared. – Biggybi May 10 '20 at 15:57
  • Very nice! Thanks for taking the time. One nitpick, instead of "direction" with "n" or "N", use something like "forward" using 1 or 0, then you can simplify to curmove = forward ? '1' : '$'. I'd also make the argument a boolean (1 or 0) though I'd keep that one with a different name, maybe keep using a:direction for that one, use 1 for "same direction" (n) and 0 for opposite direction (N). Yeah it doesn't look that bad at all! – filbranden May 10 '20 at 16:07
  • Good call, I'll make it a boolean! – Biggybi May 10 '20 at 16:34
0

As @D. Ben Knoble said in the comments, you have to change focus to the new window, for example <c-w>w, if there are only two windows open. Then hit 'n'.

If this is an issue you frequently encounter, consider creating a mapping. In this case, to make <c-s> the way to search in the new window you could add to your .vimrc the following.

nnoremap <c-s> <c-w>wn
D. Ben Knoble
  • 26,070
  • 3
  • 29
  • 65