weixin_39866874
weixin_39866874
2020-11-30 17:14

R outline improved for environments and R6 classes, = sign added as well

Dear Reviewer of this pull request. The suggested pull request improves the outline facilitities for R using geany. First it is now possible also to use the = sign as the assignment operator for functions, secondly I added support for R6Class(es), environments (new.env) and a generic RxClass which can be used as well for outline creation. The latter allows for instance to write workaround code like RxClass = proto

and then

obj=RxClass() th Best regards, Detlef Groth

该提问来源于开源项目:geany/geany

  • 点赞
  • 写回答
  • 关注问题
  • 收藏
  • 复制链接分享
  • 邀请回答

10条回答

  • weixin_39767513 weixin_39767513 5月前

    we are trying to not diverge from those

    Too late:

    diff
    --- r-geany.c   2019-10-21 16:54:35.032407824 -0700
    +++ r-upstream.c    2019-10-21 16:53:25.426404697 -0700
    @@ -19,10 +19,10 @@
    
     #include "debug.h"
     #include "entry.h"
    +#include "parse.h"
     #include "read.h"
    +#include "selectors.h"
     #include "vstring.h"
    -#include "routines.h"
    -
    
     #define SKIPSPACE(ch) while (isspace((int)*ch)) \
       ch++
    @@ -31,22 +31,27 @@
        K_FUNCTION,
        K_LIBRARY,
        K_SOURCE,
    +   K_GLOBALVAR,
    +   K_FUNCVAR,
        KIND_COUNT
     } rKind;
    
    -static kindDefinition RKinds [KIND_COUNT] = {
    +static kindDefinition RKinds[KIND_COUNT] = {
        {true, 'f', "function", "functions"},
        {true, 'l', "library", "libraries"},
        {true, 's', "source", "sources"},
    +   {true, 'g', "globalVar", "global variables"},
    +   {true, 'v', "functionVar", "function variables"},
     };
    
     static void makeRTag (const vString * const name, rKind kind)
     {
        tagEntryInfo e;
    -   initTagEntry(&e, vStringValue(name), kind);
    
        Assert (kind < KIND_COUNT);
    
    +   initTagEntry (&e, vStringValue (name), kind);
    +
        makeTagEntry (&e);
     }
    
    @@ -66,93 +71,124 @@
            {
                /* iterate to the end of line or to a comment */
                ikind = -1;
    -           switch (*cp) {
    -               case 'l':
    -               case 's':
    -                   if (strncasecmp((const char*)cp, "library", (size_t)7) == 0) {
    -                       /* load a library: library(tools) */
    -                       cp += 7;
    -                       SKIPSPACE(cp);
    -                       if (*cp == '(')
    -                           ikind = K_LIBRARY;
    -                       else
    -                           cp -= 7;
    -                   } else if (strncasecmp((const char*)cp, "source", (size_t)6) == 0) {
    -                       /* load a source file: source("myfile.r") */
    -                       cp += 6;
    -                       SKIPSPACE(cp);
    -                       if (*cp == '(')
    -                           ikind = K_SOURCE;
    -                       else
    -                           cp -= 6;
    -                   }
    -                   if (ikind != -1) {
    +           switch (*cp)
    +           {
    +           case 'l':
    +           case 's':
    +               if (strncasecmp ((const char *) cp, "library", (size_t) 7) == 0)
    +               {
    +                   /* load a library: library(tools) */
    +                   cp += 7;
    +                   SKIPSPACE (cp);
    +                   if (*cp == '(')
    +                       ikind = K_LIBRARY;
    +                   else
    +                       cp -= 7;
    +               }
    +               else if (strncasecmp ((const char *) cp, "source",
    +                       (size_t) 6) == 0)
    +               {
    +                   /* load a source file: source("myfile.r") */
    +                   cp += 6;
    +                   SKIPSPACE (cp);
    +                   if (*cp == '(')
    +                       ikind = K_SOURCE;
    +                   else
    +                       cp -= 6;
    +               }
    +               if (ikind != -1)
    +               {
    +                   cp++;
    +
    +                   vStringClear (name);
    +                   while ((!isspace ((int) *cp)) && *cp != '\0' && *cp != ')')
    +                   {
    +                       vStringPut (name, (int) *cp);
                            cp++;
    +                   }
    +
    +                   /* if the string really exists, make a tag of it */
    +                   if (vStringLength (name) > 0)
    +                       makeRTag (name, ikind);
    +
    +                   /* prepare for the next iteration */
    +                   vStringClear (name);
    +               }
    +               else
    +               {
    +                   vStringPut (name, (int) *cp);
    +                   cp++;
    +               }
    +               break;
    +           case ' 0)
    -                           makeRTag(name, ikind);
    +                       if (vStringLength (name) > 0)
    +                           makeRTag (name, K_FUNCTION);
    
                            /* prepare for the next iteration */
    -                       vStringClear(name);
    -                   } else {
    -                       vStringPut(name, (int)*cp);
    -                       cp++;
    +                       vStringClear (name);
    +                       break;
                        }
    -                   break;
    -               case ' 0)
    +                       {
    +                           if (line[0] == ' ' || line[0] == '\t')
    +                               makeRTag (name, K_FUNCVAR);
    +                           else
    +                               makeRTag (name, K_GLOBALVAR);
                            }
    
    -                       if (strncasecmp((const char*)cp, "function", (size_t)8) == 0) {
    -                           /* it's a function: ident  0)
    -                               makeRTag(name, K_FUNCTION);
    -
    -                           /* prepare for the next iteration */
    -                           vStringClear(name);
    -                           break;
    -                       }
    +                       /* prepare for the next iteration */
    +                       vStringClear (name);
    +                       break;
                        }
    -                   /* fall through */
    -               case ' ':
    -               case '\x009':
    -                   /* skip whitespace */
    -                   cp++;
    -                   break;
    -               default:
    -                   /* collect all characters that could be a part of an identifier */
    -                   vStringPut(name, (int)*cp);
    -                   cp++;
    -                   break;
    +               }
    +           case ' ':
    +           case '\x009':
    +               /* skip whitespace */
    +               cp++;
    +               break;
    +           default:
    +               /* collect all characters that could be a part of an identifier */
    +               vStringPut (name, (int) *cp);
    +               cp++;
    +               break;
                }
            }
        }
    @@ -163,14 +199,17 @@
    
     extern parserDefinition *RParser (void)
     {
    -   /* *.r: R files
    +   /* *.r;*.R: R files
         * *.s;*.q: S files
         */
    -   static const char *const extensions [] = { "r", "s", "q", NULL };
    +   static const char *const extensions[] = { "r", "R", "s", "q", NULL };
        parserDefinition *const def = parserNew ("R");
    -   def->kindTable  = RKinds;
    -   def->kindCount  = ARRAY_SIZE (RKinds);
    +   static selectLanguage selectors[] = { selectByArrowOfR,
    +                         NULL };
        def->extensions = extensions;
    -   def->parser     = createRTags;
    +   def->kindTable = RKinds;
    +   def->kindCount = KIND_COUNT;
    +   def->parser = createRTags;
    +   def->selectLanguage = selectors;
        return def;
     }
    
    点赞 评论 复制链接分享
  • weixin_39713841 weixin_39713841 5月前

    That just shows there is a difference.

    Its not unexpected that upstream has diverged from us since it takes forever to get changes incorporated in Geany since nobody (including me) will review and test them.

    点赞 评论 复制链接分享
  • weixin_39713841 weixin_39713841 5月前

    Or to put it another way, we should not make changes to Geany ctags parsers that are not made in upstream, changes in upstream are to be expected and we want to be able to import them simply, which won't happen if we also have changes.

    点赞 评论 复制链接分享
  • weixin_39767513 weixin_39767513 5月前

    changes in upstream are to be expected and we want to be able to import them simply

    Yeah, but should backporting/integrating/vetting all the upstream changes back into Geany be something a contributor working off our fork (necessarily, since they're hacking on Geany) should be responsible for? It would be different if we kept our fork up-to-date.

    点赞 评论 复制链接分享
  • weixin_39713841 weixin_39713841 5月前

    Well its up to them of course, but making it harder will probably mean things go slower for everybody, not just them.

    点赞 评论 复制链接分享
  • weixin_39866874 weixin_39866874 5月前

    So basically I have to fork universal-ctags/ctags put my extensions in and make a pull request there if I would like to have support for the = sign and R6Class syntax in geany at some point later?

    点赞 评论 复制链接分享
  • weixin_39713841 weixin_39713841 5月前

    you don't have to, but as I said ctags stuff is not happening very fast ATM because the main reviewer is overloaded (mostly by real life, not just Geany).

    If the change applies cleanly to Geany's parser after its accepted upstream it might move quicker here since it doesn't need the overloaded ctags expert to review it, and somebody else might do so and merge it. The changes to the symbols mapping don't apply to upstream of course so they would need a local review, but its much smaller that way.

    点赞 评论 复制链接分享
  • weixin_39880615 weixin_39880615 5月前

    , I'm rewriting R parser in token oriented way in the upstream. https://github.com/universal-ctags/ctags/pull/2452

    The support for assignment operators is improved. It includes '->'. The class supports come later. However, if test cases are given, I would like to merge your change.

    点赞 评论 复制链接分享
  • weixin_39880615 weixin_39880615 5月前

    u-ctags now supports R6Class(x) ( and setClass() ). See https://github.com/universal-ctags/ctags/pull/2671.

    点赞 评论 复制链接分享
  • weixin_39713841 weixin_39713841 5月前

    Please push the changes upstream to Universal Ctags, we are trying to not diverge from those, otherwise updating to there improvements is difficult.

    点赞 评论 复制链接分享

相关推荐