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

autocmd FuncUndefined - how to?

Expand Messages
  • Zdenek Sekera
    The autocmd event FuncUndefined (thanks Ron!) is a very nice feature but I am not sure if I know really how to use it. This works: autocmd FuncUndefined A
    Message 1 of 10 , Sep 13 1:32 AM
    • 0 Attachment
      The autocmd event FuncUndefined (thanks Ron!) is a very nice feature
      but I am not sure if I know really how to use it.

      This works:

      autocmd FuncUndefined A :source somedir/A.vim

      If this is the only way to use it it's quite limited IMHO.
      Indeed, if I have many functions (and I do), I have to, presumably,
      type this line for every one of them and when I write a new function
      I better not forget to add a similar line for it somewhere in .vimrc
      or wherever. You tell me that's exactly as before when one had to
      :source every function except now it gets loaded only when really needed
      so we are still better off.

      But couldn't we do something better? I am thinking along lines
      like this:

      - I'd like to place all my functions in a director(y/ies)

      - define maybe one autocmd saying in essence: if any function is
      undefined, go and look into my 'function' director(y/ies) for a file
      'function.vim' and if found load it.

      something like:

      autocmd FuncUndefined AnyFunction MyListOfDirectories

      This doesn't cover all cases, of course, e.g. when several functions
      are defined in the same file, this file will not neccessarily cary
      the name of any of functions contained in it (you know what I mean),
      but for these cases I would gladly specify the autocmd as above.

      Maybe we can already do something like I am talking about above and
      I just don't know how.

      Any idea?

      ---Zdenek
    • Moore, Paul
      From: Zdenek Sekera [mailto:zs@sgi.com] ... autocmd FuncUndefined * call MyFunctionLoader( ) or something like that? is the function which
      Message 2 of 10 , Sep 13 1:42 AM
      • 0 Attachment
        From: Zdenek Sekera [mailto:zs@...]
        > But couldn't we do something better? I am thinking along lines
        > like this:
        >
        > - I'd like to place all my functions in a director(y/ies)
        >
        > - define maybe one autocmd saying in essence: if any function is
        > undefined, go and look into my 'function' director(y/ies) for a file
        > 'function.vim' and if found load it.
        >
        > something like:
        >
        > autocmd FuncUndefined AnyFunction MyListOfDirectories

        autocmd FuncUndefined * call MyFunctionLoader("<amatch>")

        or something like that? <amatch> is the function which wasn't defined. You
        may need some combination of :exe and/or expand() to make this work...

        Paul.
      • Zdenek Sekera
        ... Yes, of course that s a possibility, should have thought about it, need some coffee... Need a special handling of MyFunctionLoader otherwise one gets some
        Message 3 of 10 , Sep 13 1:53 AM
        • 0 Attachment
          "Moore, Paul" wrote:
          >
          > From: Zdenek Sekera [mailto:zs@...]
          > > But couldn't we do something better? I am thinking along lines
          > > like this:
          > >
          > > - I'd like to place all my functions in a director(y/ies)
          > >
          > > - define maybe one autocmd saying in essence: if any function is
          > > undefined, go and look into my 'function' director(y/ies) for a file
          > > 'function.vim' and if found load it.
          > >
          > > something like:
          > >
          > > autocmd FuncUndefined AnyFunction MyListOfDirectories
          >
          > autocmd FuncUndefined * call MyFunctionLoader("<amatch>")
          >
          > or something like that? <amatch> is the function which wasn't defined. You
          > may need some combination of :exe and/or expand() to make this work...

          Yes, of course that's a possibility, should have thought about it, need
          some
          coffee... Need a special handling of MyFunctionLoader otherwise one gets
          some interesting catch-22 problems. But that's solvable.

          Gosh, just realizing, I have something similar already done for other
          purposes, just need a trivial tweak. ..I really need that coffee.....!

          Thanks for hint!

          ---Zdenek
        • Michael Geddes
          The other possibility is to have a tags type program that creates a list of autocommands for different functions... or borrow from my buffoptions, and have a
          Message 4 of 10 , Sep 13 4:07 PM
          • 0 Attachment
            The other possibility is to have a 'tags' type program that creates a list
            of autocommands for different functions...
            or borrow from my buffoptions, and have a version of 'source' that adds an
            autocmd for each function it finds in the file.

            //.

            -----Original Message-----
            From: Zdenek Sekera [SMTP:zs@...]
            Sent: Wednesday, 13 September 2000 19:32
            To: vim-dev
            Subject: autocmd FuncUndefined - how to?

            The autocmd event FuncUndefined (thanks Ron!) is a very nice feature
            but I am not sure if I know really how to use it.

            This works:

            autocmd FuncUndefined A :source somedir/A.vim

            If this is the only way to use it it's quite limited IMHO.
            Indeed, if I have many functions (and I do), I have to, presumably,
            type this line for every one of them and when I write a new function
            I better not forget to add a similar line for it somewhere in .vimrc
            or wherever. You tell me that's exactly as before when one had to
            :source every function except now it gets loaded only when really
            needed
            so we are still better off.

            But couldn't we do something better? I am thinking along lines
            like this:

            - I'd like to place all my functions in a director(y/ies)

            - define maybe one autocmd saying in essence: if any function is
            undefined, go and look into my 'function' director(y/ies) for a
            file
            'function.vim' and if found load it.

            something like:

            autocmd FuncUndefined AnyFunction MyListOfDirectories

            This doesn't cover all cases, of course, e.g. when several functions
            are defined in the same file, this file will not neccessarily cary
            the name of any of functions contained in it (you know what I mean),
            but for these cases I would gladly specify the autocmd as above.

            Maybe we can already do something like I am talking about above and
            I just don't know how.

            Any idea?

            ---Zdenek
          • Zdenek Sekera
            ... Good ideas, in fact I have started doing domething similar to your second suggestion but then I thought there must be a simpler way and asked vim-dev.
            Message 5 of 10 , Sep 13 11:53 PM
            • 0 Attachment
              Michael Geddes wrote:
              >
              > The other possibility is to have a 'tags' type program that creates a list
              > of autocommands for different functions...
              > or borrow from my buffoptions, and have a version of 'source' that adds an
              > autocmd for each function it finds in the file.

              Good ideas, in fact I have started doing domething similar to your
              second
              suggestion but then I thought 'there must be a simpler way' and asked
              vim-dev.
              After Paul Moore's answer I realized that I already have a :Source
              function
              that's almost ready to do load 'anything from anywhere', so after little
              tweaking that's what I am using now.

              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?

              ---Zdenek
            • Bram Moolenaar
              ... There has been a discussion about automatically loading functions (or packages) before. But there was no simple, straightforward solution. I don t like
              Message 6 of 10 , Sep 30 6:45 AM
              • 0 Attachment
                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.

                --
                hundred-and-one symptoms of being an internet addict:
                65. The last time you looked at the clock it was 11:30pm, and in what seems
                like only a few seconds later, your sister runs past you to catch her
                7am school bus.

                /// Bram Moolenaar Bram@... http://www.moolenaar.net \\\
                \\\ Vim: http://www.vim.org ICCF Holland: http://iccf-holland.org ///
              • 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 7 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 8 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 9 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 10 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.