2014-11-19 2 views
0

Xtext에서 DSL을 개발하는 초보자입니다. 일치하는 코드 블록의 시작과 끝을 강조 표시하는 기능을 추가하고 싶습니다. 제 언어에서는 모든 함수가 'begin'으로 시작하고 'end'로 끝나야하며 조건과 루프가있는 경우와 동일해야합니다. 커서가 '시작'에있을 때 일치하는/해당 '끝'을 강조 표시해야합니다. 아래의 예를 들면, 나는 '시작'커서가 두 번째에있을 때 해당 첫 번째 '끝'을 강조해야하시기 바랍니다과'begin'- 'end'와 일치하는 항목을 찾아 강조 표시합니다.

function X 
    begin 
    if a>b 
     begin 
     a=b; 
     end 
    end 

어떤 도움?

감사합니다.

답변

1

나는 그다지 훌륭하다고 생각하지 않습니다. 미성년자 솔루션을 살 수 있다면 당신은 불행하게도 JFace는 단지 하나를 강조

public class MyDslCharacterPairMatcher extends DefaultCharacterPairMatcher { 

    public MyDslCharacterPairMatcher(char[] chars) { 
     super(chars); 
    } 


    @Override 
    public IRegion match(IDocument document, int offset, int length) { 
     if (document instanceof IXtextDocument) { 
      IXtextDocument xtextDocument = (IXtextDocument)document; 

      IRegion result = xtextDocument.readOnly(new IUnitOfWork<IRegion, XtextResource>() { 

       @Override 
       public IRegion exec(XtextResource state) throws Exception { 
        MyDslGrammarAccess ga = state.getResourceServiceProvider().get(MyDslGrammarAccess.class); 

        ICompositeNode root = state.getParseResult().getRootNode(); 
        ILeafNode matchNode = NodeModelUtils.findLeafNodeAtOffset(root, offset); 
        EObject object = NodeModelUtils.findActualSemanticObjectFor(matchNode); 
        if (object instanceof Greeting) { 
         Greeting g = (Greeting)object; 
         if (matchNode.getGrammarElement() == ga.getGreetingAccess().getIfKeyword_0()) { 
          ICompositeNode objectNode = NodeModelUtils.findActualNodeFor(object); 
          for (INode n : objectNode.getAsTreeIterable()) { 
           if (n.getGrammarElement() != null && n.getGrammarElement() == ga.getGreetingAccess().getEndifKeyword_2()) { 
            return new Region(n.getOffset(), n.getLength()); 
           } 
          } 
         } 
         if (matchNode.getGrammarElement() == ga.getGreetingAccess().getEndifKeyword_2()) { 
          ICompositeNode objectNode = NodeModelUtils.findActualNodeFor(object); 
          for (INode n : objectNode.getAsTreeIterable()) { 
           if (n.getGrammarElement() != null && n.getGrammarElement() == ga.getGreetingAccess().getIfKeyword_0()) { 
            return new Region(n.getOffset(), n.getLength()); 
           } 
          } 
         } 
        } 

        return null; 
       } 

      }); 
      if (result != null) { 
       return result; 
      } 
     } 
     return super.match(document, offset, length); 
    } 

} 

으로 UiModule

@Override 
public ICharacterPairMatcher bindICharacterPairMatcher() { 
    return new MyDslCharacterPairMatcher(new char[] { '(', ')', '{', '}', '[', ']' }); 
} 

에서 다음

문법

Model: 
    greetings+=Greeting*; 

Greeting: 
    'if' name=ID 'endif'; 

을 시도 할 수 캐릭터. 당신은 내가 당신이 IOccurrenceComputer 에 후크가 생각보다 원하는 경우 너무 많은 힌트를

package org.xtext.example.mydsl1.ui; 

import java.util.HashMap; 
import java.util.Map; 

