package org.rascalmpl.eclipse.repl;
import java.io.IOException;
import java.io.StringReader;
import org.eclipse.tm.internal.terminal.control.ITerminalMouseListener;
import org.eclipse.tm.terminal.model.ITerminalTextDataReadOnly;
import org.rascalmpl.eclipse.editor.EditorUtil;
import org.rascalmpl.uri.LinkDetector;
import org.rascalmpl.uri.URIUtil;
import org.rascalmpl.uri.LinkDetector.Type;
import io.usethesource.vallang.ISourceLocation;
import io.usethesource.vallang.IValue;
import io.usethesource.vallang.exceptions.FactParseError;
import io.usethesource.vallang.exceptions.FactTypeUseException;
import io.usethesource.vallang.io.StandardTextReader;
import org.rascalmpl.values.ValueFactoryFactory;
final class RascalLinkMouseListener implements ITerminalMouseListener {
private int currentLine = -1;
private int currentColumn = -1;
private String safeToString(char[] ch) {
if (ch == null) {
return "";
}
return new String(ch);
}
@Override
public void mouseUp(ITerminalTextDataReadOnly model, int line, int column, int button) {
if (line == currentLine && column == currentColumn) {
// concat the line before and after to make sure we can get wrapped lines
String lineBefore = line > 0 && model.isWrappedLine(line - 1) ? safeToString(model.getChars(line - 1)) : "";
String lineAfter = model.isWrappedLine(line) ? safeToString(model.getChars(line + 1)) : "";
String fullLine = lineBefore + safeToString(model.getChars(line)) + lineAfter;
String link = LinkDetector.findAt(fullLine, lineBefore.length() + column);
if (link != null && LinkDetector.typeOf(link) == Type.SOURCE_LOCATION) {
try {
IValue loc = new StandardTextReader().read(ValueFactoryFactory.getValueFactory(), new StringReader(link));
if (loc instanceof ISourceLocation) {
EditorUtil.openAndSelectURI((ISourceLocation)loc);
}
}
catch (FactTypeUseException | FactParseError | IOException e) {
}
}
else if (link != null && LinkDetector.typeOf(link) == Type.HYPERLINK) {
EditorUtil.openWebURI(ValueFactoryFactory.getValueFactory().sourceLocation(URIUtil.assumeCorrect(link)));
}
}
currentColumn = -1;
currentLine = -1;
}
@Override
public void mouseDown(ITerminalTextDataReadOnly model, int line, int column, int button) {
currentLine = line;
currentColumn = column;
}
@Override
public void mouseDoubleClick(ITerminalTextDataReadOnly model, int line, int column, int button) {
// TODO: copy source loc to clipboard
}
}