Re: Problematic doautocmd behavior

2018-04-15 Fir de Conversatie Bram Moolenaar

Ivan Brennan wrote:

> When your plugin wants to provide an event the user can hook into, it could 
> broadcast a User autocommand:
> 
> function! foo#do_it()
>   call s:do_thing()
>   doautocmd User FooDidIt
> endfunction
> 
> If the user's vimrc contains,
> 
> augroup MyGroup
>   autocmd!
>   autocmd User FooDidIt call MyHandler()
> augroup END
> 
> then MyHandler() will be called any time foo#do_it() runs.
> 
> If the user *does not* set up any such autocommand, however, any time 
> foo#do_it() runs, Vim displays "No matching autocommands".
> 
> You could suppress these messages by prefixing doautocmd with "silent", but 
> that would also suppress any messages a handler tries to display. So most 
> plugins wrap doautocmd in a conditional:
> 
> function! foo#do_it()
>   call s:do_thing()
>   if exists('#User#FooThing')
> doautocmd User FooThing
>   endif
> endfunction
> 
> When providing an event the user can hook into, I'd think it's better to 
> decouple the plugin from any knowledge/concern about what, if anything, has 
> been set up to listen for the event. But we're forced to run this check, 
> given how doautocmd works.
> 
> More importantly, the exists() check is inaccurate in some cases. For 
> example, the following are two autocommand definitions are equivalent,
> 
> autocmd User FooBar,FooBaz call MyHandler()
> autocmd User Foo{Bar,Baz}  call MyHandler()
> 
> but exists('#User#FooBar') will return true for the first and false for the 
> second.
> 
> I can see the usefulness of displaying No matching autocommands for debugging 
> purposes, but beyond that it seems like bad behavior.
> 
> Am I thinking about this the wrong way?

A simple solution, which does not require a change in Vim itself, is to
define one dummy autocommand yourself:

 augroup MyGroup
   autocmd!
   autocmd User FooDidIt "
 augroup END

 function! foo#do_it()
   call s:do_thing()
   doautocmd User FooDidIt
 endfunction

-- 
hundred-and-one symptoms of being an internet addict:
187. You promise yourself that you'll only stay online for another
 15 minutes...at least once every hour.

 /// Bram Moolenaar -- b...@moolenaar.net -- http://www.Moolenaar.net   \\\
///sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\
\\\  an exciting new programming language -- http://www.Zimbu.org///
 \\\help me help AIDS victims -- http://ICCF-Holland.org///

-- 
-- 
You received this message from the "vim_dev" 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_dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to vim_dev+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: Problematic doautocmd behavior

2018-04-14 Fir de Conversatie Christian Brabandt

On Sa, 14 Apr 2018, Ivan Brennan wrote:

> I'm curious how difficult it would be to change the implementation of 
> doautocmd, but since I'm not about to try myself I won't dwell on it any 
> further :)

That should be rather easy. Something like this I believe:


diff --git a/src/ex_docmd.c b/src/ex_docmd.c
index 046ef3cf5..0c435f562 100644
--- a/src/ex_docmd.c
+++ b/src/ex_docmd.c
@@ -5504,8 +5504,11 @@ ex_doautocmd(exarg_T *eap)
 char_u *arg = eap->arg;
 intcall_do_modelines = check_nomodeline();
 intdid_aucmd;
+int do_msg = TRUE;

-(void)do_doautocmd(arg, TRUE, _aucmd);
+/* do not give warning messages for mon-existent auto commands */
+do_msg = STRNCMP(arg, "User", 4);
+(void)do_doautocmd(arg, do_msg, _aucmd);
 /* Only when there is no . */
 if (call_do_modelines && did_aucmd)
do_modelines(0);



Best,
Christian
-- 
Ein alter gutmütiger Examinator sagte einem Schüler ins Ohr:
Etiam nihil didicisti,
und lässt ihn für gut hingehen.
-- Goethe, Maximen und Reflektionen, Nr. 364

-- 
-- 
You received this message from the "vim_dev" 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_dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to vim_dev+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: Problematic doautocmd behavior

2018-04-14 Fir de Conversatie Ivan Brennan
That's a good point. Given the choice between:

  a) unintentionally silencing messages that a hook tried to display

and

  b) failing to trigger an autocommand because it was defined using a pattern 
construct that exists() fails to recognize

I'll opt for (a).

I'm curious how difficult it would be to change the implementation of 
doautocmd, but since I'm not about to try myself I won't dwell on it any 
further :)

-- 
-- 
You received this message from the "vim_dev" 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_dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to vim_dev+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: Problematic doautocmd behavior

