Thursday, August 29, 2019

Re: Mapping erases search count message

On 2019-08-29, Christian Brabandt wrote:
> On Do, 29 Aug 2019, Christian Brabandt wrote:
>
> >
> > On Di, 27 Aug 2019, Gary Johnson wrote:
> >
> > > On 2019-08-28, Christian Brabandt wrote:
> > > > On Di, 27 Aug 2019, Gary Johnson wrote:
> > > >
> > > > > I just tried exposing the search count message by removing 'S' from
> > > > > 'shortmess', but I couldn't see it. I discovered that it is hidden,
> > > > > erased and/or not updated by a couple of my mappings.
> > > > >
> > > > > nnoremap <silent> n nzv:call AdjCursor()<CR>
> > > > > nnoremap <silent> N Nzv:call AdjCursor()<CR>
> > > > >
> > > > > Here is a simple experiment that demonstrates the problem. Create
> > > > > a file, test.vim, that contains the following.
> > > > >
> > > > > set shortmess-=S
> > > > > nnoremap <silent> n n
> > > > > help map.txt
> > > > >
> > > > > Open a standard-sized, 80x24 terminal, and in it run
> > > > >
> > > > > $ vim -N -u NONE -i NONE -S test.vim
> > > > >
> > > > > Then search for "command":
> > > > >
> > > > > /command
> > > > >
> > > > > After hitting Enter, the cursor will be at the start of "commands"
> > > > > on line 7 and the command line will contain this:
> > > > >
> > > > > /command [1/>99]
> > > > >
> > > > > After hitting 'n', the cursor advances to line 13 and the command
> > > > > line stays the same, even showing "[1/>99]" when it should be
> > > > > showing "[2/>99]".
> > > > >
> > > > > Another 'n' advances the cursor to line 17, the screen scrolls
> > > > > up so that that line is at the bottom of the window, and the command
> > > > > line is empty--no search count message at all.
> > > > >
> > > > > I would think that <silent> would prevent the mapping from
> > > > > disturbing the command line, in which case this is a bug.
> > > > >
> > > > > If it's not a bug, then is there some way of defining a mapping that
> > > > > does not interfere with the search count message, or some way of
> > > > > restoring that message at the end of a mapping?
> > > >
> > > > Is that with patch 8.1.1288 included?
> > >
> > > Sorry, I forgot to include the version information. Yes, I used the
> > > latest version, 8.1.1933.
> >
> > Hm, I need to investigate.
>
> I see what is happening. A mapping with the `<silent>` flag will set the
> internal variable cmd_silent to prevent it from being output the command
> line. So what your mapping does is it acts like 'n' without outputting
> anything on the command line.
>
> But this is not what you want. You want the default behaviour of n,
> which does output the command to search + the new search index feature.
>
> (See the difference on the commandline between a plain `n` and a n
> mapped with `nnoremap <silent> n n`).
>
> So the obvious fix would be to remove the `<silent>` command. While this
> fixes your minimal test case, it most likely is no fix for your actual
> issue, that calling the AdjCursor() function will be output in the
> command line in addition (possibly overwriting the command line).
>
> What might work (depending on the complexity of your AdjCursor()
> function) is to use an expression mapping that simply returns 'n' after
> having done whatever action it needs to be doing. However, this might be
> a bit difficult since you want this to happen after the cursor has been
> placed.
>
> Another alternative might be a mapping like this:
>
> nmap n nzv
> nnoremap <silent> zv zv:call AdjCursor()<cr>

Thanks for looking further into this, Christian.

I don't understand how that first mapping in your alternative
mappings works. I thought that using nmap (not nnoremap) to map
n to a rhs including n would cause an infinite recursion, but it
doesn't.

Those mappings solve part of the problem. That is, if AdjCursor()
is an empty function, they work fine--the search count message is
always visible. But if AdjCursor() is the actual function (which
scrolls the window when needed to keep the cursor at least two lines
from the top and bottom), then whenever the window is scrolled, the
message disappears.

In fact, removing all the mappings and just executing Ctrl-E or
Ctrl-Y to scroll the window after a search erases the search count
message. I think that's a bug. I can see no reason why scrolling
should erase that message unless scrolling moves the cursor.

Further, certain motion commands such as j, k and gg _don't_ erase
the search count message, even though it would make sense for them
to do so. It's weird to jump from the bottom of a buffer to the top
with gg and still see the last search count message in the command
line.

The purpose of AdjCursor () is to scroll the window after a search
moves the cursor near the top or bottom of the window so as to
provide at least two lines of context around the cursor. (It should
really be named AdjWindow().) It behaves like scrolloff=2, but only
after certain commands. I don't want 'scrolloff' on all the time.

That gave me an idea, a different solution to the problem:
temporarily enable 'scrolloff' instead of scrolling the window.
Here is what I just came up with and it seems to work well.

nmap <silent> n :call ScrolloffCmd('n')<cr>
nmap <silent> N :call ScrolloffCmd('N')<cr>
function! ScrolloffCmd(cmd)
set scrolloff=2
try
exe 'normal!' a:cmd
catch
echohl ErrorMsg
echomsg matchstr(v:exception, ':\zs.*')
echohl NONE
endtry
set scrolloff=0
endfunction

Regards,
Gary

--
--
You received this message from the "vim_use" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php

---
You received this message because you are subscribed to the Google Groups "vim_use" group.
To unsubscribe from this group and stop receiving emails from it, send an email to vim_use+unsubscribe@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/vim_use/20190829205233.GB27112%40phoenix.

No comments: