/**
* Copyright (c) 2005-2013 by Appcelerator, Inc. All Rights Reserved.
* Licensed under the terms of the Eclipse Public License (EPL).
* Please see the license.txt included with this distribution for details.
* Any modifications to this file must keep this entire header intact.
*/
/*
* Author: atotic
* Created: July 10, 2003
*/
package org.python.pydev.editor;
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.ITextHover;
import org.eclipse.jface.text.ITextViewerExtension2;
import org.eclipse.jface.text.contentassist.IContentAssistProcessor;
import org.eclipse.jface.text.contentassist.IContentAssistant;
import org.eclipse.jface.text.quickassist.IQuickAssistAssistant;
import org.eclipse.jface.text.quickassist.IQuickAssistProcessor;
import org.eclipse.jface.text.source.IAnnotationHover;
import org.eclipse.jface.text.source.ISourceViewer;
import org.python.pydev.core.IPythonPartitions;
import org.python.pydev.editor.codecompletion.PyCodeCompletionPreferencesPage;
import org.python.pydev.editor.codecompletion.PythonCompletionProcessor;
import org.python.pydev.editor.codecompletion.PythonStringCompletionProcessor;
import org.python.pydev.editor.correctionassist.PyCorrectionAssistant;
import org.python.pydev.editor.correctionassist.PythonCorrectionProcessor;
import org.python.pydev.editor.hover.PyAnnotationHover;
import org.python.pydev.editor.hover.PyEditorTextHoverDescriptor;
import org.python.pydev.editor.hover.PyEditorTextHoverProxy;
import org.python.pydev.editor.hover.PyHoverPreferencesPage;
import org.python.pydev.editor.simpleassist.SimpleAssistProcessor;
import org.python.pydev.plugin.PydevPlugin;
import org.python.pydev.shared_core.utils.ArrayUtils;
import org.python.pydev.ui.ColorAndStyleCache;
/**
* Adds simple partitioner, and specific behaviors like double-click actions to the TextWidget.
*
* <p>
* Implements a simple partitioner that does syntax highlighting.
*
* Changed to a subclass of TextSourceViewerConfiguration as of pydev 1.3.5
*/
public class PyEditConfiguration extends PyEditConfigurationWithoutEditor {
private IPySyntaxHighlightingAndCodeCompletionEditor edit;
/**
* @param edit The edit to set.
*/
private void setEdit(IPySyntaxHighlightingAndCodeCompletionEditor edit) {
this.edit = edit;
}
/**
* @return Returns the edit.
*/
private IPySyntaxHighlightingAndCodeCompletionEditor getEdit() {
return edit;
}
public PyEditConfiguration(ColorAndStyleCache colorManager, IPySyntaxHighlightingAndCodeCompletionEditor edit,
IPreferenceStore preferenceStore) {
super(colorManager, preferenceStore, edit);
this.setEdit(edit);
}
@Override
public IAnnotationHover getAnnotationHover(ISourceViewer sourceViewer) {
return new PyAnnotationHover(sourceViewer);
}
@Override
public ITextHover getTextHover(ISourceViewer sourceViewer, String contentType, int stateMask) {
/**
* Return the combining hover if the preferences are set accordingly and the state mask matches.
*/
if (PyHoverPreferencesPage.getCombineHoverInfo()) {
PyEditorTextHoverDescriptor combiningHover = PydevPlugin.getCombiningHoverDescriptor();
if (combiningHover.getStateMask() == stateMask) {
return new PyEditorTextHoverProxy(combiningHover, contentType);
}
}
/**
* We return the highest priority registered hover whose state mask matches. If two or more hovers
* have the highest priority, it is indeterminate which will be selected. The proper way to combine
* hover info is to select that option on the PyDev->Editor->Hover preference page. This will cause
* the combining hover to be returned by the code above.
*/
PyEditorTextHoverDescriptor[] hoverDescs = PydevPlugin.getDefault().getPyEditorTextHoverDescriptors();
int i = 0;
while (i < hoverDescs.length) {
if (hoverDescs[i].isEnabled() && hoverDescs[i].getStateMask() == stateMask) {
return new PyEditorTextHoverProxy(hoverDescs[i], contentType);
}
i++;
}
return null;
}
/*
* @see SourceViewerConfiguration#getTextHover(ISourceViewer, String)
*/
@Override
public ITextHover getTextHover(ISourceViewer sourceViewer, String contentType) {
return getTextHover(sourceViewer, contentType, ITextViewerExtension2.DEFAULT_HOVER_STATE_MASK);
}
/*
* @see org.eclipse.jface.text.source.SourceViewerConfiguration#getHyperlinkDetectorTargets(org.eclipse.jface.text.source.ISourceViewer)
* @since 3.3
*/
@Override
protected Map<String, IAdaptable> getHyperlinkDetectorTargets(
ISourceViewer sourceViewer) {
Map<String, IAdaptable> targets = super.getHyperlinkDetectorTargets(
sourceViewer);
targets.put("org.python.pydev.editor.PythonEditor", edit); //$NON-NLS-1$
return targets;
}
/*
* (non-Javadoc)
*
* @see org.eclipse.jface.text.source.SourceViewerConfiguration#getContentAssistant(org.eclipse.jface.text.source.ISourceViewer)
*/
@Override
public IContentAssistant getContentAssistant(ISourceViewer sourceViewer) {
// next create a content assistant processor to populate the completions window
IContentAssistProcessor processor = new SimpleAssistProcessor(edit, new PythonCompletionProcessor(edit,
pyContentAssistant), pyContentAssistant);
PythonStringCompletionProcessor stringProcessor = new PythonStringCompletionProcessor(edit, pyContentAssistant);
pyContentAssistant.setRestoreCompletionProposalSize(getSettings("pydev_completion_proposal_size"));
// No code completion in comments
pyContentAssistant.setContentAssistProcessor(stringProcessor, IPythonPartitions.PY_SINGLELINE_BYTES1);
pyContentAssistant.setContentAssistProcessor(stringProcessor, IPythonPartitions.PY_SINGLELINE_BYTES2);
pyContentAssistant.setContentAssistProcessor(stringProcessor, IPythonPartitions.PY_MULTILINE_BYTES1);
pyContentAssistant.setContentAssistProcessor(stringProcessor, IPythonPartitions.PY_MULTILINE_BYTES2);
pyContentAssistant.setContentAssistProcessor(stringProcessor, IPythonPartitions.PY_SINGLELINE_UNICODE1);
pyContentAssistant.setContentAssistProcessor(stringProcessor, IPythonPartitions.PY_SINGLELINE_UNICODE2);
pyContentAssistant.setContentAssistProcessor(stringProcessor, IPythonPartitions.PY_MULTILINE_UNICODE1);
pyContentAssistant.setContentAssistProcessor(stringProcessor, IPythonPartitions.PY_MULTILINE_UNICODE2);
pyContentAssistant
.setContentAssistProcessor(stringProcessor, IPythonPartitions.PY_SINGLELINE_BYTES_OR_UNICODE1);
pyContentAssistant
.setContentAssistProcessor(stringProcessor, IPythonPartitions.PY_SINGLELINE_BYTES_OR_UNICODE2);
pyContentAssistant.setContentAssistProcessor(stringProcessor, IPythonPartitions.PY_MULTILINE_BYTES_OR_UNICODE1);
pyContentAssistant.setContentAssistProcessor(stringProcessor, IPythonPartitions.PY_MULTILINE_BYTES_OR_UNICODE2);
pyContentAssistant.setContentAssistProcessor(stringProcessor, IPythonPartitions.PY_COMMENT);
pyContentAssistant.setContentAssistProcessor(processor, IDocument.DEFAULT_CONTENT_TYPE);
pyContentAssistant.setInformationControlCreator(getInformationControlCreator(sourceViewer));
pyContentAssistant.enableAutoActivation(true); //always true, but the chars depend on whether it is activated or not in the preferences
//note: delay and auto activate are set on PyContentAssistant constructor.
pyContentAssistant.setDocumentPartitioning(IPythonPartitions.PYTHON_PARTITION_TYPE);
pyContentAssistant.setAutoActivationDelay(PyCodeCompletionPreferencesPage.getAutocompleteDelay());
return pyContentAssistant;
}
/*
* (non-Javadoc)
*
* @see org.eclipse.jface.text.source.SourceViewerConfiguration#getQuickAssistAssistant(org.eclipse.jface.text.source.ISourceViewer)
*/
@Override
public IQuickAssistAssistant getQuickAssistAssistant(ISourceViewer sourceViewer) {
// create a content assistant:
PyCorrectionAssistant assistant = new PyCorrectionAssistant();
// next create a content assistant processor to populate the completions window
IQuickAssistProcessor processor = new PythonCorrectionProcessor(this.getEdit());
// Correction assist works on all
assistant.setQuickAssistProcessor(processor);
assistant.setInformationControlCreator(getInformationControlCreator(sourceViewer));
//delay and auto activate set on PyContentAssistant constructor.
return assistant;
}
/*
* @see SourceViewerConfiguration#getConfiguredTextHoverStateMasks(ISourceViewer, String)
* Implementation copied from org.eclipse.jdt.ui.text.JavaSourceViewerConfiguration and adapted
* for PyDev.
*/
@Override
public int[] getConfiguredTextHoverStateMasks(ISourceViewer sourceViewer, String contentType) {
PyEditorTextHoverDescriptor[] hoverDescs = PydevPlugin.getDefault().getPyEditorTextHoverDescriptors();
hoverDescs = ArrayUtils.concatArrays(hoverDescs,
new PyEditorTextHoverDescriptor[] { PydevPlugin.getCombiningHoverDescriptor() });
int stateMasks[] = new int[hoverDescs.length];
int stateMasksLength = 0;
for (int i = 0; i < hoverDescs.length; i++) {
if (hoverDescs[i].isEnabled()) {
int j = 0;
int stateMask = hoverDescs[i].getStateMask();
while (j < stateMasksLength) {
if (stateMasks[j] == stateMask) {
break;
}
j++;
}
if (j == stateMasksLength) {
stateMasks[stateMasksLength++] = stateMask;
}
}
}
if (stateMasksLength == hoverDescs.length) {
return stateMasks;
}
int[] shortenedStateMasks = new int[stateMasksLength];
System.arraycopy(stateMasks, 0, shortenedStateMasks, 0, stateMasksLength);
return shortenedStateMasks;
}
}