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

Re: Function to complete #if's

Expand Messages
  • Mark Zealey
    ... [Nice script cut] Thanks! here s a slightly fixed version which works with #ifndef too. preprocessor macro s can t have whitepsace before the # however, I
    Message 1 of 10 , Aug 1, 2001
      On Wed, Aug 01, 2001 at 09:48:50PM +0300, Bohdan Vlasyuk wrote:

      > On Wed, Aug 01, 2001 at 07:38:10PM +0100, Mark Zealey wrote:
      >
      > > And vim could automatically fill in the #else and #endif with /* __foo__ */
      > > after them, as is commonly the style in complexed .h files.

      [Nice script cut]


      Thanks! here's a slightly fixed version which works with #ifndef too.
      preprocessor macro's can't have whitepsace before the # however, I believe, so I
      fixed that:

      fun SetPreproc()
      mark j
      if match(getline('.'), '^#\s*endif\s*') != -1
      normal %
      let cond = ''
      let line = getline('.')

      let c_start = matchend(line, '^#\s*if\s\+')
      if c_start != -1
      let cond = strpart(line, c_start)
      endif

      let c_start = matchend(line, '^#\s*ifdef\s\+')
      if c_start != -1
      let cond = strpart(line, c_start)
      endif

      let c_start = matchend(line, '^#\s*ifndef\s\+')
      if c_start != -1
      let cond = '!' . strpart(line, c_start)
      endif

      if cond != ''
      normal %
      if match(getline('.'), '^#\s*else') != -1
      exec 'normal A /* ' . cond . ' */'
      normal ^%
      endif
      exec 'normal A /* ' . cond . ' */'
      endif
      endif
      'j
      endfun

      inoremap #endif #endif<C-O>:call SetPreproc()<CR>


      --

      Mark Zealey (aka JALH on irc.openprojects.net: #zealos and many more)
      mark@...

      UL++++>$ G!>(GCM/GCS/GS/GM) dpu? s:-@ a16! C++++>$ P++++>+++++$ L+++>+++++$
      !E---? W+++>$ N- !o? !w--- O? !M? !V? !PS !PE--@ PGP+? r++ !t---?@ !X---?
      !R- b+ !tv b+ DI+ D+? G+++ e>+++++ !h++* r!-- y--

      (www.geekcode.com)
    • Bohdan Vlasyuk
      ... Ok. sorry that no explaination followed (was it working at all??) -- it was 14-th hour of my sitting in front of computed, and I somewhat hurried to leave.
      Message 2 of 10 , Aug 2, 2001
        On Wed, Aug 01, 2001 at 08:29:22PM +0100, Mark Zealey wrote:

        >>> And vim could automatically fill in the #else and #endif with /*
        >>> __foo__ */
        >> [Nice script cut]
        > Thanks! here's a slightly fixed version which works with #ifndef
        > too.
        Ok. sorry that no explaination followed (was it working at all??) --
        it was 14-th hour of my sitting in front of computed, and I somewhat
        hurried to leave.

        > fun SetPreproc()

        [skip]
        > let line = getline('.')
        > let c_start = matchend(line, '^#\s*if\s\+')
        > let c_start = matchend(line, '^#\s*ifdef\s\+')
        > let c_start = matchend(line, '^#\s*ifndef\s\+')
        this can be changed to one line
        let c_start = matchend(line, '^#\s*if\(n\=def\)\=\s\+')
        however, three `if's have that advantage that you can specify
        different strings for different cases, e.g.:
        #if foo
        ...
        #ednif /* if foo */

        #ifdef foo
        ...
        #endif /* ifdef foo */

        etc...


        > if cond != ''
        > normal %
        > if match(getline('.'), '^#\s*else') != -1
        > exec 'normal A /* ' . cond . ' */'
        > normal ^%
        > endif
        > exec 'normal A /* ' . cond . ' */'
        this can be turned into while loop, matching for #endif, but while
        loop is not safe, if your % is broken, and would lead you to place
        where there would be no return..

        > inoremap #endif #endif<C-O>:call SetPreproc()<CR>
        I suppose you'd better make it abbreviation, see :h Abbreviations for
        details...



        --
        "You know, of course, that the Tasmanians, who never committed adultery, are
        now extinct."
        - M. Somerset Maugham
      • Benji Fisher
        ... [snip] I could add functionality like this to my script matchit.vim. The problem of automatically generating #endif from #if is similar to the problem of
        Message 3 of 10 , Aug 2, 2001
          Bohdan Vlasyuk wrote:
          >
          > On Wed, Aug 01, 2001 at 08:29:22PM +0100, Mark Zealey wrote:
          >
          > >>> And vim could automatically fill in the #else and #endif with /*
          > >>> __foo__ */
          > >> [Nice script cut]
          > > Thanks! here's a slightly fixed version which works with #ifndef
          > > too.
          [snip]

          I could add functionality like this to my script matchit.vim. The
          problem of automatically generating #endif from #if is similar to the problem
          of using % to jump between the two. (This much is already in standard vim,
          but matchit.vim allows you to customize the behavior for different
          languages.) The only reason I have not done this already is that it is hard,
          given the regular expressions that match <tag> and </tag> (where the "tag"
          text can be anything), it is difficult to generate the string "</tag>". One
          way to solve this is to have separate sets of patterns for % matching and for
          completion.

          My idea is to allow the user to map a key, such as <C-Enter>, to call the
          function that generates the closing string. I am not sure how to handle
          "else"-like strings...

          --Benji Fisher
        • Bohdan Vlasyuk
          ... I think if you can generate #endif, it also means that you re able to find corresponding #if. [That looks obvious] ... If I got it right, you re talking
          Message 4 of 10 , Aug 2, 2001
            On Thu, Aug 02, 2001 at 09:31:04AM -0400, Benji Fisher wrote:

            > The problem of automatically generating #endif from #if is similar
            > to the problem of using % to jump between the two.
            I think if you can generate #endif, it also means that you're able to
            find corresponding #if. [That looks obvious]

            > The only reason I have not done this already is that it is hard,
            > given the regular expressions that match <tag> and </tag>, it is
            > difficult to generate the string "</tag>". One way to solve this is
            > to have separate sets of patterns for % matching and for completion.
            > My idea is to allow the user to map a key, such as <C-Enter>, to
            > call the function that generates the closing string. I am not sure
            > how to handle "else"-like strings...
            If I got it right, you're talking about thing different from that what
            was originally supposed -- you mean to generate closing strings, not
            comments to already given strings..

            As far as I understand how it would work, I assume this may be
            misleading.. I think you search backwards for anything that looks like
            closing/opening tag, and skip to corresponding opening tag in case of
            closing, and generate closing tag if you've met opening tag.. Is it
            correct ??

            In the context of html, how would you deal with <p> and other which
            are not neccesary closed ??


            --
            The luck that is ordained for you will be coveted by others.
          • Benji Fisher
            ... Right. The point is, one of these problems has already been solved, in matchit.vim . It is not much additional work to solve the other one. ... Right.
            Message 5 of 10 , Aug 2, 2001
              Bohdan Vlasyuk wrote:
              >
              > On Thu, Aug 02, 2001 at 09:31:04AM -0400, Benji Fisher wrote:
              >
              > > The problem of automatically generating #endif from #if is similar
              > > to the problem of using % to jump between the two.
              > I think if you can generate #endif, it also means that you're able to
              > find corresponding #if. [That looks obvious]

              Right. The point is, one of these problems has already been solved, in
              matchit.vim . It is not much additional work to solve the other one.

              > > The only reason I have not done this already is that it is hard,
              > > given the regular expressions that match <tag> and </tag>, it is
              > > difficult to generate the string "</tag>". One way to solve this is
              > > to have separate sets of patterns for % matching and for completion.
              > > My idea is to allow the user to map a key, such as <C-Enter>, to
              > > call the function that generates the closing string. I am not sure
              > > how to handle "else"-like strings...
              > If I got it right, you're talking about thing different from that what
              > was originally supposed -- you mean to generate closing strings, not
              > comments to already given strings..

              Right.

              > As far as I understand how it would work, I assume this may be
              > misleading.. I think you search backwards for anything that looks like
              > closing/opening tag, and skip to corresponding opening tag in case of
              > closing, and generate closing tag if you've met opening tag.. Is it
              > correct ??

              Not quite. When I hit <C-Enter> (or whatever other key I have chosen)
              the script looks back to find an unclosed "<tag>", say. It does not actually
              move the cursor, though, which is how I would understand your "skip". The
              script would add "</tag>" at the cursor position.

              > In the context of html, how would you deal with <p> and other which
              > are not neccesary closed ??

              For each language, someone has to decide what matching patterns would be
              used. For HTML, one might decide to ignore "<p>".

              --Benji Fisher
            • Bohdan Vlasyuk
              ... I mean: if you have ... and press , what would you have then ?? I think it woule be natural to get , wouldn t
              Message 6 of 10 , Aug 2, 2001
                In Thu, Aug 02, 2001 at 11:09:14PM -0400, Benji Fisher wrote:

                >> I think you search backwards for anything that looks like
                >> closing/opening tag, and skip to corresponding opening tag in case
                >> of closing, and generate closing tag if you've met opening tag.. Is
                >> it correct ??
                > Not quite. When I hit <C-Enter> (or whatever other key I have
                > chosen) the script looks back to find an unclosed "<tag>", say. It
                > does not actually move the cursor, though, which is how I would
                > understand your "skip". The script would add "</tag>" at the cursor
                > position.
                I mean:

                if you have

                <foo>
                <bar>
                <foobar>
                </bar>
                | [<-cursor]

                and press <C-Enter>, what would you have then ?? I think it woule be
                natural to get </foo>, wouldn't it ? Obviously, if you'd get
                </foobar> if would be broken construction, and most probably not that
                you would like to have..



                --
                Fortune's current rates:

                Answers .10
                Long answers .25
                Answers requiring thought .50
                Correct answers $1.00

                Dumb looks are still free.
              • Thomas S. Urban
                ... [another nice script cut] Here is an improved (well, maybe just expanded) version that will automatically indent your preprocessor directives if they are
                Message 7 of 10 , Sep 1, 2001
                  On Wed, Aug 01, 2001 at 08:29:22PM +0100, Mark Zealey wrote:
                  > On Wed, Aug 01, 2001 at 09:48:50PM +0300, Bohdan Vlasyuk wrote:
                  >
                  > > On Wed, Aug 01, 2001 at 07:38:10PM +0100, Mark Zealey wrote:
                  > >
                  > > > And vim could automatically fill in the #else and #endif with /* __foo__ */
                  > > > after them, as is commonly the style in complexed .h files.
                  >
                  > [Nice script cut]
                  >
                  >
                  > Thanks! here's a slightly fixed version which works with #ifndef too.
                  > preprocessor macro's can't have whitepsace before the # however, I believe, so I
                  > fixed that:
                  >

                  [another nice script cut]

                  Here is an improved (well, maybe just expanded) version that will
                  automatically indent your preprocessor directives if they are nested.
                  It also handles mutliple #elif directives (adding to the comments on
                  each subsequent #el* and the #endif). It uses // for C++, /* */ for C.

                  The imaps are:
                  #i -> #if (user completes to #ifdef, #ifndef, or just #if args)
                  #d -> #define
                  #u -> #undef
                  #el -> #el (user completes to #else or #elif)
                  #en -> #endif
                  (you might want to change them to the full words if you don't like
                  suprises as you type)

                  Like the inspiring script, comment adding is only triggered for the #en
                  mapping. All the others do the nested indenting. So if I type this:

                  #idef BILL
                  #indef BOB
                  #d FRED
                  #en
                  #en
                  #i 1
                  #i !defined(BILL)
                  #elif defined(FRED)
                  #elif defined(F) || !defined(R)
                  #d 2 3
                  #else
                  #idef TRUE
                  #d 3 2
                  #en
                  #en
                  #u BOB
                  #en

                  I get this output (with ts=2):

                  #ifdef BILL
                  # ifndef BOB
                  # define FRED
                  # endif /* !BOB */
                  #endif /* BILL */
                  #if 1
                  # if !defined(BILL)
                  # elif defined(FRED) /* !defined(BILL) */
                  # elif defined(F) || !defined(R) /* !defined(BILL) + defined(FRED) */
                  # define 2 3
                  # else /* !defined(BILL) + defined(FRED) + defined(F) || !defined(R) */
                  # ifdef TRUE
                  # define 3 2
                  # endif /* TRUE */
                  # endif /* !defined(BILL) + defined(FRED) + defined(F) || !defined(R) */
                  # undef BOB
                  #endif /* 1 */

                  If you don't find this indenting style attractive, you might find this
                  all that useful. It's implemented with two functions though, so you
                  could separate them. Moderated numbers of #elif's can produce really
                  long comments.



                  Scott

                  --
                  If all men were brothers, would you let one marry your sister?
                Your message has been successfully submitted and would be delivered to recipients shortly.