2018-04-14 Fir de Conversatie Ingo Karkat
On 14-Apr-2018 20:39 +0200, Christian Brabandt wrote: 

> 
> On Sa, 14 Apr 2018, Ivan Brennan wrote:
> 
>> When your plugin wants to provide an event the user can hook into, it could 
>> broadcast a User autocommand:
>>
>> function! foo#do_it()
>>   call s:do_thing()
>>   doautocmd User FooDidIt
>> endfunction
>>
>> If the user's vimrc contains,
>>
>> augroup MyGroup
>>   autocmd!
>>   autocmd User FooDidIt call MyHandler()
>> augroup END
>>
>> then MyHandler() will be called any time foo#do_it() runs.
>>
>> If the user *does not* set up any such autocommand, however, any time 
>> foo#do_it() runs, Vim displays "No matching autocommands".
>>
>> You could suppress these messages by prefixing doautocmd with "silent", but 
>> that would also suppress any messages a handler tries to display. So most 
>> plugins wrap doautocmd in a conditional:
>>
>> function! foo#do_it()
>>   call s:do_thing()
>>   if exists('#User#FooThing')
>> doautocmd User FooThing
>>   endif
>> endfunction
>>
>> When providing an event the user can hook into, I'd think it's better to 
>> decouple the plugin from any knowledge/concern about what, if anything, has 
>> been set up to listen for the event. But we're forced to run this check, 
>> given how doautocmd works.
>>
>> More importantly, the exists() check is inaccurate in some cases. For 
>> example, the following are two autocommand definitions are equivalent,
>>
>> autocmd User FooBar,FooBaz call MyHandler()
>> autocmd User Foo{Bar,Baz}  call MyHandler()
>>
>> but exists('#User#FooBar') will return true for the first and false for the 
>> second.
>>
>> I can see the usefulness of displaying No matching autocommands for 
>> debugging purposes, but beyond that it seems like bad behavior.
>>
>> Am I thinking about this the wrong way?
> 
> You are probably right. However most plugins I have seen usually do not 
> bother and use `:sil doautocmd User ...` So perhaps nothing to worry 
> about?

I agree to both of you. The behavior is unfortunate, and most plugins
(including my own) seem to use :silent doautocmd User. Usually, hooks do
not need to print any messages to users, and if they really need to,
they could use :unsilent, right? Too bad this wasn't better thought
through from the beginning, but I also wonder whether changing this now
would make a difference.

-- regards, ingo

-- 
-- 
You received this message from the "vim_dev" 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_dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to vim_dev+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: Problematic doautocmd behavior

2018-04-14 Fir de Conversatie Christian Brabandt

On Sa, 14 Apr 2018, Ivan Brennan wrote:

> When your plugin wants to provide an event the user can hook into, it could 
> broadcast a User autocommand:
> 
> function! foo#do_it()
>   call s:do_thing()
>   doautocmd User FooDidIt
> endfunction
> 
> If the user's vimrc contains,
> 
> augroup MyGroup
>   autocmd!
>   autocmd User FooDidIt call MyHandler()
> augroup END
> 
> then MyHandler() will be called any time foo#do_it() runs.
> 
> If the user *does not* set up any such autocommand, however, any time 
> foo#do_it() runs, Vim displays "No matching autocommands".
> 
> You could suppress these messages by prefixing doautocmd with "silent", but 
> that would also suppress any messages a handler tries to display. So most 
> plugins wrap doautocmd in a conditional:
> 
> function! foo#do_it()
>   call s:do_thing()
>   if exists('#User#FooThing')
> doautocmd User FooThing
>   endif
> endfunction
> 
> When providing an event the user can hook into, I'd think it's better to 
> decouple the plugin from any knowledge/concern about what, if anything, has 
> been set up to listen for the event. But we're forced to run this check, 
> given how doautocmd works.
> 
> More importantly, the exists() check is inaccurate in some cases. For 
> example, the following are two autocommand definitions are equivalent,
> 
> autocmd User FooBar,FooBaz call MyHandler()
> autocmd User Foo{Bar,Baz}  call MyHandler()
> 
> but exists('#User#FooBar') will return true for the first and false for the 
> second.
> 
> I can see the usefulness of displaying No matching autocommands for debugging 
> purposes, but beyond that it seems like bad behavior.
> 
> Am I thinking about this the wrong way?

You are probably right. However most plugins I have seen usually do not 
bother and use `:sil doautocmd User ...` So perhaps nothing to worry 
about?


Best,
Christian
-- 
Lnull, Norma:
  weibliche Sagengestalt aus Niveausibirsk und Levelkusen spiegelte
  sich gerne in der Meeresoberfläche

-- 
-- 
You received this message from the "vim_dev" 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_dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to vim_dev+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.