Monday, November 21, 2011

Re: In script always search from start of buffer

On 21/11/11 12:22, porphyry5 wrote:
> On Sun, Nov 20, 2011 at 1:25 PM, Gary Johnson-4 [via VIM]
> <[hidden email] </user/SendEmail.jtp?type=node&node=5010270&i=0>> wrote:
>
> > On 2011-11-20, porphyry5 wrote:
> >> In a script, how can I get repeated searches always to begin at the
> start
> >> of
> >> the buffer?
> >> If I precede the search with gg or :cursor(1, 1) I get E492, with 1G I
> >> get
> >> E464.
> >>
> >> :map p$ ggdd:while @" != ""<CR>:b#<CR>:cursor (1, 1)<CR>:silent!
> >> /^R"<CR>0i$<Space><Esc>:b#<CR>dd:endwhile
> >
> > I haven't looked closely at your mapping, but to use a normal-mode
> > command such as gg in a script, that is, as an ex command, you must
> > precede it with ":normal", as
> >
> > :normal gg
> >
> > Similarly, to use a function as an ex command, you must precede it
> > with ":call", as
> >
> > :call cursor(1, 1)
> >
> > See
> >
> > :help :normal
> > :help :call
> >
> > Another way to move the cursor to the first line of the buffer is to
> > simply put the number 1 on a line by itself, or in a mapping like
> > yours, as ":1<CR>".
> >
> > HTH,
> > Gary
> >
>
> It certainly does help, thank you, particularly with reference to
> :help :normal, because it seems that sometimes a normal-mode command
> works as-is, other times it doesn't. I originally wrote the script as
>
> :map p$ ggdd:while @" != ""<CR>:b#<CR>gg:silent!
> /^R"<CR>0i$<Space><Esc>:b#<CR>dd:endwhile
>
> in which the first gg works, the second gg fails.

If you type

:while @" != ""

followed by Return, you will notice that Vim does not go back to Normal
mode: it presents you with a new, empty command-line already prefixed by
a colon. This is because a :while statement cannot be executed as long
as everything until and including the :endwhile isn't known. The :b#
above is OK in this context (a second colon, or even a string of many
colons, at the start of an ex-command, changes nothing), but the
following gg is still interpreted in that "implicit command-line mode",
and since there is no ":gg:silent" ex-command, you get an error. That
error invalidates the whole "incomplete complex command" (started by
:while not yet followed by :endwhile), Vim discards it, and I think the
exception propagates (making Vim discard the whole mapping) until it is
ready to read the next command at the keyboard.

OTOH, if you type

:if 0

you will be presented by empty lines in the same way, and if you type
nonsense in them, there will be no error. Further :if's, :while's, etc.
will cause additional indentation, and when you come back to indent
level zero with the _matching_ :endif (with no matching :else or
:elseif) Vim will come back to Normal mode, do nothing, and still give
no error for any intervening "nonsense line", because they were on the
"false path" of the :if.

I find it less confusing, when typing at the command-line (not in a
script) to type complex commands (:while, :if, etc.) all on one line
until their :endwhile, :endif, etc., separating intervening commands
with bars, and taking care that some commands take the | as part of
their arguments: such commands (listed under :help :bar) need to be
wrapped in :execute if they are to be part of such a set of concatenated
commands other than at the end.

Doing it this way (on one line) allows me to come back if, before
hitting <Enter>, I notice that I'm made a typo several bars before in
the line.


Best regards,
Tony.
--
No animal should ever jump on the dining room furniture unless
absolutely certain he can hold his own in conversation.
-- Fran Lebowitz

--
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

No comments: