mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-07-01 06:05:24 +02:00
Bug 481126 - Add hyperlink support to open decl in QML editor.
Also moved the text package contents to the editor package. Change-Id: I352f8cfa78e937fb4046f86df8c7767df6c5eff2
This commit is contained in:
parent
48f520d54c
commit
6ba6157708
16 changed files with 311 additions and 25 deletions
|
@ -39,7 +39,7 @@ public class CMakeBuilder extends IncrementalProjectBuilder {
|
|||
// TODO assuming cmake is in the path here, probably need a
|
||||
// preference in case it isn't.
|
||||
List<String> command = Arrays.asList("cmake", //$NON-NLS-1$
|
||||
new File(project.getLocationURI()).getAbsolutePath());
|
||||
"-DCMAKE_EXPORT_COMPILE_COMMANDS=ON", new File(project.getLocationURI()).getAbsolutePath());
|
||||
ProcessBuilder processBuilder = new ProcessBuilder(command).directory(buildDir.toFile());
|
||||
cmakeConfig.getToolChain().setEnvironment(processBuilder.environment());
|
||||
Process process = processBuilder.start();
|
||||
|
|
|
@ -26,7 +26,6 @@ import javax.script.ScriptException;
|
|||
|
||||
import org.eclipse.cdt.internal.qt.core.Activator;
|
||||
import org.eclipse.core.resources.IContainer;
|
||||
import org.eclipse.core.resources.IFolder;
|
||||
import org.eclipse.core.resources.IResource;
|
||||
import org.eclipse.core.resources.IWorkspaceRoot;
|
||||
import org.eclipse.core.resources.ResourcesPlugin;
|
||||
|
@ -135,7 +134,7 @@ public class QMLAnalyzer {
|
|||
|
||||
@FunctionalInterface
|
||||
public interface RequestCallback {
|
||||
void callback(Object err, Bindings data);
|
||||
void callback(Object err, Object data);
|
||||
}
|
||||
|
||||
public void addFile(String fileName, String code) throws NoSuchMethodException, ScriptException {
|
||||
|
@ -182,8 +181,9 @@ public class QMLAnalyzer {
|
|||
throw new RuntimeException(err.toString());
|
||||
} else {
|
||||
try {
|
||||
for (Bindings completion : (Bindings[]) invoke.invokeMethod(engine.get("Java"), "to",
|
||||
data.get("completions"), "javax.script.Bindings[]")) {
|
||||
Bindings comps = (Bindings) ((Bindings) data).get("completions");
|
||||
for (Bindings completion : (Bindings[]) invoke.invokeMethod(engine.get("Java"), "to", comps,
|
||||
"javax.script.Bindings[]")) {
|
||||
completions.add(new QMLTernCompletion((String) completion.get("name"),
|
||||
(String) completion.get("type"), (String) completion.get("origin")));
|
||||
}
|
||||
|
@ -198,4 +198,45 @@ public class QMLAnalyzer {
|
|||
return completions;
|
||||
}
|
||||
|
||||
public List<Bindings> getDefinition(String identifier, String fileName, String text, int pos)
|
||||
throws NoSuchMethodException, ScriptException {
|
||||
waitUntilLoaded();
|
||||
Bindings file = engine.createBindings();
|
||||
file.put("type", "full");
|
||||
file.put("name", fileName);
|
||||
file.put("text", text);
|
||||
Bindings files = (Bindings) engine.eval("new Array()");
|
||||
invoke.invokeMethod(files, "push", file);
|
||||
|
||||
Bindings query = engine.createBindings();
|
||||
query.put("type", "definition");
|
||||
query.put("file", fileName);
|
||||
query.put("end", pos);
|
||||
query.put("types", true);
|
||||
query.put("docs", false);
|
||||
query.put("urls", false);
|
||||
query.put("origins", true);
|
||||
query.put("caseInsensitive", true);
|
||||
query.put("lineCharPositions", true);
|
||||
query.put("expandWordForward", false);
|
||||
query.put("includeKeywords", true);
|
||||
query.put("guess", false);
|
||||
Bindings request = engine.createBindings();
|
||||
request.put("files", files);
|
||||
request.put("query", query);
|
||||
|
||||
List<Bindings> definitions = new ArrayList<>();
|
||||
|
||||
RequestCallback callback = (err, data) -> {
|
||||
if (err != null) {
|
||||
throw new RuntimeException(err.toString());
|
||||
} else {
|
||||
definitions.add((Bindings) data);
|
||||
}
|
||||
};
|
||||
|
||||
invoke.invokeMethod(tern, "request", request, invoke.invokeFunction("requestCallback", callback));
|
||||
return definitions;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -140,4 +140,24 @@
|
|||
name="Reload QML Analyzer">
|
||||
</command>
|
||||
</extension>
|
||||
<extension
|
||||
point="org.eclipse.ui.workbench.texteditor.hyperlinkDetectorTargets">
|
||||
<target
|
||||
id="org.eclipse.cdt.qt.ui.qml"
|
||||
name="QML Hyperlink Target">
|
||||
<context
|
||||
type="org.eclipse.cdt.internal.qt.ui.editor.QMLEditor">
|
||||
</context>
|
||||
</target>
|
||||
</extension>
|
||||
<extension
|
||||
point="org.eclipse.ui.workbench.texteditor.hyperlinkDetectors">
|
||||
<hyperlinkDetector
|
||||
activate="true"
|
||||
class="org.eclipse.cdt.internal.qt.ui.editor.QMLHyperlinkDetector"
|
||||
id="org.eclipse.cdt.qt.ui.hyperlinkDetector2"
|
||||
name="QML Hyperlink Detector"
|
||||
targetId="org.eclipse.cdt.qt.ui.qml">
|
||||
</hyperlinkDetector>
|
||||
</extension>
|
||||
</plugin>
|
||||
|
|
|
@ -0,0 +1,22 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2015 QNX Software Systems and others
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*******************************************************************************/
|
||||
package org.eclipse.cdt.internal.qt.ui.actions;
|
||||
|
||||
import org.eclipse.jface.action.Action;
|
||||
|
||||
public class OpenDeclarationsAction extends Action {
|
||||
|
||||
public static final String ID = "OpenDeclarations"; //$NON-NLS-1$
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
// TODO Auto-generated method stub
|
||||
super.run();
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,14 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2015 QNX Software Systems and others.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*******************************************************************************/
|
||||
package org.eclipse.cdt.internal.qt.ui.editor;
|
||||
|
||||
public interface IQMLEditorActionDefinitionIds {
|
||||
|
||||
public static final String OPEN_DECLARATION = "org.eclipse.cdt.qml.edit.opendecl"; //$NON-NLS-1$
|
||||
|
||||
}
|
|
@ -8,9 +8,7 @@
|
|||
* Contributors:
|
||||
* QNX Software Systems - Initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.eclipse.cdt.internal.qt.ui.text;
|
||||
|
||||
import org.eclipse.cdt.internal.qt.ui.editor.QMLPartitionScanner;
|
||||
package org.eclipse.cdt.internal.qt.ui.editor;
|
||||
|
||||
/**
|
||||
* Constants for the various partitions created by {@link QMLPartitionScanner}.
|
|
@ -5,14 +5,14 @@
|
|||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*******************************************************************************/
|
||||
package org.eclipse.cdt.internal.qt.ui.text;
|
||||
package org.eclipse.cdt.internal.qt.ui.editor;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.Collection;
|
||||
|
||||
import javax.script.ScriptException;
|
||||
|
||||
import org.eclipse.cdt.internal.qt.ui.Activator;
|
||||
import org.eclipse.cdt.internal.qt.ui.editor.QMLEditor;
|
||||
import org.eclipse.cdt.qt.core.QMLAnalyzer;
|
||||
import org.eclipse.cdt.qt.core.QMLTernCompletion;
|
||||
import org.eclipse.jface.text.BadLocationException;
|
||||
|
@ -42,7 +42,7 @@ public class QMLContentAssistProcessor implements IContentAssistProcessor {
|
|||
String prefix = lastWord(document, offset);
|
||||
// Save the file
|
||||
IFileEditorInput fileInput = (IFileEditorInput) editor.getEditorInput();
|
||||
String fileName = fileInput.getFile().getFullPath().toString().substring(1);// getLocation().toOSString().substring(1);
|
||||
String fileName = new File(fileInput.getFile().getLocationURI()).getAbsolutePath().substring(1);
|
||||
|
||||
try {
|
||||
String contents = document.get();
|
|
@ -10,7 +10,6 @@
|
|||
*******************************************************************************/
|
||||
package org.eclipse.cdt.internal.qt.ui.editor;
|
||||
|
||||
import org.eclipse.cdt.internal.qt.ui.text.IQMLPartitions;
|
||||
import org.eclipse.core.filebuffers.IDocumentSetupParticipant;
|
||||
import org.eclipse.jface.text.IDocument;
|
||||
import org.eclipse.jface.text.IDocumentExtension3;
|
||||
|
|
|
@ -13,12 +13,16 @@ package org.eclipse.cdt.internal.qt.ui.editor;
|
|||
import javax.script.ScriptException;
|
||||
|
||||
import org.eclipse.cdt.internal.qt.ui.Activator;
|
||||
import org.eclipse.cdt.internal.qt.ui.text.QMLSourceViewerConfiguration;
|
||||
import org.eclipse.cdt.internal.qt.ui.actions.OpenDeclarationsAction;
|
||||
import org.eclipse.cdt.qt.core.QMLAnalyzer;
|
||||
import org.eclipse.core.runtime.IProgressMonitor;
|
||||
import org.eclipse.jface.action.IAction;
|
||||
import org.eclipse.jface.preference.IPreferenceStore;
|
||||
import org.eclipse.jface.text.BadLocationException;
|
||||
import org.eclipse.jface.text.IDocument;
|
||||
import org.eclipse.jface.text.IDocumentExtension3;
|
||||
import org.eclipse.jface.text.IRegion;
|
||||
import org.eclipse.jface.text.Region;
|
||||
import org.eclipse.jface.text.source.DefaultCharacterPairMatcher;
|
||||
import org.eclipse.jface.text.source.ICharacterPairMatcher;
|
||||
import org.eclipse.ui.IFileEditorInput;
|
||||
|
@ -39,8 +43,8 @@ public class QMLEditor extends TextEditor {
|
|||
|
||||
@Override
|
||||
protected void initializeEditor() {
|
||||
setPreferenceStore(Activator.getDefault().getPreferenceStore());
|
||||
setSourceViewerConfiguration(new QMLSourceViewerConfiguration(this));
|
||||
super.initializeEditor();
|
||||
setSourceViewerConfiguration(new QMLSourceViewerConfiguration(this, getPreferenceStore()));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -76,4 +80,56 @@ public class QMLEditor extends TextEditor {
|
|||
store.setDefault(BRACKET_MATCHING_COLOR_PREFERENCE, "155,155,155"); //$NON-NLS-1$
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void createActions() {
|
||||
super.createActions();
|
||||
|
||||
IAction action = new OpenDeclarationsAction();
|
||||
action.setActionDefinitionId(IQMLEditorActionDefinitionIds.OPEN_DECLARATION);
|
||||
setAction(OpenDeclarationsAction.ID, action);
|
||||
}
|
||||
|
||||
public static IRegion findWord(IDocument document, int offset) {
|
||||
int start = -2;
|
||||
int end = -1;
|
||||
|
||||
try {
|
||||
int pos = offset;
|
||||
char c;
|
||||
|
||||
while (--pos >= 0) {
|
||||
c = document.getChar(pos);
|
||||
if (!Character.isJavaIdentifierPart(c)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
start = pos;
|
||||
|
||||
pos = offset;
|
||||
int length = document.getLength();
|
||||
|
||||
while (pos < length) {
|
||||
c = document.getChar(pos);
|
||||
if (!Character.isJavaIdentifierPart(c))
|
||||
break;
|
||||
++pos;
|
||||
}
|
||||
|
||||
end = pos;
|
||||
} catch (BadLocationException x) {
|
||||
}
|
||||
|
||||
if (start >= -1 && end > -1) {
|
||||
if (start == offset && end == offset)
|
||||
return new Region(offset, 0);
|
||||
else if (start == offset)
|
||||
return new Region(start, end - start);
|
||||
else
|
||||
return new Region(start + 1, end - start - 1);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,100 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2015 QNX Software Systems and others.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*******************************************************************************/
|
||||
package org.eclipse.cdt.internal.qt.ui.editor;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.List;
|
||||
|
||||
import javax.script.Bindings;
|
||||
import javax.script.ScriptException;
|
||||
|
||||
import org.eclipse.cdt.internal.qt.core.Activator;
|
||||
import org.eclipse.cdt.qt.core.QMLAnalyzer;
|
||||
import org.eclipse.core.resources.IFile;
|
||||
import org.eclipse.core.resources.ResourcesPlugin;
|
||||
import org.eclipse.jface.text.BadLocationException;
|
||||
import org.eclipse.jface.text.IDocument;
|
||||
import org.eclipse.jface.text.IRegion;
|
||||
import org.eclipse.jface.text.ITextViewer;
|
||||
import org.eclipse.jface.text.hyperlink.IHyperlink;
|
||||
import org.eclipse.ui.IEditorPart;
|
||||
import org.eclipse.ui.IFileEditorInput;
|
||||
import org.eclipse.ui.PartInitException;
|
||||
import org.eclipse.ui.ide.IDE;
|
||||
import org.eclipse.ui.texteditor.ITextEditor;
|
||||
|
||||
public class QMLHyperlink implements IHyperlink {
|
||||
|
||||
private final IRegion region;
|
||||
private final ITextViewer viewer;
|
||||
private final ITextEditor editor;
|
||||
|
||||
public QMLHyperlink(IRegion region, ITextViewer viewer, ITextEditor editor) {
|
||||
this.region = region;
|
||||
this.viewer = viewer;
|
||||
this.editor = editor;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IRegion getHyperlinkRegion() {
|
||||
return region;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getTypeLabel() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getHyperlinkText() {
|
||||
return "Open Declaration";
|
||||
}
|
||||
|
||||
@Override
|
||||
public void open() {
|
||||
QMLAnalyzer analyzer = Activator.getService(QMLAnalyzer.class);
|
||||
try {
|
||||
IDocument document = viewer.getDocument();
|
||||
String selected = document.get(region.getOffset(), region.getLength());
|
||||
IFileEditorInput fileInput = (IFileEditorInput) editor.getEditorInput();
|
||||
String fileName = new File(fileInput.getFile().getLocationURI()).getAbsolutePath().substring(1);
|
||||
List<Bindings> definitions = analyzer.getDefinition(selected, fileName, document.get(),
|
||||
region.getOffset() + region.getLength());
|
||||
if (!definitions.isEmpty()) {
|
||||
Bindings definition = definitions.iterator().next();
|
||||
Bindings start = (Bindings) definition.get("start"); //$NON-NLS-1$
|
||||
if (start == null) {
|
||||
return;
|
||||
}
|
||||
int startLine = (int) (double) start.get("line"); //$NON-NLS-1$
|
||||
int startChar = (int) (double) start.get("ch"); //$NON-NLS-1$
|
||||
int startOffset = document.getLineOffset(startLine) + startChar;
|
||||
Bindings end = (Bindings) definition.get("end"); //$NON-NLS-1$
|
||||
int endLine = (int) (double) end.get("line"); //$NON-NLS-1$
|
||||
int endChar = (int) (double) end.get("ch"); //$NON-NLS-1$
|
||||
int endOffset = document.getLineOffset(endLine) + endChar;
|
||||
String target = (String) definition.get("file"); //$NON-NLS-1$
|
||||
if (fileName.equals(target)) {
|
||||
editor.selectAndReveal(startOffset, endOffset - startOffset);
|
||||
} else {
|
||||
IFile[] targetFiles = ResourcesPlugin.getWorkspace().getRoot()
|
||||
.findFilesForLocationURI(new File("/" + target).toURI()); //$NON-NLS-1$
|
||||
if (targetFiles.length > 0) {
|
||||
IEditorPart part = IDE.openEditor(editor.getEditorSite().getPage(), targetFiles[0]);
|
||||
if (part instanceof ITextEditor) {
|
||||
((ITextEditor) part).selectAndReveal(startOffset, endOffset - startOffset);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (BadLocationException | NoSuchMethodException | ScriptException | PartInitException e) {
|
||||
Activator.log(e);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,29 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2015 QNX Software Systems and others.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*******************************************************************************/
|
||||
package org.eclipse.cdt.internal.qt.ui.editor;
|
||||
|
||||
import org.eclipse.jface.text.IRegion;
|
||||
import org.eclipse.jface.text.ITextViewer;
|
||||
import org.eclipse.jface.text.hyperlink.AbstractHyperlinkDetector;
|
||||
import org.eclipse.jface.text.hyperlink.IHyperlink;
|
||||
import org.eclipse.ui.texteditor.ITextEditor;
|
||||
|
||||
public class QMLHyperlinkDetector extends AbstractHyperlinkDetector {
|
||||
|
||||
@Override
|
||||
public IHyperlink[] detectHyperlinks(ITextViewer textViewer, IRegion region, boolean canShowMultipleHyperlinks) {
|
||||
// TODO is length of region ever > 0?
|
||||
IRegion wordRegion = QMLEditor.findWord(textViewer.getDocument(), region.getOffset());
|
||||
if (wordRegion != null) {
|
||||
ITextEditor editor = (ITextEditor) getAdapter(ITextEditor.class);
|
||||
return new IHyperlink[] { new QMLHyperlink(wordRegion, textViewer, editor) };
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
|
@ -10,7 +10,6 @@
|
|||
*******************************************************************************/
|
||||
package org.eclipse.cdt.internal.qt.ui.editor;
|
||||
|
||||
import org.eclipse.cdt.internal.qt.ui.text.IQMLPartitions;
|
||||
import org.eclipse.jface.text.rules.EndOfLineRule;
|
||||
import org.eclipse.jface.text.rules.IPredicateRule;
|
||||
import org.eclipse.jface.text.rules.IToken;
|
||||
|
|
|
@ -8,10 +8,12 @@
|
|||
* Contributors:
|
||||
* QNX Software Systems - Initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.eclipse.cdt.internal.qt.ui.text;
|
||||
package org.eclipse.cdt.internal.qt.ui.editor;
|
||||
|
||||
import org.eclipse.cdt.internal.qt.ui.editor.QMLEditor;
|
||||
import org.eclipse.cdt.internal.qt.ui.editor.QMLKeywords;
|
||||
import java.util.Map;
|
||||
|
||||
import org.eclipse.core.runtime.IAdaptable;
|
||||
import org.eclipse.jface.preference.IPreferenceStore;
|
||||
import org.eclipse.jface.text.IDocument;
|
||||
import org.eclipse.jface.text.TextAttribute;
|
||||
import org.eclipse.jface.text.contentassist.ContentAssistant;
|
||||
|
@ -56,7 +58,8 @@ public class QMLSourceViewerConfiguration extends TextSourceViewerConfiguration
|
|||
|
||||
private final QMLEditor editor;
|
||||
|
||||
public QMLSourceViewerConfiguration(QMLEditor editor) {
|
||||
public QMLSourceViewerConfiguration(QMLEditor editor, IPreferenceStore prefs) {
|
||||
super(prefs);
|
||||
this.editor = editor;
|
||||
}
|
||||
|
||||
|
@ -160,4 +163,12 @@ public class QMLSourceViewerConfiguration extends TextSourceViewerConfiguration
|
|||
return contentAssistant;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Map<String, IAdaptable> getHyperlinkDetectorTargets(ISourceViewer sourceViewer) {
|
||||
@SuppressWarnings("unchecked")
|
||||
Map<String, IAdaptable> targets = super.getHyperlinkDetectorTargets(sourceViewer);
|
||||
targets.put("org.eclipse.cdt.qt.ui.qml", editor); //$NON-NLS-1$
|
||||
return targets;
|
||||
}
|
||||
|
||||
}
|
|
@ -8,13 +8,12 @@
|
|||
* Contributors:
|
||||
* QNX Software Systems - Initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.eclipse.cdt.internal.qt.ui.text;
|
||||
package org.eclipse.cdt.internal.qt.ui.editor;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Locale;
|
||||
|
||||
import org.eclipse.cdt.internal.qt.ui.Activator;
|
||||
import org.eclipse.cdt.internal.qt.ui.editor.QtProjectFileKeyword;
|
||||
import org.eclipse.jface.text.BadLocationException;
|
||||
import org.eclipse.jface.text.IDocument;
|
||||
import org.eclipse.jface.text.ITextViewer;
|
|
@ -10,7 +10,6 @@
|
|||
*******************************************************************************/
|
||||
package org.eclipse.cdt.internal.qt.ui.editor;
|
||||
|
||||
import org.eclipse.cdt.internal.qt.ui.text.QtProjectFileSourceViewerConfiguration;
|
||||
import org.eclipse.jface.preference.IPreferenceStore;
|
||||
import org.eclipse.jface.text.IDocumentExtension3;
|
||||
import org.eclipse.jface.text.source.DefaultCharacterPairMatcher;
|
||||
|
|
|
@ -8,9 +8,8 @@
|
|||
* Contributors:
|
||||
* QNX Software Systems - Initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.eclipse.cdt.internal.qt.ui.text;
|
||||
package org.eclipse.cdt.internal.qt.ui.editor;
|
||||
|
||||
import org.eclipse.cdt.internal.qt.ui.editor.QtProjectFileKeyword;
|
||||
import org.eclipse.jface.text.IDocument;
|
||||
import org.eclipse.jface.text.IDocumentExtension3;
|
||||
import org.eclipse.jface.text.TextAttribute;
|
Loading…
Add table
Reference in a new issue