xtext 中的自动漂亮格式
auto pretty formatting in xtext
我想问有没有一种方法可以在不使用 (ctrl+shift+f) 或从首选项菜单中打开它的情况下自动在 xtext 中进行漂亮的格式化。我真正想要的是,每当用户完成编写代码时,它会自动格式化(或在运行时)而无需 (ctrl+shift+f).
有一种方法可以做到这一点,称为 "AutoEdit"。这不是用户完成写作的确切时间,而是每个令牌。这至少是我所做的。你肯定可以改变它。我会给你一个我自己为我的项目实现的例子。它基本上在用户键入时将每个关键字大写(由空格和结尾触发)。
这是一件 UI 的事情。所以,在您的 UI 项目中:
在 MyDslUiModule.java 中,您需要附加自定义的自动编辑 class 这样做:
public Class<? extends DefaultAutoEditStrategyProvider> bindDefaultAutoEditStrategyProvider()
{
return MyDslAutoEditStrategyProvider.class;
}
我们的 class 将被称为 MyDslAutoEditStrategyProvider 所以,继续在 MyDslAutoEditStrategyProvider.java 文件中创建它。我有这个来做我在介绍中解释的事情:
import java.util.Set;
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.GrammarUtil;
import org.eclipse.xtext.IGrammarAccess;
import org.eclipse.xtext.ui.editor.autoedit.DefaultAutoEditStrategyProvider;
import org.eclipse.xtext.ui.editor.model.XtextDocument;
import com.google.inject.Inject;
import com.google.inject.Provider;
public class MyDslAutoEditStrategyProvider extends DefaultAutoEditStrategyProvider {
@Inject
Provider<IGrammarAccess> iGrammar;
private Set<String> KWDS;
@Override
protected void configure(IEditStrategyAcceptor acceptor) {
KWDS = GrammarUtil.getAllKeywords(iGrammar.get().getGrammar());
IAutoEditStrategy strategy = new IAutoEditStrategy()
{
@Override
public void customizeDocumentCommand(IDocument document, DocumentCommand command)
{
if ( command.text.length() == 0 || command.text.charAt(0) > ' ') return;
IRegion reg = ((XtextDocument) document).getLastDamage();
try {
String token = document.get(reg.getOffset(), reg.getLength());
String possibleKWD = token.toLowerCase();
if ( token.equals(possibleKWD.toUpperCase()) || !KWDS.contains(possibleKWD) ) return;
document.replace(reg.getOffset(), reg.getLength(), possibleKWD.toUpperCase());
}
catch (Exception e)
{
System.out.println("AutoEdit error.\n" + e.getMessage());
}
}
};
acceptor.accept(strategy, IDocument.DEFAULT_CONTENT_TYPE);
super.configure(acceptor);
}
}
我假设你说 "user completes writing" 可以是 "user saves file"。如果是这样,这里是如何在保存时触发格式化程序:
在MyDslUiModule.java中:
public Class<? extends XtextDocumentProvider> bindXtextDocumentProvider()
{
return MyDslDocumentProvider.class;
}
创建 MyDslDocumentProvider class:
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.jface.text.IDocument;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.handlers.IHandlerService;
import org.eclipse.xtext.ui.editor.model.XtextDocumentProvider;
public class MyDslDocumentProvider extends XtextDocumentProvider
{
@Override
protected void doSaveDocument(IProgressMonitor monitor, Object element, IDocument document, boolean overwrite)
throws CoreException {
IHandlerService service = (IHandlerService) PlatformUI.getWorkbench().getService(IHandlerService.class);
try {
service.executeCommand("org.eclipse.xtext.ui.FormatAction", null);
} catch (Exception e)
{
e.printStackTrace();
}
super.doSaveDocument(monitor, element, document, overwrite);
}
}
我想问有没有一种方法可以在不使用 (ctrl+shift+f) 或从首选项菜单中打开它的情况下自动在 xtext 中进行漂亮的格式化。我真正想要的是,每当用户完成编写代码时,它会自动格式化(或在运行时)而无需 (ctrl+shift+f).
有一种方法可以做到这一点,称为 "AutoEdit"。这不是用户完成写作的确切时间,而是每个令牌。这至少是我所做的。你肯定可以改变它。我会给你一个我自己为我的项目实现的例子。它基本上在用户键入时将每个关键字大写(由空格和结尾触发)。
这是一件 UI 的事情。所以,在您的 UI 项目中:
在 MyDslUiModule.java 中,您需要附加自定义的自动编辑 class 这样做:
public Class<? extends DefaultAutoEditStrategyProvider> bindDefaultAutoEditStrategyProvider()
{
return MyDslAutoEditStrategyProvider.class;
}
我们的 class 将被称为 MyDslAutoEditStrategyProvider 所以,继续在 MyDslAutoEditStrategyProvider.java 文件中创建它。我有这个来做我在介绍中解释的事情:
import java.util.Set;
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.GrammarUtil;
import org.eclipse.xtext.IGrammarAccess;
import org.eclipse.xtext.ui.editor.autoedit.DefaultAutoEditStrategyProvider;
import org.eclipse.xtext.ui.editor.model.XtextDocument;
import com.google.inject.Inject;
import com.google.inject.Provider;
public class MyDslAutoEditStrategyProvider extends DefaultAutoEditStrategyProvider {
@Inject
Provider<IGrammarAccess> iGrammar;
private Set<String> KWDS;
@Override
protected void configure(IEditStrategyAcceptor acceptor) {
KWDS = GrammarUtil.getAllKeywords(iGrammar.get().getGrammar());
IAutoEditStrategy strategy = new IAutoEditStrategy()
{
@Override
public void customizeDocumentCommand(IDocument document, DocumentCommand command)
{
if ( command.text.length() == 0 || command.text.charAt(0) > ' ') return;
IRegion reg = ((XtextDocument) document).getLastDamage();
try {
String token = document.get(reg.getOffset(), reg.getLength());
String possibleKWD = token.toLowerCase();
if ( token.equals(possibleKWD.toUpperCase()) || !KWDS.contains(possibleKWD) ) return;
document.replace(reg.getOffset(), reg.getLength(), possibleKWD.toUpperCase());
}
catch (Exception e)
{
System.out.println("AutoEdit error.\n" + e.getMessage());
}
}
};
acceptor.accept(strategy, IDocument.DEFAULT_CONTENT_TYPE);
super.configure(acceptor);
}
}
我假设你说 "user completes writing" 可以是 "user saves file"。如果是这样,这里是如何在保存时触发格式化程序:
在MyDslUiModule.java中:
public Class<? extends XtextDocumentProvider> bindXtextDocumentProvider()
{
return MyDslDocumentProvider.class;
}
创建 MyDslDocumentProvider class:
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.jface.text.IDocument;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.handlers.IHandlerService;
import org.eclipse.xtext.ui.editor.model.XtextDocumentProvider;
public class MyDslDocumentProvider extends XtextDocumentProvider
{
@Override
protected void doSaveDocument(IProgressMonitor monitor, Object element, IDocument document, boolean overwrite)
throws CoreException {
IHandlerService service = (IHandlerService) PlatformUI.getWorkbench().getService(IHandlerService.class);
try {
service.executeCommand("org.eclipse.xtext.ui.FormatAction", null);
} catch (Exception e)
{
e.printStackTrace();
}
super.doSaveDocument(monitor, element, document, overwrite);
}
}