blob: efa7d8bebc49e5496cfd05e2668bea2547ffe07c [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.click.eclipse.ui.editor;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.apache.click.eclipse.ClickPlugin;
import org.eclipse.jface.text.ITypedRegion;
import org.eclipse.swt.custom.StyleRange;
import org.eclipse.swt.graphics.Color;
import org.eclipse.wst.html.ui.internal.style.LineStyleProviderForHTML;
import org.eclipse.wst.sse.core.internal.provisional.text.IStructuredDocument;
import org.eclipse.wst.sse.core.internal.provisional.text.IStructuredDocumentRegion;
import org.eclipse.wst.xml.core.internal.regions.DOMRegionContext;
/**
* The <code>LineStyleProvider</code> implementation for the Velocity template.
* <p>
* TODO multi-line comment (#* ... *#)
*
* @author Naoki Takezoe
*/
public class LineStyleProviderForVelocity extends LineStyleProviderForHTML {
@Override
@SuppressWarnings({"unchecked", "rawtypes"})
public boolean prepareRegions(ITypedRegion currentRegion, int start, int length, Collection styleRanges) {
List<Object> results = new ArrayList<Object>();
boolean result = super.prepareRegions(currentRegion, start, length, results);
// TODO Is it possible to update colors when preferences changed...?
Color colorVariable = ClickPlugin.getDefault().getColorManager().get(ClickPlugin.PREF_COLOR_VAR);
Color colorDirective = ClickPlugin.getDefault().getColorManager().get(ClickPlugin.PREF_COLOR_DIR);
Color colorComment = ClickPlugin.getDefault().getColorManager().get(ClickPlugin.PREF_COLOR_CMT);
IStructuredDocument document = getDocument();
for(Iterator ite = results.iterator(); ite.hasNext();){
StyleRange styleRange = (StyleRange)ite.next();
IStructuredDocumentRegion region = document.getRegionAtCharacterOffset(styleRange.start);
String text = region.getText();
int mStart = styleRange.start - region.getStartOffset();
int mEnd = mStart + styleRange.length;
for(IStructuredDocumentRegion chkRegion = region.getPrevious(); chkRegion != null; chkRegion = chkRegion.getPrevious()){
String type = chkRegion.getType();
if(!type.equals(DOMRegionContext.XML_CONTENT) && !type.equals(DOMRegionContext.UNDEFINED)){
break;
}
text = chkRegion.getText() + text;
mStart += chkRegion.getLength();
mEnd += chkRegion.getLength();
}
for(IStructuredDocumentRegion chkRegion = region.getNext(); chkRegion != null; chkRegion = chkRegion.getNext()){
String type = chkRegion.getType();
if(!type.equals(DOMRegionContext.XML_CONTENT) && !type.equals(DOMRegionContext.UNDEFINED)){
break;
}
text = (new StringBuilder(String.valueOf(text))).append(chkRegion.getText()).toString();
}
Pattern p = Pattern.compile("##.*|#[a-z]+|\\$((\\{.*?\\})|([a-zA-Z0-9\\-_]*))");
Matcher m = p.matcher(text);
int pos = 0;
while(m.find()) {
Color color = m.group().startsWith("##") ? colorComment :
m.group().startsWith("#") ? colorDirective : colorVariable;
if(m.start() < mStart){
if(m.end() < mStart){
continue;
}
StyleRange curr;
if(m.end() < mEnd){
curr = (StyleRange)styleRange.clone();
curr.start = styleRange.start;
curr.length = m.end() - mStart;
curr.foreground = color;
styleRanges.add(curr);
pos = m.end() - mStart;
continue;
}
curr = (StyleRange)styleRange.clone();
curr.foreground = color;
styleRanges.add(curr);
pos = m.end();
break;
}
if(m.start() >= mEnd){
break;
}
if(m.start() > mStart && pos == 0){
StyleRange prev = (StyleRange)styleRange.clone();
prev.start = styleRange.start;
prev.length = m.start() - mStart;
styleRanges.add(prev);
pos = m.end() - mStart;
}
if(m.end() < mEnd){
StyleRange curr = (StyleRange)styleRange.clone();
curr.start = (styleRange.start + m.start()) - mStart;
curr.length = m.end() - m.start();
curr.foreground = color;
styleRanges.add(curr);
pos = m.end() - mStart;
} else {
StyleRange curr = (StyleRange)styleRange.clone();
curr.start = (styleRange.start + m.start()) - mStart;
curr.length = (styleRange.length - m.start()) + mStart;
curr.foreground = color;
styleRanges.add(curr);
pos = m.end() - mStart;
}
}
if(pos < styleRange.length){
StyleRange post = (StyleRange)styleRange.clone();
post.start = styleRange.start + pos;
post.length = styleRange.length - pos;
styleRanges.add(post);
}
//styleRanges.remove(styleRange);
}
return result;
}
}