1

How to get a tab space for beautification after writing a statement in Xtext.
Here is my code is in Xtext grammar :

 Block:
      '_block' 
         name=ID
     '_endblock' 
    ;

and UI template is

override complete_BLOCK(EObject model, RuleCall ruleCall, ContentAssistContext context, ICompletionProposalAcceptor acceptor) {
      super.complete_BLOCK(model, ruleCall, context, acceptor)
      acceptor.accept(createCompletionProposal("_block \n    
    _endblock","_block",null,context));

}

How do I indent for a tab space after writing a block statement?

Thomas Fritsch
  • 9,639
  • 33
  • 37
  • 49
Chaitanya
  • 11
  • 6
  • is this about content assist, about auto edit, or about formatters – Christian Dietrich Oct 02 '17 at 20:16
  • i have xtext parser rule like this Block: '_block' name=ID '_endblock' ; for this i have written a template in class MydslProposalProvider extends AbstractMagikProposalProvider { override complete_BLOCK(EObject model, RuleCall ruleCall, ContentAssistContext context, ICompletionProposalAcceptor acceptor) { super.complete_BLOCK(model, ruleCall, context, acceptor) acceptor.accept(createCompletionProposal("_block \n _endblock","_block",null,context));} – Chaitanya Oct 03 '17 at 05:34
  • i have formatter like this def dispatch void format(BLOCK block, extension IFormattableDocument document) { val ds =block.blbody block.allRegionsFor.keywords(",").forEach[append[oneSpace; autowrap]] block.allRegionsFor.keyword("_block").append[newLine].surround[newLine] block.allRegionsFor.keyword("_endblock").prepend[newLine] interior( block.regionFor.keyword("_block").append[newLine].surround[newLine] , block.regionFor.keyword("_endblock").prepend[newLine] )[indent] block.blbody.forEach[format] – Chaitanya Oct 03 '17 at 05:37
  • no what is your question about. formatting, content assist and auto edit are 3 different things – Christian Dietrich Oct 03 '17 at 05:41
  • it is working with indentation when i hit formatter through format option but i need when i click my template and i hit enter directly i need a tab space like class A { } gives a tab space in java – Chaitanya Oct 03 '17 at 05:50
  • this feature is called autoedit and you need to implement a customization of DefaultAutoEditStrategyProvider – Christian Dietrich Oct 03 '17 at 05:51
  • hi christian,i am asking about formatting – Chaitanya Oct 03 '17 at 05:57
  • if you want to format you have to call the formatter ?!? – Christian Dietrich Oct 03 '17 at 05:58
  • can you please share the steps to do that – Chaitanya Oct 03 '17 at 05:59
  • see my answer below – Christian Dietrich Oct 03 '17 at 06:05

1 Answers1

4

to implement a formatter

  1. open the mwe2 file
  2. add formatter = {generateStub = true} to the language = StandardLanguage { section of the workflow
  3. regenerate the language
  4. open the MyDslFormatter Xtend class and implement it

to call the formatter

  1. mark the section to format or dont mark to format everything
  2. call rightclick -> Source -> Format or the Shortcut Cmd/Crtl + Shift + F

here is a very naive no failsafe impl of an auto edit strategy

package org.xtext.example.mydsl1.ui;

import org.eclipse.jface.text.BadLocationException;
import org.eclipse.jface.text.DocumentCommand;
import org.eclipse.jface.text.IAutoEditStrategy;
import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.IRegion;
import org.eclipse.xtext.ui.editor.autoedit.DefaultAutoEditStrategyProvider;

import com.google.inject.Inject;
import com.google.inject.Provider;

public class YourAutoEditStrategyProvider extends DefaultAutoEditStrategyProvider {

    public static class BlockStrategy implements IAutoEditStrategy {

        private static final String BLOCK =  "_block";

        protected int findEndOfWhiteSpace(IDocument document, int offset, int end) throws BadLocationException {
            while (offset < end) {
                char c= document.getChar(offset);
                if (c != ' ' && c != '\t') {
                    return offset;
                }
                offset++;
            }
            return end;
        }

        @Override
        public void customizeDocumentCommand(IDocument d, DocumentCommand c) {
            if ("\n".equals(c.text)) {
                if (d.getLength()> BLOCK.length()) {
                    try {
                        if ((BLOCK+" ").equals(d.get(c.offset-BLOCK.length()-1, BLOCK.length()+1)) || (BLOCK).equals(d.get(c.offset-BLOCK.length(), BLOCK.length()))) {
                            int p= (c.offset == d.getLength() ? c.offset  - 1 : c.offset);
                            IRegion info= d.getLineInformationOfOffset(p);
                            int start= info.getOffset();

                            // find white spaces
                            int end= findEndOfWhiteSpace(d, start, c.offset);
                            int l = 0;
                            StringBuilder buf= new StringBuilder(c.text);
                            if (end > start) {
                                // append to input
                                buf.append(d.get(start, end - start));
                                l += (end - start);
                            }

                            buf.append("\t");
                            buf.append("\n");
                            buf.append(d.get(start, end - start));

                            c.text= buf.toString();
                            c.caretOffset = c.offset+2+l;
                            c.shiftsCaret=false;
                        }
                    } catch (BadLocationException e) {
                        e.printStackTrace();
                    }
                }
            }
        }

    }

    @Inject
    private Provider<BlockStrategy> blockStrategy;

    @Override
    protected void configure(IEditStrategyAcceptor acceptor) {
        super.configure(acceptor);
        acceptor.accept(blockStrategy.get(), IDocument.DEFAULT_CONTENT_TYPE);
    }

}

and dont forget to bind

class MyDslUiModule extends AbstractMyDslUiModule {

    override bindAbstractEditStrategyProvider() {
        YourAutoEditStrategyProvider
    }

}
Christian Dietrich
  • 11,778
  • 4
  • 24
  • 32
  • thnx christian, i did the above procedure for formatting and it is working fine in my window, i have a question like can we do auto formatting like it should append a tab space when we entering into a new line like java class do – Chaitanya Oct 03 '17 at 06:26
  • as i said: no. the only thing you can do is autoedit. gave you the pointers to look for – Christian Dietrich Oct 03 '17 at 06:31
  • btw this is configured out of the box so if you type enter between the brackets in `class xxx {}` you get the cursor indented after the newline – Christian Dietrich Oct 03 '17 at 06:35
  • you dont add it there. you simply add a binding. please read the docs on DI https://www.eclipse.org/Xtext/documentation/302_configuration.html#dependency-injection – Christian Dietrich Oct 03 '17 at 09:26