All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.fife.ui.rsyntaxtextarea.AbstractJFlexCTokenMaker Maven / Gradle / Ivy

/*
 * 01/25/2009
 *
 * AbstractJFlexCTokenMaker.java - Base class for token makers that use curly
 * braces to denote code blocks, such as C, C++, Java, Perl, etc.
 * 
 * This library is distributed under a modified BSD license.  See the included
 * RSyntaxTextArea.License.txt file for details.
 */
package org.fife.ui.rsyntaxtextarea;

import java.awt.event.ActionEvent;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.swing.Action;
import javax.swing.UIManager;
import javax.swing.text.BadLocationException;
import javax.swing.text.Element;

import org.fife.ui.rtextarea.RTextArea;
import org.fife.ui.rtextarea.RTextAreaEditorKit;



/**
 * Base class for JFlex-based token makers using C-style syntax.  This class
 * knows how to auto-indent after opening braces and parens.
 *
 * @author Robert Futrell
 * @version 1.0
 */
public abstract class AbstractJFlexCTokenMaker extends AbstractJFlexTokenMaker {

	protected static final Action INSERT_BREAK_ACTION = new InsertBreakAction();


	/**
	 * Returns true always as C-style languages use curly braces
	 * to denote code blocks.
	 *
	 * @return true always.
	 */
	public boolean getCurlyBracesDenoteCodeBlocks() {
		return true;
	}


	/**
	 * Returns an action to handle "insert break" key presses (i.e. Enter).
	 * An action is returned that handles newlines differently in multi-line
	 * comments.
	 *
	 * @return The action.
	 */
	public Action getInsertBreakAction() {
		return INSERT_BREAK_ACTION;
	}


	/**
	 * {@inheritDoc}
	 */
	public boolean getMarkOccurrencesOfTokenType(int type) {
		return type==Token.IDENTIFIER || type==Token.FUNCTION;
	}


	/**
	 * {@inheritDoc}
	 */
	public boolean getShouldIndentNextLineAfter(Token t) {
		if (t!=null && t.textCount==1) {
			char ch = t.text[t.textOffset];
			return ch=='{' || ch=='(';
		}
		return false;
	}


	/**
	 * Action that knows how to special-case inserting a newline in a
	 * multi-line comment for languages like C and Java.
	 */
	private static class InsertBreakAction extends RTextAreaEditorKit.InsertBreakAction {

		private static final Pattern p =
							Pattern.compile("([ \\t]*)(/?[\\*]+)([ \\t]*)");

		public void actionPerformedImpl(ActionEvent e, RTextArea textArea) {

			if (!textArea.isEditable() || !textArea.isEnabled()) {
				UIManager.getLookAndFeel().provideErrorFeedback(textArea);
				return;
			}

			RSyntaxTextArea rsta = (RSyntaxTextArea)getTextComponent(e);
			RSyntaxDocument doc = (RSyntaxDocument)rsta.getDocument();

			int line = textArea.getCaretLineNumber();
			int type = doc.getLastTokenTypeOnLine(line);

			// Only in MLC's should we try this
			if (type==Token.COMMENT_DOCUMENTATION ||
					type==Token.COMMENT_MULTILINE) {
				insertBreakInMLC(e, rsta, line);
			}
			else {
				handleInsertBreak(rsta, true);
			}

		}


		/**
		 * Returns whether the MLC token containing offs appears
		 * to have a "nested" comment (i.e., contains "/*"
		 * somewhere inside of it).  This implies that it is likely a "new" MLC
		 * and needs to be closed.  While not foolproof, this is usually good
		 * enough of a sign.
		 *
		 * @param textArea
		 * @param line
		 * @param offs
		 * @return Whether a comment appears to be nested inside this one.
		 */
		private boolean appearsNested(RSyntaxTextArea textArea,
						int line, int offs) {

			final int firstLine = line; // Remember the line we start at.

			while (line=start &&
						dot




© 2015 - 2024 Weber Informatics LLC | Privacy Policy