/******************************************************************************* * Copyright (c) 2004 Eric Merritt and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at http://www.eclipse.org/legal/epl-v10.html * * Contributors: * Eric Merritt * Vlad Dumitrescu *******************************************************************************/ package org.erlide.ui.editors.erl.autoedit; import java.util.Map; import java.util.TreeMap; 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.TextUtilities; import org.eclipse.ui.editors.text.EditorsUI; import org.eclipse.ui.texteditor.AbstractDecoratedTextEditorPreferenceConstants; import org.erlide.engine.ErlangEngine; import org.erlide.engine.model.IErlElement; import org.erlide.engine.model.erlang.IErlMember; import org.erlide.engine.services.text.IndentResult; import org.erlide.engine.services.text.IndentService; import org.erlide.ui.editors.erl.AbstractErlangEditor; import org.erlide.ui.editors.erl.ErlangEditor; import org.erlide.ui.internal.ErlideUIPlugin; import org.erlide.ui.prefs.plugin.IndentationPreferencePage; import org.erlide.util.ErlLogger; /** * The erlang auto indent strategy * * * @author Eric Merritt [cyberlync at gmail dot com] */ public class AutoIndentStrategy implements IAutoEditStrategy { // extends DefaultIndentLineAutoEditStrategy { private final AbstractErlangEditor editor; public AutoIndentStrategy(final AbstractErlangEditor editor) { super(); this.editor = editor; } private void autoIndentAfterNewLine(final IDocument d, final DocumentCommand c) { try { indentAfterNewLine(d, c); } catch (final BadLocationException e) { ErlLogger.warn(e); } } protected void indentAfterNewLine(final IDocument d, final DocumentCommand c) throws BadLocationException { if (editor == null) { return; } final int offset = c.offset; String txt = null; editor.reconcileNow(); final IErlElement element = editor.getElementAt(offset, false); final IErlMember member = (IErlMember) element; if (member != null) { final int start = member.getSourceRange().getOffset(); if (offset >= start) { txt = d.get(start, offset - start); } } if (txt == null) { txt = ""; } final int lineN = d.getLineOfOffset(offset); final int lineOffset = d.getLineOffset(lineN); final int lineLength = d.getLineLength(lineN); final String oldLine = d.get(offset, lineLength + lineOffset - offset); try { final int indentw = getIndentWidthFromPreferences(); final int tabw = EditorsUI.getPreferenceStore().getInt( AbstractDecoratedTextEditorPreferenceConstants.EDITOR_TAB_WIDTH); final Map<String, String> prefs = new TreeMap<>(); IndentationPreferencePage.addKeysAndPrefs(prefs); SmartTypingPreferencePage.addAutoNLKeysAndPrefs(prefs); final boolean useTabs = getUseTabsFromPreferences(); final IndentResult res = ErlangEngine.getInstance() .getService(IndentService.class) .indentLine(oldLine, txt, c.text, indentw, tabw, useTabs, prefs); if (res.isAddNewLine()) { c.text += "\n"; } c.text += res.getText(); c.length += res.getRemoveNext(); } catch (final Exception e) { ErlLogger.warn(e); } } /** * @return */ public static int getIndentWidthFromPreferences() { int tabw = ErlideUIPlugin.getDefault().getPreferenceStore() .getInt(ErlangEditor.EDITOR_INDENTATION_WIDTH); if (tabw == 0) { tabw = 4; } return tabw; } public static boolean getUseTabsFromPreferences() { return !EditorsUI.getPreferenceStore().getBoolean( AbstractDecoratedTextEditorPreferenceConstants.EDITOR_SPACES_FOR_TABS); } /** * Override a DocumentCommand if it ends with a line delim (CR) to include * space characters for autoindentation * * @param d * the document * @param c * the command */ @Override public void customizeDocumentCommand(final IDocument d, final DocumentCommand c) { if (c.length == 0 && c.text != null) { if (TextUtilities.endsWith(d.getLegalLineDelimiters(), c.text) != -1) { autoIndentAfterNewLine(d, c); } else if (c.text.endsWith(",")) { autoIndentAfterNewLine(d, c); } else if (c.text.endsWith(";")) { autoIndentAfterNewLine(d, c); } else if (c.text.endsWith(".")) { autoIndentAfterNewLine(d, c); } else if (c.text.endsWith(">")) { try { if (c.offset > 0 && c.offset <= d.getLength() && d.getChar(c.offset - 1) == '-') { autoIndentAfterNewLine(d, c); } } catch (final BadLocationException e) { // never mind... } } } } }