Eclipse编辑器插件:语法高亮

时间:2014-07-09 20:36:53

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

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

例如:我们说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); 

但我得到了相同的结果。

3 个答案:

答案 0 :(得分:0)

好的我找出了部分问题。为了解决这个问题,我制作了自己的单词

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;
}

}

但是,这并没有完全解决问题。现在,如果单词末尾有关键字,则关键字仍会突出显示。使用与以前相同的示例,如果我有一个关键字&#39; Public&#39;我有一个名为&#39; varPublic&#39;两种情况都突出了公众。但如果我有一个名为&#39; PublicVar&#39;公众没有突出显示。任何提示?

答案 1 :(得分:0)

如果你试图突出显示单词,而不是单词的一部分,我认为你应该使用WordRule而不是WordPatternRule。据我所知,WordPatternRule用于查找单词中的模式,而WordRule用于查找单个单词。

我已经在Eclipse插件中使用过WordRules,我一直在努力工作,而且我不会在其他单词中突出显示单词的问题。您可以查看its code并将其用作示例。基本上,它需要IWordDetector实现,并使用其 addWord 方法添加您想要检测的所有单词。

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

答案 2 :(得分:0)

不确定,如果这仍然有用,但我通过覆盖扫描程序中的方法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);
}