【问题标题】:Eclipse editor plug-in: syntax highlightingEclipse 编辑器插件:语法高亮
【发布时间】:2014-07-09 20:36:53
【问题描述】:

我正在开发一个自定义语言的编辑器插件,并且我已经设法设置它,以便突出显示所有必要的关键字。问题是即使它们是另一个词的一部分,这些词也会被突出显示。

例如:假设public 是一个关键字,我初始化了一个名为publicVar 的变量,所以它看起来像这样public int publicVarpublic 按预期突出显示,但 publicVar 的“公共”部分也突出显示,这不是我想要的。

public WFSPartitionScanner()
{

    int index = 0;
    int numOfRules = 5 + reversedWords.length + commonFunctions.length+directives.length + 
            BIFs.length + operators.length + strongOperators.length;
    IToken string = new Token(WFS_STRING);
    IToken comment = new Token(WFS_COMMENT);
    IToken reversedWord = new Token(WFS_REVERSED_WORD);
    IToken commonFunction = new Token(WFS_COMMON_FUNCTION);
    IToken directive = new Token(WFS_DIRECTIVE);
    IToken bif = new Token(WFS_BIF);
    IToken operator = new Token(WFS_OPERATOR);
    IToken strongOperator = new Token(WFS_STRONG_OPERATOR);
    IToken numberToken = new Token(WFS_NUMBER);

    IPredicateRule[] rules= new IPredicateRule[numOfRules];

    rules[index] = new MultiLineRule("\"","\"", string, '\\');
    rules[++index] = new MultiLineRule("\'", "\'", string, '\\');
    rules[++index] = new SingleLineRule("//","\n", comment);
    rules[++index] = new MultiLineRule("/*", "*/", comment);
    rules[++index] = new WFSNumberRule(numberToken);

    for(int i = 0;  i < reversedWords.length;  i++)
    {
        rules[++index] = new WordPatternRule(new WordDetector(reversedWords[i]), reversedWords[i], "",reversedWord);
    }
    for(int i = 0; i < commonFunctions.length; i++)
    {
        rules[++index] = new WordPatternRule(new WordDetector(commonFunctions[i]), commonFunctions[i], "",commonFunction);
    }
    for(int i = 0; i < BIFs.length;i++)
    {
        rules[++index] = new WordPatternRule(new WordDetector(BIFs[i]), BIFs[i], "",bif);
    }
    for(int i = 0; i < directives.length;i++)
    {
        rules[++index] = new WordPatternRule(new WordDetector(directives[i]), directives[i], "",directive);
    }
    for(int i=0; i < operators.length; i++)
    {
        rules[++index]= new WordPatternRule(new WordDetector(operators[i]), operators[i], "", operator);
    }
    for(int i=0; i < strongOperators.length; i++)
    {
        rules[++index]= new WordPatternRule(new WordDetector(strongOperators[i]), strongOperators[i], "", strongOperator);
    }

    setPredicateRules(rules);
}

public class WordDetector implements IWordDetector{
private char start;
private char[] part;

public WordDetector(String word)
{
    this.start = word.charAt(0);
    this.part = new char[word.length() - 1];
    for(int i = 1; i < word.length(); i++)
    {
        part[i-1] = word.charAt(i); 
    }

}
@Override
public boolean isWordPart(char c) {

    for(int i = 0; i < part.length; i++)
    {
        if(c == part[i])
        {
            return true;
        }   
    }
    return false;
}

@Override
public boolean isWordStart(char c) {

    return (c == start);
}
}

我也尝试过将 WordPatternRule

WordPatternRule(new WordDetector('KEYWORD'), 'KEYWORD', "",reversedWord);

 WordPatternRule(new WordDetector('KEYWORD'), 'FIRST LETTER OF KEYWORD', 'LAST LETTER OF KEYWORD,reversedWord); 

但我得到了相同的结果。

【问题讨论】:

  • org.eclipse.jdt.internal.ui.text.CombinedWordRule(在 JDT 中)看起来像你想要的那样,看看那个。

标签: eclipse eclipse-plugin editor syntax-highlighting jface


【解决方案1】:

好的,我发现了部分问题。为了解决这个问题,我制作了自己的 WORDRULE

public class WFSWordRule extends WordRule implements IPredicateRule{

private IToken successToken;

public WFSWordRule(IWordDetector detector, String[] keywords, IToken token ) {
    super(detector);
    this.successToken= token;
      for (String word : keywords) {
        addWord(word, token);
      }
}


@Override
public IToken evaluate(ICharacterScanner scanner, boolean arg1) {

    return super.evaluate(scanner);
}

@Override
public IToken getSuccessToken() {

    return successToken;
}

}

但这并不能完全解决问题。现在,如果单词末尾有关键字,则该关键字仍会突出显示。使用与之前相同的示例,如果我有一个关键字“Public”并且我有一个名为“varPublic”的变量,那么在这两种情况下都会突出显示 public。但是,如果我有一个名为“PublicVar”的变量,则不会突出显示 public。有什么建议吗?

【讨论】:

    【解决方案2】:

    如果您想突出显示单词,而不是单词的一部分,我认为您应该使用 WordRule 而不是 WordPatternRule,就像您一样。据我了解,WordPatternRule 用于查找单词中的模式,而 WordRule 用于查找单个单词。

    我在我一直在研究的 Eclipse 插件中使用了 WordRules,并且我没有遇到在其他单词中突出显示单词的问题。您可以查看its code 并将其用作示例。基本上,它需要一个 IWordDetector 实现,并且您使用它的 addWord 方法来添加您希望它检测的所有单词。

    与 greg-449 提到的 CombinedWordRule 不同,它是您已经在使用的 JFace 框架的公共部分。

    【讨论】:

      【解决方案3】:

      不确定,如果这仍然有用,但我通过覆盖我的扫描仪中的方法 nextToken 解决了这个问题:

      public IToken nextToken() {
      
          if (this.fContentType == null || this.fRules == null) {
            // don't try to resume
            this.fTokenOffset = this.fOffset;
            this.fColumn = RuleBasedScanner.UNDEFINED;
      
            if (this.fRules != null) {
              for (IRule fRule : this.fRules) {
                IToken token = fRule.evaluate(this);
                try {
                  if (!token.isUndefined()) {
                    if (this.fTokenOffset > 0 && (isWordEnd(this.fDocument.getChar(this.fTokenOffset - 1))
                        || isSpecialKey(this.fDocument.getChar(this.fTokenOffset)))) {
                      this.fContentType = null;
                      return token;
                    }
                  }
                } catch (BadLocationException ex) {
                  ex.printStackTrace();
                }
              }
            }
      
            if (this.read() == ICharacterScanner.EOF) {
              return Token.EOF;
              }
              return this.fDefaultReturnToken;
          }
      }
      

      isWordEnd 检查:

      c == (char) 0 || c == ' ' || c == '\t' || c == '\n' || c == '\r' || c == '(' || c == ')' || c == ',' || c == ';'
      

      isSpecialKey 检查:

      c == '%'
      

      对于另一个问题,您已经修复了,我在我的规则中重新实现了endSequenceDetected 方法:

      @Override
      protected boolean endSequenceDetected(ICharacterScanner scanner) {
          int c = scanner.read();
          scanner.unread();
          return isWordEnd((char) c);
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2011-11-28
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2010-09-29
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多