Hi Gary!
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?
regards,
Christian
--
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