package org.simantics.scl.ui.editor2; import org.eclipse.core.commands.AbstractHandler; import org.eclipse.core.commands.ExecutionEvent; import org.eclipse.core.commands.ExecutionException; import org.eclipse.swt.custom.StyledText; import org.eclipse.swt.widgets.Control; import org.eclipse.ui.IEditorPart; import org.eclipse.ui.PlatformUI; import org.simantics.scl.compiler.elaboration.modules.SCLValue; import org.simantics.scl.ui.editor.completion.SCLTextEditorEnvironment; public class OpenDeclaration extends AbstractHandler { private static boolean isIdentifierPart(char c) { return Character.isJavaIdentifierPart(c) || c=='.'; } private static String extractIdentifierAt(String text, int caretPos) { int startPos = caretPos; while(startPos > 0 && isIdentifierPart(text.charAt(startPos-1))) --startPos; int endPos = caretPos; while(endPos < text.length() && isIdentifierPart(text.charAt(endPos))) ++endPos; return text.substring(startPos, endPos); } private static final String SYMBOL_CHARS = "!$%&*+/<=>?@\\^|-:~."; private static boolean isSymbolPart(char c) { for(int i=0;i 0 && isSymbolPart(text.charAt(startPos-1))) --startPos; int endPos = caretPos; while(endPos < text.length() && isSymbolPart(text.charAt(endPos))) ++endPos; return text.substring(startPos, endPos); } public static String extractIdentifierOrSymbolAt(String text, int caretPos) { String result = extractIdentifierAt(text, caretPos); if(!result.isEmpty()) return result; return extractSymbolAt(text, caretPos); } private static String extractLineAt(String text, int caretPos) { int startPos = caretPos; while(startPos > 0 && !isNewline(text.charAt(startPos-1))) --startPos; int endPos = caretPos; while(endPos < text.length() && !isNewline(text.charAt(endPos))) ++endPos; return text.substring(startPos, endPos); } private static boolean isNewline(char c) { return c=='\n' || c=='\r'; } @Override public Object execute(ExecutionEvent event) throws ExecutionException { IEditorPart editor = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage().getActiveEditor(); if(!(editor instanceof SCLModuleEditor2)) return null; SCLModuleEditor2 moduleEditor = (SCLModuleEditor2)editor; StyledText styledText = (StyledText)moduleEditor.getAdapter(Control.class); String text = styledText.getText(); int caretOffset = styledText.getCaretOffset(); // Find the line where the caret is String lineAtCaret = extractLineAt(text, caretOffset); if(lineAtCaret.startsWith("import ") || lineAtCaret.startsWith("include ")) { int p1 = lineAtCaret.indexOf('"', 6); int p2 = lineAtCaret.indexOf('"', p1+1); String moduleName = lineAtCaret.substring(p1+1, p2); OpenSCLModule.openModule(moduleName); } else { // Try to find an identifier at caret String identifierAtCaret = extractIdentifierOrSymbolAt(text, caretOffset); if(identifierAtCaret.isEmpty()) return null; SCLTextEditorEnvironment editorEnvironment = moduleEditor.getSCLTextEditorEnvironment(); editorEnvironment.updateEnvironment(moduleEditor.getDocument()); SCLValue value = editorEnvironment.getValue(identifierAtCaret); if(value != null) OpenSCLDefinition.openDefinition(value); } return null; } }