Loading ...
Sorry, an error occurred while loading the content.

RE: bug in explicit :setf behavior?

Expand Messages
  • Vince Negri
    ... If you look at how the ftplugins work, you will see why there is this limitation. The plugins are written to assert their settings over a blank canvas, and
    Message 1 of 17 , May 1, 2003
    • 0 Attachment
      > Essentially, one can do any number of explicit
      > :setf somefiletype's after the initial filetype setting, but only
      > the first existing

      > ftplugin/somefiletype.vim
      > indent/somefiletype.vim

      > take effect.

      If you look at how the ftplugins work, you will
      see why there is this limitation. The plugins
      are written to assert their settings over a
      blank canvas, and won't necessarily remove
      the settings of a previous ftplugin. Thus, if
      the second ftplugin was allowed to run, you
      would get a mixture of settings.

      To remove this problem, each ftplugin script
      would have to provide an "uninstall" function
      which could be first called by the :setf command
      if it detected there was an already loaded
      filetype.

      Vince



      Legal Disclaimer: Any views expressed by the sender of this message are
      not necessarily those of Application Solutions Ltd. Information in this
      e-mail may be confidential and is for the use of the intended recipient
      only, no mistake in transmission is intended to waive or compromise such
      privilege. Please advise the sender if you receive this e-mail by mistake.
    • Dorai Sitaram
      ... Right. Each ftplugin would have to do the equivalent of ... where all the options are set to their currently obtaining global values, before it starts
      Message 2 of 17 , May 1, 2003
      • 0 Attachment
        Vince wrote:
        > Dorai wrote:
        > > Essentially, one can do any number of explicit
        > > :setf somefiletype's after the initial filetype setting, but only
        > > the first existing
        >
        > > ftplugin/somefiletype.vim
        > > indent/somefiletype.vim
        >
        > > take effect.
        >
        > If you look at how the ftplugins work, you will
        > see why there is this limitation. The plugins
        > are written to assert their settings over a
        > blank canvas, and won't necessarily remove
        > the settings of a previous ftplugin. Thus, if
        > the second ftplugin was allowed to run, you
        > would get a mixture of settings.
        >
        > To remove this problem, each ftplugin script
        > would have to provide an "uninstall" function
        > which could be first called by the :setf command
        > if it detected there was an already loaded
        > filetype.

        Right. Each ftplugin would have to do the equivalent
        of

        :setlocal all<

        where all the options are set to their currently
        obtaining global values, before it starts doing
        its own setlocals.

        Unfortunately, :setlocal all< is not (yet?)
        supported in vim. Doing :setlocal option< individually
        for each possibly modified option is too tedious. vim
        does support :setlocal all&, but that wouldn't be quite
        right, since we want the user's preferences for globals
        to be respected.
      • Bram Moolenaar
        ... True, but not providing the possibility to load another filetype plugin isn t nice either. Currently you would have to do :bwipe and edit the file again
        Message 3 of 17 , May 1, 2003
        • 0 Attachment
          Vince Negri wrote:

          > > Essentially, one can do any number of explicit
          > > :setf somefiletype's after the initial filetype setting, but only
          > > the first existing
          >
          > > ftplugin/somefiletype.vim
          > > indent/somefiletype.vim
          >
          > > take effect.
          >
          > If you look at how the ftplugins work, you will
          > see why there is this limitation. The plugins
          > are written to assert their settings over a
          > blank canvas, and won't necessarily remove
          > the settings of a previous ftplugin. Thus, if
          > the second ftplugin was allowed to run, you
          > would get a mixture of settings.

          True, but not providing the possibility to load another filetype plugin
          isn't nice either. Currently you would have to do ":bwipe" and edit the
          file again (making sure the right filetype is used this time).

          > To remove this problem, each ftplugin script
          > would have to provide an "uninstall" function
          > which could be first called by the :setf command
          > if it detected there was an already loaded
          > filetype.

          That might not be a bad idea. How to implement this? We should at
          least make sure that old filetype plugins still work. Thus new filetype
          plugins must provide their "uninstall" function somehow. Perhaps simply
          by providing an "s:uninstall()" function?

          --
          hundred-and-one symptoms of being an internet addict:
          129. You cancel your newspaper subscription.

          /// Bram Moolenaar -- Bram@... -- http://www.Moolenaar.net \\\
          /// Creator of Vim - Vi IMproved -- http://www.Vim.org \\\
          \\\ Project leader for A-A-P -- http://www.A-A-P.org ///
          \\\ Help AIDS victims, buy at Amazon -- http://ICCF.nl/click1.html ///
        • Dorai Sitaram
          ... Ability to do :setlocal all
          Message 4 of 17 , May 1, 2003
          • 0 Attachment
            Bram wrote:
            >
            > Vince Negri wrote:
            >
            > > To remove this problem, each ftplugin script
            > > would have to provide an "uninstall" function
            > > which could be first called by the :setf command
            > > if it detected there was an already loaded
            > > filetype.
            >
            > That might not be a bad idea. How to implement this? We should at
            > least make sure that old filetype plugins still work. Thus new filetype
            > plugins must provide their "uninstall" function somehow. Perhaps simply
            > by providing an "s:uninstall()" function?

            Ability to do :setlocal all< would be a lifesaver.
            Once that's in, changing the definition of

            :setf {filetype}

            to be something like

            :if !did_filetype()
            : if exists("b:did_ftplugin")
            : unlet b:did_ftplugin
            : endif
            : if exists("b:did_indent")
            : unlet b:did_indent
            : endif
            : setlocal all<
            : setlocal filetype={filetype}
            :endif

            should all be all that's needed. The old plugin
            files wouldn't need to be changed. (If they introduced
            let variables and function definitions, those would
            stay across filetype changes for the same buffer, but
            perhaps that's harmless?)
          • Bram Moolenaar
            ... I don t like this, because the order in which things are done will ... Even when the mail filetype plugin doesn t set tw . That is not what people
            Message 5 of 17 , May 1, 2003
            • 0 Attachment
              Dorai wrote:

              > Ability to do :setlocal all< would be a lifesaver.
              > Once that's in, changing the definition of
              >
              > :setf {filetype}
              >
              > to be something like
              >
              > :if !did_filetype()
              > : if exists("b:did_ftplugin")
              > : unlet b:did_ftplugin
              > : endif
              > : if exists("b:did_indent")
              > : unlet b:did_indent
              > : endif
              > : setlocal all<
              > : setlocal filetype={filetype}
              > :endif
              >
              > should all be all that's needed. The old plugin
              > files wouldn't need to be changed. (If they introduced
              > let variables and function definitions, those would
              > stay across filetype changes for the same buffer, but
              > perhaps that's harmless?)

              I don't like this, because the order in which things are done will
              matter, e.g.:

              :setl tw=55
              :setf mail

              Will work differently from:

              :setf mail
              :setl tw=55

              Even when the "mail" filetype plugin doesn't set 'tw'. That is not what
              people expect.

              --
              hundred-and-one symptoms of being an internet addict:
              131. You challenge authority and society by portnuking people

              /// Bram Moolenaar -- Bram@... -- http://www.Moolenaar.net \\\
              /// Creator of Vim - Vi IMproved -- http://www.Vim.org \\\
              \\\ Project leader for A-A-P -- http://www.A-A-P.org ///
              \\\ Help AIDS victims, buy at Amazon -- http://ICCF.nl/click1.html ///
            • Bram Moolenaar
              ... A simple solution would be to support the b:undo_ftplugin variable. It should be set by the filetype plugin to the commands required to undo the settings.
              Message 6 of 17 , May 1, 2003
              • 0 Attachment
                I wrote to Dorai:

                > > Ability to do :setlocal all< would be a lifesaver.
                > > Once that's in, changing the definition of
                > >
                > > :setf {filetype}
                > >
                > > to be something like
                > >
                > > :if !did_filetype()
                > > : if exists("b:did_ftplugin")
                > > : unlet b:did_ftplugin
                > > : endif
                > > : if exists("b:did_indent")
                > > : unlet b:did_indent
                > > : endif
                > > : setlocal all<
                > > : setlocal filetype={filetype}
                > > :endif
                > >
                > > should all be all that's needed. The old plugin
                > > files wouldn't need to be changed. (If they introduced
                > > let variables and function definitions, those would
                > > stay across filetype changes for the same buffer, but
                > > perhaps that's harmless?)
                >
                > I don't like this, because the order in which things are done will
                > matter, e.g.:
                >
                > :setl tw=55
                > :setf mail
                >
                > Will work differently from:
                >
                > :setf mail
                > :setl tw=55
                >
                > Even when the "mail" filetype plugin doesn't set 'tw'. That is not what
                > people expect.

                A simple solution would be to support the b:undo_ftplugin variable. It
                should be set by the filetype plugin to the commands required to undo
                the settings. I have implemented this for the Vim plugin.

                Note that a bug in the source code needs to be fixed for this to work.
                Apparently nobody tried doing ":setlocal tw<" yet!

                Would there be any problem with this approach?


                *** runtime/ftplugin.vim~ Fri Oct 19 15:21:05 2001
                --- runtime/ftplugin.vim Thu May 1 19:40:27 2003
                ***************
                *** 12,17 ****
                --- 12,21 ----
                au FileType * call s:LoadFTPlugin()
                func! s:LoadFTPlugin()
                if expand("<amatch>") != ""
                + if exists("b:undo_ftplugin")
                + exe b:undo_ftplugin
                + unlet b:undo_ftplugin b:did_ftplugin
                + endif
                if &cpo =~# "S" && exists("b:did_ftplugin")
                " In compatible mode options are reset to the global values, need to
                " set the local values also when a plugin was already used.
                *** runtime/ftplugin/vim.vim~ Fri Apr 25 20:14:38 2003
                --- runtime/ftplugin/vim.vim Thu May 1 19:44:34 2003
                ***************
                *** 11,16 ****
                --- 11,22 ----
                " Don't load another plugin for this buffer
                let b:did_ftplugin = 1

                + let cpo_save = &cpo
                + set cpo-=C
                +
                + let b:undo_ftplugin = "setl fo< com< tw< commentstring<"
                + \ . "| unlet b:match_ignorecase b:match_words b:match_skip"
                +
                " Set 'formatoptions' to break comment lines but not other lines,
                " and insert the comment leader when hitting <CR> or using "o".
                setlocal fo-=t fo+=croql
                ***************
                *** 24,31 ****
                " Comments start with a double quote
                setlocal commentstring=\"%s

                - set cpo-=C
                -
                " Let the matchit plugin know what items can be matched.
                if exists("loaded_matchit")
                let b:match_ignorecase = 0
                --- 30,35 ----
                ***************
                *** 41,43 ****
                --- 45,48 ----
                \ synIDattr(synID(line("."),col("."),1),"name") =~? "comment\\|string"'
                endif

                + let &cpo = cpo_save
                *** src/option.c~ Wed Apr 30 16:39:05 2003
                --- src/option.c Thu May 1 19:51:43 2003
                ***************
                *** 3515,3521 ****
                value = (long)options[opt_idx].def_val[
                ((flags & P_VI_DEF) || cp_val)
                ? VI_DEFAULT : VIM_DEFAULT];
                ! else if (nextchar == '^')
                value = *(long *)get_varp_scope(&(options[opt_idx]),
                OPT_GLOBAL);
                else if (((long *)varp == &p_wc
                --- 3515,3521 ----
                value = (long)options[opt_idx].def_val[
                ((flags & P_VI_DEF) || cp_val)
                ? VI_DEFAULT : VIM_DEFAULT];
                ! else if (nextchar == '<')
                value = *(long *)get_varp_scope(&(options[opt_idx]),
                OPT_GLOBAL);
                else if (((long *)varp == &p_wc

                --
                hundred-and-one symptoms of being an internet addict:
                133. You communicate with people on other continents more than you
                do with your own neighbors.

                /// Bram Moolenaar -- Bram@... -- http://www.Moolenaar.net \\\
                /// Creator of Vim - Vi IMproved -- http://www.Vim.org \\\
                \\\ Project leader for A-A-P -- http://www.A-A-P.org ///
                \\\ Help AIDS victims, buy at Amazon -- http://ICCF.nl/click1.html ///
              • Vince Negri
                ... That would seem logical. The call to uninstall() could then be placed in the b:undo_ftplugin variable you suggested. Vince Legal Disclaimer: Any views
                Message 7 of 17 , May 2, 2003
                • 0 Attachment
                  > Thus new filetype
                  > plugins must provide their "uninstall" function somehow. Perhaps simply
                  > by providing an "s:uninstall()" function?

                  That would seem logical. The call to uninstall() could
                  then be placed in the b:undo_ftplugin variable you suggested.

                  Vince


                  Legal Disclaimer: Any views expressed by the sender of this message are
                  not necessarily those of Application Solutions Ltd. Information in this
                  e-mail may be confidential and is for the use of the intended recipient
                  only, no mistake in transmission is intended to waive or compromise such
                  privilege. Please advise the sender if you receive this e-mail by mistake.
                • Dorai Sitaram
                  Bram wrote ... silent one (no error message). It doesn t change isi to its current global value; it is a no-op. Try
                  Message 8 of 17 , May 2, 2003
                  • 0 Attachment
                    Bram wrote
                    >
                    > Note that a bug in the source code needs to be fixed for this to work.
                    > Apparently nobody tried doing ":setlocal tw<" yet!
                    >

                    :setl isi< also has a bug, and what's more, it's a
                    silent one (no error message).

                    It doesn't change isi to its current global
                    value; it is a no-op. Try

                    :setg isi=@
                    :setl isi+=+
                    :setl isi<
                    :echo &isi
                  • Dorai Sitaram
                    I wrote ... The docs say isi is a global option with no per-buffer incarnations possible, so the behavior I mention is expected (since :setl isi is
                    Message 9 of 17 , May 2, 2003
                    • 0 Attachment
                      I wrote
                      >
                      > :setl isi< also has a bug, and what's more, it's a
                      > silent one (no error message).
                      >
                      > It doesn't change isi to its current global
                      > value; it is a no-op. Try
                      >
                      > :setg isi=@
                      > :setl isi+=+
                      > :setl isi<
                      > :echo &isi

                      The docs say 'isi' is a global option with no
                      per-buffer incarnations possible, so the behavior
                      I mention is expected (since :setl isi is
                      indistinguishable from :setg isi).

                      So: It's not a bug (but maybe it should be...).
                    • Bram Moolenaar
                      ... isident is a global option, thus it s always at it s global value. -- hundred-and-one symptoms of being an internet addict: 143. You dream in pallettes
                      Message 10 of 17 , May 2, 2003
                      • 0 Attachment
                        Dorai wrote:

                        > Bram wrote
                        > >
                        > > Note that a bug in the source code needs to be fixed for this to work.
                        > > Apparently nobody tried doing ":setlocal tw<" yet!
                        > >
                        >
                        > :setl isi< also has a bug, and what's more, it's a
                        > silent one (no error message).
                        >
                        > It doesn't change isi to its current global
                        > value; it is a no-op. Try
                        >
                        > :setg isi=@
                        > :setl isi+=+
                        > :setl isi<
                        > :echo &isi

                        'isident' is a global option, thus it's always at it's global value.

                        --
                        hundred-and-one symptoms of being an internet addict:
                        143. You dream in pallettes of 216 websafe colors.

                        /// Bram Moolenaar -- Bram@... -- http://www.Moolenaar.net \\\
                        /// Creator of Vim - Vi IMproved -- http://www.Vim.org \\\
                        \\\ Project leader for A-A-P -- http://www.A-A-P.org ///
                        \\\ Help AIDS victims, buy at Amazon -- http://ICCF.nl/click1.html ///
                      Your message has been successfully submitted and would be delivered to recipients shortly.