0

I'm writing a function to automate some task.

I did this:

function InitTTbuffer()
    " Split file and find the first imap
    :exe "normal \<C-w>\<C-s>/imap\<CR>"

    "resize window to 9 lines (with z9>CR>) then scroll (zt)
    :exe "normal z9\<CR>zt"

    "and then return to my file and execute my mapping "se"
    :exe "normal \<C-w>\<DOWN>se"

endfunction

It works fine but I read here that the OP must not use <CR> nor :exe in his case.
I tried to remove the :exe, changing

:exe "normal z9\<CR>zt"

in:

normal z9
normal zt

but now the z9 and zt aren't be executed.

Then, my question:

  • In which way is my case different from the question in the link?
  • And why my code now don't works?
3
  • according to the help, zN requires the <CR> so you must use exe ":norm zt\<cr>" Jul 12, 2023 at 13:03
  • @ChristianBrabandt :normal! zt works perfectly. The doc is about z9<cr> or z1<cr>. So yes, in that case, it must be :exe "normal! z9\<cr>" Jul 12, 2023 at 13:27
  • 1
    yes, it's not required for zt. But if you want to chain them together, you'll need again the :exe call. Jul 12, 2023 at 13:32

2 Answers 2

2

According to the help at :h z the zN command requires the <CR>, so in that case you must use :exe ":norm! z<nr>\<cr>" (replace <nr> by an actual number).

Alternatively we can use normal z<nr>^M where ^M is inserted by pressing CTRL-V CTRL-M.
The colon (:) at the start of the row is unnecessary.

So everything okay, except that I would always recommend to use :norm! (with bang attribute, to be independent on what the user has actual mapped).

4
  • Thanks! I understand and I proved that there's no difference between :normal and normal. But there's another question, now: there's a way better than the other, in terms of performance, speed, etc.?
    – Antonio
    Jul 12, 2023 at 13:26
  • @Antonio you won't see any differences. However if your trigger a lot of redraw, it may have consequences. BTW, I don't know which would be better between :exe "normal! z9\<cr>" and :resize 9. They seem to do the same things. (I'm not sure though) Jul 12, 2023 at 13:31
  • 1
    I don't think the : is actually required, but I tend to write it, to make it explicit 🤷‍♂️ Jul 12, 2023 at 13:33
  • @LucHermitte, I didn't know the :resize command. Thanks!
    – Antonio
    Jul 13, 2023 at 14:33
2

I would restrict the use of :help :normal to where there is no better option:

function InitTTbuffer()
    " show current buffer in new 9 lines window and search for `imap`
    9split +/imap

    " scroll current line to top
    normal! zt

    " return to previous window
    wincmd p

    " execute se normal mode command
    normal! se
endfunction

The function is much more readable that way.

See :help :split and :help :wincmd.

--- EDIT ---

This line:

9split +/imap

could also be written:

9split | /imap

or even:

9split
/imap

The differences are subtle and may or may not always matter:

  • :help +cmd provides a traditional and intuitive way to "open file X at line Y". I used it here because I use it often.
  • :help :| can be used to chain several commands. It would work just as well, here, but it has a number of "issues". One is that the RHS of a | won't be executed if the LHS fails, which might be useful in some cases and surprising in others, for example. Also, especially in scenarios involving windows, the order of execution can be very surprising.
  • The last one is the simplest, with an implicit <CR> between the commands.

Off the three, I consider the 1st and 3rd to be the safest and least surprising. I prefer to use the 2nd when I am interested in its peculiarities.

1
  • Great! But could you explain the difference between 9split +/imap and 9split | /imap?
    – Antonio
    Jul 13, 2023 at 15:55

Your Answer

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

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