Account Options

  1. Sign in
The old Google Groups will be going away soon, but your browser is incompatible with the new version.
Google Groups Home
« Groups Home
Message from discussion Does b:undo_ftplugin actually work?
The group you are posting to is a Usenet group. Messages posted to this group will make your email address visible to anyone on the Internet.
Your reply message has not been sent.
Your post was successful
 
From:
To:
Cc:
Followup To:
Add Cc | Add Followup-to | Edit Subject
Subject:
Validation:
For verification purposes please type the characters you see in the picture below or the numbers you hear by clicking the accessibility icon. Listen and type the numbers you hear
 
Bram Moolenaar  
View profile  
 More options Nov 15 2012, 4:32 pm
From: Bram Moolenaar <B...@Moolenaar.net>
Date: Thu, 15 Nov 2012 22:32:08 +0100
Local: Thurs, Nov 15 2012 4:32 pm
Subject: Re: Does b:undo_ftplugin actually work?

Christian Brabandt wrote:
> On Do, 27 Sep 2012, Gary Johnson wrote:

> > On 2012-09-27, ZyX wrote:
> > > , 28 2012 ., 8:04:05 UTC+4 Gary Johnson :
> > > > I was working on some code that set b:undo_ftplugin, but it didn't
> > > > have any effect when I set a new filetype.  I copied
> > > > $VIMRUNTIME/ftplugin.vim to ~/.vim and instrumented the section that
> > > > is supposed to execute b:undo_ftplugin.

> > > >       func! s:LoadFTPlugin()
> > > >         echo "In s:LoadFTPlugin()" | sleep 2
> > > >         echo "b:undo_ftplugin is" b:undo_ftplugin | sleep 2
> > > You should've put this line after the next one (or, better, remove
> > > it as absense of the next message will indicate absence of
> > > b:undo_ftplugin definition). And use ":echom", not ":echo |
> > > sleep", then all messages will be seen when you do ":messages"
> > > >         if exists("b:undo_ftplugin")
> > > >           echo "b:undo_ftplugin exists" | sleep 2
> > > >           exe b:undo_ftplugin
> > > >           unlet! b:undo_ftplugin b:did_ftplugin
> > > >         endif

> > > > Whenever I open a new file for which Vim can detect the filetype, or
> > > > :edit some file, I always get the following errors.
> > > b:undo_ftplugin is defined in filetype plugins. What else do you
> > > expect? When opening new file and doing :edit buffer scope is
> > > clean and filetype plugins are loaded by s:LoadFTPlugin function
> > > *after* you test for b:undo_ftplugin. You should have used "set
> > > filetype=new_filetype" on *existing* buffer to trigger desired
> > > behavior.

> > > >     Error detected while processing function <SNR>5_LoadFTPlugin:
> > > >     line    2:
> > > >     E121: Undefined variable: b:undo_ftplugin
> > > >     E15: Invalid expression: b:undo_ftplugin | sleep 2

> > > > That is even after I execute

> > > >     :echo b:undo_ftplugin

> > > > and verify that it is set correctly according to the new filetype.
> > > Don't use :edit. It wipes the buffer.

> > > > It seems that b:undo_ftplugin does not exist in the environment in
> > > > which s:LoadFTPlugin() is executed.  Does setting b:undo_ftplugin as
> > > > most current ftplugin scripts do actually do anything?
> > > They do. Use "set filetype=new_filetype".

> > Thanks for the reply, but I see that I didn't explain the problem
> > very well.  Also, some of my experiments created new buffers instead
> > of replacing the contents of existing buffers with new filetypes, so
> > I wasn't replicating the actual problem conditions.

> > Let me try again.

> > The actual problem is that I would like to set 'indentexpr' for
> > buffers with no 'filetype' so that I get indenting behavior that I
> > think might be useful when just opening Vim and typing notes.  To
> > that end I put the following in my ~/.vimrc.

> >     au BufWinEnter * if &ft == "" || &ft == "text"
> >          \ |     setlocal indentexpr=indent(prevnonblank(v:lnum-1))
> >          \ |     setlocal indentkeys-=o
> >          \ |     let b:undo_ftplugin = "setl inde< indk<"
> >          \ | endif

> > When I start vim and execute

> >     :echo b:undo_ftplugin

> > I see

> >     setl inde< indk<

> > as expected.  Further, ":ls" shows

> >   1 %a   "[No Name]"                    line 1

> > Now, if I open a C file, I expect to have 'indentexpr' empty, either
> > because the C file is opened in a new buffer or because the C file
> > was opened in the same buffer and the b:undo_ftplugin was executed.
> > However, after executing

> >     :e foo.c
> >     :set indentexpr?

> > I see

> >       indentexpr=indent(prevnonblank(v:lnum-1))

> > and ":ls" shows

> >       1 %a   "foo.c"                        line 1

> > I did take your advice about using echom and instrumented
> > ftplugin.vim differently and verified that when it was executed by
> > the 'filetype' change to "c", b:undo_ftplugin did not exist.

> > If ":edit wipes the buffer" as you say, so that b:undo_ftplugin is
> > deleted, then shouldn't that wiping reset the values of any local
> > options?

> > I'm just looking for a way to reset those local options when I edit
> > a new file, b:undo_ftplugin seemed to be the way to do it, but it
> > doesn't seem to do anything useful.

> > Not using :edit is not a solution.  For example, if I start vim
> > and use ":MRU" to open a recently-used C file, I wind up with
> > 'indentexpr' set as above, which wrongly indents C.

> Hi Gary,

> Looks like the initial buffer isn't correctly freed.
> Try this patch: which at least also gets rid of the buffer local
> options, when loading another buffer:
> diff --git a/src/buffer.c b/src/buffer.c
> --- a/src/buffer.c
> +++ b/src/buffer.c
> @@ -1702,6 +1702,12 @@
>  #endif
>         /* buf->b_nwindows = 0; why was this here? */
>         free_buffer_stuff(buf, FALSE);  /* delete local variables et al. */
> +       /* can't set TRUE in free_buffer_stuff(), this would destroy the wininfo stuff,
> +        * so freeing the buffer options here afterwards manually */
> +       free_buf_options(buf, TRUE);
> +#ifdef FEAT_SPELL
> +       ga_clear(&buf->b_s.b_langp);
> +#endif
>  #ifdef FEAT_KEYMAP
>         /* need to reload lmaps and set b:keymap_name */
>         curbuf->b_kmap_state |= KEYMAP_INIT;

> Although, this doesn't solve the problem, that the b:undo_ftplugin
> option isn't executed on BufUnload event. Possibly we need a global
> BufUnLoad event, that takes care of this, e.g. something like this:

> " Make sure, the b:undo_ftplugin is also executed deleting the buffer
> BufUnload * if exists("b:undo_ftplugin") | exe b:undo_ftplugin | endif

> But I am not sure, where to put this script. Perhaps also put this into
> ftplugin.vim?

I finally had time to look into this patch.  It breaks the tests in a
nasty way.  Thus this is not the right solution. Instead of freeing the
options they should be initialized to the global values.
Perhaps setting buf->b_p_initialized to FALSE works?

--
The technology involved in making anything invisible is so infinitely
complex that nine hundred and ninety-nine billion, nine hundred and
ninety-nine million, nine hundred and ninety-nine thousand, nine hundred
and ninety-nine times out of a trillion it is much simpler and more
effective just to take the thing away and do without it.
                -- Douglas Adams, "The Hitchhiker's Guide to the Galaxy"

 /// 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 must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.