import org.eclipse.core.runtime.SubMonitor; 
import org.eclipse.emf.ecore.EObject; 
import org.eclipse.jface.text.ITextSelection; 
import org.eclipse.jface.text.Position; 
import org.eclipse.jface.text.source.Annotation; 
import org.eclipse.xtext.nodemodel.ICompositeNode; 
import org.eclipse.xtext.nodemodel.ILeafNode; 
import org.eclipse.xtext.nodemodel.INode; 
import org.eclipse.xtext.nodemodel.util.NodeModelUtils; 
import org.eclipse.xtext.resource.XtextResource; 
import org.eclipse.xtext.ui.editor.XtextEditor; 
import org.eclipse.xtext.ui.editor.model.IXtextDocument; 
import org.eclipse.xtext.ui.editor.occurrences.DefaultOccurrenceComputer; 
import org.eclipse.xtext.util.CancelIndicator; 
import org.eclipse.xtext.util.TextRegion; 
import org.eclipse.xtext.util.concurrent.CancelableUnitOfWork; 
import org.xtext.example.mydsl1.myDsl.Greeting; 
import org.xtext.example.mydsl1.services.MyDslGrammarAccess; 

public class MyDslOccurrenceComputer extends DefaultOccurrenceComputer { 

    @Override 
    public Map<Annotation, Position> createAnnotationMap(XtextEditor editor, 
      ITextSelection selection, SubMonitor monitor) { 

     final IXtextDocument document = editor.getDocument(); 

     if (document != null) { 
      Map<Annotation, Position> result = document.readOnly(new CancelableUnitOfWork<Map<Annotation, Position>, XtextResource>() { 

       @Override 
       public Map<Annotation, Position> exec(XtextResource state, 
         final CancelIndicator cancelIndicator) throws Exception { 
        MyDslGrammarAccess ga = state.getResourceServiceProvider() 
          .get(MyDslGrammarAccess.class); 

        ICompositeNode root = state.getParseResult().getRootNode(); 
        ILeafNode matchNode = NodeModelUtils.findLeafNodeAtOffset(
          root, selection.getOffset()); 
        EObject object = NodeModelUtils 
          .findActualSemanticObjectFor(matchNode); 
        if (object instanceof Greeting) { 
         Greeting g = (Greeting) object; 
         if (matchNode.getGrammarElement() == ga 
           .getGreetingAccess().getIfKeyword_0()) { 
          ICompositeNode objectNode = NodeModelUtils 
            .findActualNodeFor(object); 
          for (INode n : objectNode.getAsTreeIterable()) { 
           if (n.getGrammarElement() != null 
             && n.getGrammarElement() == ga 
               .getGreetingAccess() 
               .getEndifKeyword_3()) { 
            Map<Annotation, Position> result = new HashMap<>(); 
            addOccurrenceAnnotation(
              DECLARATION_ANNOTATION_TYPE, 
              document, 
              new TextRegion(matchNode 
                .getOffset(), matchNode 
                .getLength()), result); 
            addOccurrenceAnnotation(
              OCCURRENCE_ANNOTATION_TYPE, 
              document, 
              new TextRegion(n.getOffset(), n 
                .getLength()), result); 
            return result; 

           } 
          } 
         } 
         if (matchNode.getGrammarElement() == ga 
           .getGreetingAccess().getEndifKeyword_3()) { 
          ICompositeNode objectNode = NodeModelUtils 
            .findActualNodeFor(object); 
          for (INode n : objectNode.getAsTreeIterable()) { 
           if (n.getGrammarElement() != null 
             && n.getGrammarElement() == ga 
               .getGreetingAccess() 
               .getIfKeyword_0()) { 
            Map<Annotation, Position> result = new HashMap<>(); 
            addOccurrenceAnnotation(
              DECLARATION_ANNOTATION_TYPE, 
              document, 
              new TextRegion(matchNode 
                .getOffset(), matchNode 
                .getLength()), result); 
            addOccurrenceAnnotation(
              OCCURRENCE_ANNOTATION_TYPE, 
              document, 
              new TextRegion(n.getOffset(), n 
                .getLength()), result); 
            return result; 
           } 
          } 
         } 
        } 
        return null; 
       } 
      }); 
      if (result != null) { 
       return result; 
      } 
     } 
     return super.createAnnotationMap(editor, selection, monitor); 
    } 

} 
+0

감사를 (당신이 다음에 표시 발행 수 있어야한다). 어디서나 MyDslOccurrenceComputer를 바인딩해야합니까? – Shereen

+1

ui 모듈에서 '예'public class bindIOccurrenceComputer() {return MyDslOccurrenceComputer.class;} –

+0

나와 함께 작동하지 않습니다 – Shereen

관련 문제