PageRenderTime 88ms CodeModel.GetById 81ms app.highlight 5ms RepoModel.GetById 1ms app.codeStats 0ms

/jEdit/tags/jedit-4-5-pre1/org/gjt/sp/jedit/indent/RegexpIndentRule.java

#
Java | 162 lines | 103 code | 14 blank | 45 comment | 17 complexity | 0fcb16cd52d95ad2640dc3bfb9c136ac MD5 | raw file
  1/*
  2 * RegexpIndentRule.java
  3 * :tabSize=8:indentSize=8:noTabs=false:
  4 * :folding=explicit:collapseFolds=1:
  5 *
  6 * Copyright (C) 2005 Slava Pestov
  7 *
  8 * This program is free software; you can redistribute it and/or
  9 * modify it under the terms of the GNU General Public License
 10 * as published by the Free Software Foundation; either version 2
 11 * of the License, or any later version.
 12 *
 13 * This program is distributed in the hope that it will be useful,
 14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 16 * GNU General Public License for more details.
 17 *
 18 * You should have received a copy of the GNU General Public License
 19 * along with this program; if not, write to the Free Software
 20 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 21 */
 22
 23package org.gjt.sp.jedit.indent;
 24
 25import java.util.List;
 26import java.util.regex.Matcher;
 27import java.util.regex.Pattern;
 28import java.util.regex.PatternSyntaxException;
 29
 30import javax.swing.text.Segment;
 31
 32import org.gjt.sp.jedit.buffer.JEditBuffer;
 33import org.gjt.sp.jedit.syntax.Token;
 34import org.gjt.sp.jedit.syntax.TokenHandler;
 35import org.gjt.sp.jedit.syntax.TokenMarker;
 36
 37/**
 38 * @author Slava Pestov
 39 * @version $Id: RegexpIndentRule.java 18919 2010-11-04 10:52:55Z kpouer $
 40 */
 41public class RegexpIndentRule implements IndentRule
 42{
 43	//{{{ RegexpIndentRule constructor
 44	/**
 45	 * @param collapse If true, then if the next indent rule is
 46	 * an opening bracket, this rule will not increase indent.
 47	 */
 48	public RegexpIndentRule(String regexp, IndentAction prevPrev,
 49		IndentAction prev, IndentAction thisLine, boolean collapse)
 50	throws PatternSyntaxException
 51	{
 52		prevPrevAction = prevPrev;
 53		prevAction = prev;
 54		thisAction = thisLine;
 55		this.regexp = Pattern.compile(regexp, Pattern.CASE_INSENSITIVE );
 56		this.collapse = collapse;
 57	} //}}}
 58
 59	//{{{ apply() method
 60	public void apply(JEditBuffer buffer, int thisLineIndex,
 61		int prevLineIndex, int prevPrevLineIndex,
 62		List<IndentAction> indentActions)
 63	{
 64		if(thisAction != null
 65			&& lineMatches(buffer, thisLineIndex))
 66		{
 67			indentActions.add(thisAction);
 68		}
 69		if(prevAction != null
 70			&& prevLineIndex != -1
 71			&& lineMatches(buffer, prevLineIndex))
 72		{
 73			indentActions.add(prevAction);
 74			if (collapse)
 75				indentActions.add(IndentAction.PrevCollapse);
 76		}
 77		if(prevPrevAction != null
 78			&& prevPrevLineIndex != -1
 79			&& lineMatches(buffer, prevPrevLineIndex))
 80		{
 81			indentActions.add(prevPrevAction);
 82			if (collapse)
 83				indentActions.add(IndentAction.PrevPrevCollapse);
 84		}
 85	} //}}}
 86
 87	//{{{ toString() method
 88	public String toString()
 89	{
 90		return getClass().getName() + '[' + regexp + ']';
 91	} //}}}
 92
 93	private IndentAction prevPrevAction, prevAction, thisAction;
 94	private Pattern regexp;
 95	private boolean collapse;
 96
 97	//{{{ class TokenFilter
 98	/**
 99	 * A filter which removes non syntactic characters in comments
100	 * or literals which might confuse regexp matchings for indent.
101	 */
102	private static class TokenFilter implements TokenHandler
103	{
104		public StringBuilder result;
105
106		public TokenFilter(int originalLength)
107		{
108			result = new StringBuilder(originalLength);
109		}
110
111		public void handleToken(Segment seg
112			, byte id, int offset, int length
113			, TokenMarker.LineContext context)
114		{
115			// Avoid replacing an empty token into a non empty
116			// string.
117			if (length <= 0)
118			{
119				return;
120			}
121			
122			switch (id)
123			{
124			case Token.COMMENT1:
125			case Token.COMMENT2:
126			case Token.COMMENT3:
127			case Token.COMMENT4:
128				// Replace any comments to a white space
129				// so that they are simply ignored.
130				result.append(' ');
131				break;
132			case Token.LITERAL1:
133			case Token.LITERAL2:
134			case Token.LITERAL3:
135			case Token.LITERAL4:
136				// Replace any literals to a '0' which means
137				// a simple integer literal in most programming
138				// languages.
139				result.append('0');
140				break;
141			default:
142				result.append(seg.array
143					, seg.offset + offset
144					, length);
145				break;
146			}
147		}
148
149		public void setLineContext(TokenMarker.LineContext lineContext)
150		{
151		}
152	} //}}}
153
154	//{{{ lineMatches() method
155	private boolean lineMatches(JEditBuffer buffer, int lineIndex)
156	{
157		TokenFilter filter
158			= new TokenFilter(buffer.getLineLength(lineIndex));
159		buffer.markTokens(lineIndex, filter);
160		return regexp.matcher(filter.result).matches();
161	} //}}}
162}