/** * Aptana Studio * Copyright (c) 2005-2011 by Appcelerator, Inc. All Rights Reserved. * Licensed under the terms of the GNU Public License (GPL) v3 (with exceptions). * Please see the license.html included with this distribution for details. * Any modifications to this file must keep this entire header intact. */ package com.aptana.editor.haml; import java.util.regex.Pattern; import org.eclipse.jface.preference.IPreferenceStore; import org.eclipse.jface.text.BadLocationException; import org.eclipse.jface.text.DocumentCommand; import org.eclipse.jface.text.IDocument; import org.eclipse.jface.text.IRegion; import org.eclipse.jface.text.source.ISourceViewer; import org.eclipse.jface.text.source.SourceViewerConfiguration; import com.aptana.core.logging.IdeLog; import com.aptana.core.util.StringUtil; import com.aptana.editor.common.text.RubyRegexpAutoIndentStrategy; public class HAMLAutoIndentStrategy extends RubyRegexpAutoIndentStrategy { private static final String TAG_OR_FILTER_ONLY = "^\\s*[%:](\\w|\\.|#)+"; //$NON-NLS-1$ private static final Pattern BEGIN_WITH_TAG_OR_FILTER = Pattern .compile("^\\s*[%:](?!area|base|br|col|hr|img|input|link|meta|param)(\\w|\\.)+.*$"); //$NON-NLS-1$ private static final Pattern ATTRIBUTE = Pattern.compile("^\\s*\\{.*\\}\\s*$"); //$NON-NLS-1$ public HAMLAutoIndentStrategy(String contentType, SourceViewerConfiguration configuration, ISourceViewer sourceViewer, IPreferenceStore prefStore) { super(contentType, configuration, sourceViewer, prefStore); } @Override protected boolean autoIndent(IDocument d, DocumentCommand c) { if (c.offset <= 0 || d.getLength() == 0 || !shouldAutoIndent()) { return false; } String newline = c.text; try { // Get the line and run a regexp check against it IRegion curLineRegion = d.getLineInformationOfOffset(c.offset); String lineContent = d.get(curLineRegion.getOffset(), c.offset - curLineRegion.getOffset()).trim(); boolean shouldAutoIndent = false; // check for ruby blocks if (lineContent.length() > 1 && lineContent.charAt(0) == '-' && lineContent.endsWith("|")) //$NON-NLS-1$ { shouldAutoIndent = true; } else if (BEGIN_WITH_TAG_OR_FILTER.matcher(lineContent).matches() && !lineContent.endsWith("/")) //$NON-NLS-1$ { // Remove the tag/filter and check if there is content after. If there is, we only want to indent if // it's an attribute String contentWithoutTagFilter = lineContent.replaceAll(TAG_OR_FILTER_ONLY, StringUtil.EMPTY); if (StringUtil.isEmpty(contentWithoutTagFilter) || ATTRIBUTE.matcher(contentWithoutTagFilter).matches()) { shouldAutoIndent = true; } } if (shouldAutoIndent) { String previousLineIndent = getAutoIndentAfterNewLine(d, c); String restOfLine = d.get(c.offset, curLineRegion.getLength() - (c.offset - curLineRegion.getOffset())); String startIndent = newline + previousLineIndent + getIndentString(); if (indentAndPushTrailingContentAfterNewlineAndCursor(lineContent, restOfLine)) { c.text = startIndent + newline + previousLineIndent; } else { c.text = startIndent; } c.shiftsCaret = false; c.caretOffset = c.offset + startIndent.length(); return true; } } catch (BadLocationException e) { IdeLog.logError(HAMLEditorPlugin.getDefault(), e); } return false; } }