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

Re: autocmd FuncUndefined - how to?

Expand Messages
  • Zdenek Sekera
    Sorry for copying all the previous mail but it contains lots of useful info scattered throughout which may be lost and make my anser not comprehensible (it
    Message 1 of 10 , Oct 2, 2000
    • 0 Attachment
      Sorry for copying all the previous mail but it contains lots
      of useful info scattered throughout which may be lost and make
      my anser not comprehensible (it still might be even with all
      the previous text present! :-)

      Bram Moolenaar wrote:
      >
      > Zdenek Sekera wrote:
      >
      > > It seems to me, however, that such type of usage
      > >
      > > autocmd FuncUndefined * MyListOfDirectories
      > >
      > > and the autocmd would load any function that it finds in MyListOfDirectories
      > > and which is in the form of *.vim would be pretty common way of doing it
      > > (at least it's very simple and practical) that vim could/should have it.
      > >
      > > The cases that are not covered by this statement can be resolved by an
      > > appropriate specific autocmd.
      > >
      > > Is this a reasonable suggestion? Bram?
      >
      > There has been a discussion about automatically loading functions (or
      > packages) before. But there was no simple, straightforward solution. I don't
      > like adding another mechanism that makes using Vim more complicated. The
      > simple solution to load all functions when starting Vim works for most people.
      >
      > Adding the FuncUndefined autocommand would be simple. Then it's up to each
      > user how he wants to load the function. Vim would then retry to execute the
      > function. One problem to avoid is an endless loop: Suppose the autocommand
      > fails to load the function, Vim tries to execute the function again, which
      > fails. You probably don't want to trigger the FuncUndefined event twice for
      > the same function.

      FuncUndefined autocmd exists already, I use it (not sure now why I have
      it this
      way):

      autocmd FuncUndefined [A-Z]* exe "source
      functions/".expand("<amatch>:t").".vim

      does exactly what I want: when vim arrives at 'call Abc()' at it doesn't
      know it,
      it will go to "<runtimepath>/functions/" and try to find Abc.vim and if
      it's
      found it will source it in and re-xecute "call Abc()".
      If it doesn't find it it will quit with "Unknown function Abc".

      That's perfect, no endless loop.

      So all the functionality is in already.

      All I wanted to add was to simplify the autocmd statement to this:

      autocmd FuncUndefined * dir1,dir2,dir3

      meaning:

      if "call Abc()" finds Abc undefined, (* = any function) got to
      <runtimepath>/dir1, <runtimepath>/dir2, <runtimepath>/dir3 and try to
      find
      Abc.vim, take the first and source it in and re-execute "call Abc()",
      just as
      it's done now.

      I thought at first that my autocmd has to be specified for every
      function,
      something like

      autocmd FuncUndefined Abc source Abc.vim

      but Michael Geddes suggested using '*' with complicating the action part
      of
      the autocmd (what I use now, see above).

      I am no longer sure that my suggestion with dir1, ... is really needed
      anymore,
      sure it looks simpler and is easy to grasp, but not really a vast
      improvement.

      ---Zdenek
    • Bram Moolenaar
      ... Oops, forgot it was added already. That s why it wasn t in the todo list... ... [...] ... You can do this by temporarily changing the runtimepath
      Message 2 of 10 , Oct 2, 2000
      • 0 Attachment
        Zdenek Sekera wrote:

        > FuncUndefined autocmd exists already,

        Oops, forgot it was added already. That's why it wasn't in the todo list...

        > I use it (not sure now why I have it this way):
        > autocmd FuncUndefined [A-Z]* exe "source functions/".expand("<amatch>:t").".vim

        [...]
        > All I wanted to add was to simplify the autocmd statement to this:
        >
        > autocmd FuncUndefined * dir1,dir2,dir3
        >
        > meaning:
        >
        > if "call Abc()" finds Abc undefined, (* = any function) got to
        > <runtimepath>/dir1, <runtimepath>/dir2, <runtimepath>/dir3 and try to
        > find Abc.vim, take the first and source it in and re-execute "call Abc()",
        > just as it's done now.

        You can do this by temporarily changing the 'runtimepath' option, something
        like this:

        autocmd FuncUndefined [A-Z]* call LoadFunc(expand("<amatch>"))

        fun LoadFunc(name)
        let tt = &runtimepath
        set runtimepath=here/dir1,there/dir2,elsewhere/dir3
        exe "runtime functions/" . a:name
        let &runtimepath = tt
        endfun

        --
        hundred-and-one symptoms of being an internet addict:
        122. You ask if the Netaholics Anonymous t-shirt you ordered can be
        sent to you via e-mail.

        /// Bram Moolenaar Bram@... http://www.moolenaar.net \\\
        \\\ Vim: http://www.vim.org ICCF Holland: http://iccf-holland.org ///
      • Ron Aaron
        ... Yeah, I added it! My approach is different; I have my scripts with demand load functions in them. I do not put one function per script, though that now
        Message 3 of 10 , Oct 2, 2000
        • 0 Attachment
          Bram Moolenaar <Bram@...> writes:
          >Zdenek Sekera wrote:
          >
          >> FuncUndefined autocmd exists already,
          >
          >Oops, forgot it was added already. That's why it wasn't in the todo list...

          Yeah, I added it!

          My approach is different; I have my scripts with 'demand load' functions in
          them. I do not put one function per script, though that now seems like a more
          simple idea. Anyway, I have a 'tags' file which says "Function XYZ is in
          file ABC" for each function; then I just load the appropriate file. It works
          like a charm for me, but one does have to regenerate the 'tags' file, which
          can be a bummer.

          Ron
        • Johannes Zellner
          ... that s exactly the way I do it. The tags file (I call it `autoload.vim ) is generated by a Makefile. I ve in each file which is autoloadable something like
          Message 4 of 10 , Oct 2, 2000
          • 0 Attachment
            On Mon, Oct 02, 2000 at 10:27:24AM -0700, Ron Aaron wrote:
            > Bram Moolenaar <Bram@...> writes:
            > >Zdenek Sekera wrote:
            > >
            > >> FuncUndefined autocmd exists already,
            > >
            > >Oops, forgot it was added already. That's why it wasn't in the todo list...
            >
            > Yeah, I added it!
            >
            > My approach is different; I have my scripts with 'demand load' functions in
            > them. I do not put one function per script, though that now seems like a more
            > simple idea. Anyway, I have a 'tags' file which says "Function XYZ is in
            > file ABC" for each function; then I just load the appropriate file. It works
            > like a charm for me, but one does have to regenerate the 'tags' file, which
            > can be a bummer.

            that's exactly the way I do it. The tags file (I call it `autoload.vim')
            is generated by a Makefile. I've in each file which is autoloadable
            something like

            if !exists("g:vimautoload")
            map <Map>k :<c-u>call ManFancyCword(v:count)<cr>
            command! -nargs=* Man call ManPrePrep(<f-args>)
            endif

            my make rules extract everything which is in between the if / endif
            (autocommands and mappings) and uses the latest `ctags' to get all
            function names of the script. (ctags can make tags for vim functions!)

            So finally I get a `autoload.vim' which contains:

            let g:vimautoload = 1
            " functions/Man.vim
            map <Map>k :<c-u>call ManFancyCword(v:count)<cr>
            command! -nargs=* Man call ManPrePrep(<f-args>)
            au FuncUndefined ManFancyCword source /home/joze/.vim/functions/Man.vim
            au FuncUndefined ManPrePrep source /home/joze/.vim/functions/Man.vim
            au FuncUndefined ManPrep source /home/joze/.vim/functions/Man.vim
            " functions/another.vim
            ...


            The `if !exists("g:vimautoload")' has the advantage that the scripts
            work still w/o any autoloading (but sourcing directly), that means I
            can still share the scripts with others: as they don't define
            g:vimautoload, the mappings and autocommands are applied directly.

            --
            Johannes
          Your message has been successfully submitted and would be delivered to recipients shortly.