/**
* Copyright (c) 2005-2013 by Appcelerator, Inc. All Rights Reserved.
* Copyright (c) 2013 by Syapse, 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.
*/
/*
* Created on Feb 18, 2005
*
* @author Fabio Zadrozny, Jeremy J. Carroll
*/
package org.python.pydev.editor.actions;
import java.util.List;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.runtime.IAdaptable;
import org.eclipse.jface.action.IAction;
import org.eclipse.jface.text.Document;
import org.eclipse.jface.text.DocumentRewriteSession;
import org.eclipse.jface.text.IDocument;
import org.python.pydev.core.ExtensionHelper;
import org.python.pydev.core.IPyFormatStdProvider;
import org.python.pydev.core.docutils.PySelection;
import org.python.pydev.core.docutils.SyntaxErrorException;
import org.python.pydev.core.log.Log;
import org.python.pydev.editor.PyEdit;
import org.python.pydev.editor.actions.organize_imports.ImportArranger;
import org.python.pydev.editor.actions.organize_imports.Pep8ImportArranger;
import org.python.pydev.editor.autoedit.DefaultIndentPrefs;
import org.python.pydev.parser.prettyprinterv2.IFormatter;
import org.python.pydev.shared_core.string.TextSelectionUtils;
import org.python.pydev.ui.importsconf.ImportsPreferencesPage;
/**
* @author Fabio Zadrozny, Jeremy J. Carroll
*/
public class PyOrganizeImports extends PyAction implements IFormatter {
private final boolean automatic;
public PyOrganizeImports() {
automatic = false;
}
public PyOrganizeImports(boolean automatic) {
this.automatic = automatic;
}
/**
* @see org.eclipse.ui.IActionDelegate#run(org.eclipse.jface.action.IAction)
*/
@Override
public void run(IAction action) {
try {
if (!canModifyEditor()) {
return;
}
PyEdit pyEdit = getPyEdit();
PySelection ps = new PySelection(pyEdit);
final IDocument doc = ps.getDoc();
if (ps.getStartLineIndex() == ps.getEndLineIndex()) {
organizeImports(pyEdit, doc, null, ps);
} else {
DocumentRewriteSession session = TextSelectionUtils.startWrite(doc);
try {
ps.performSimpleSort(doc, ps.getStartLineIndex(), ps.getEndLineIndex());
} finally {
TextSelectionUtils.endWrite(doc, session);
}
}
} catch (Exception e) {
Log.log(e);
beep(e);
}
}
@SuppressWarnings("unchecked")
private void organizeImports(PyEdit edit, final IDocument doc, IFile f, PySelection ps) {
DocumentRewriteSession session = null;
String endLineDelim = ps.getEndLineDelim();
List<IOrganizeImports> participants = null;
if (f == null && !automatic) {
// organizing single file ...
//let's see if someone wants to make a better implementation in another plugin...
participants = ExtensionHelper.getParticipants(ExtensionHelper.PYDEV_ORGANIZE_IMPORTS);
for (IOrganizeImports organizeImports : participants) {
if (!organizeImports.beforePerformArrangeImports(ps, edit, f)) {
return;
}
}
}
IAdaptable projectAdaptable = edit != null ? edit : f;
String indentStr = edit != null ? edit.getIndentPrefs().getIndentationString()
: DefaultIndentPrefs.get(f).getIndentationString();
session = TextSelectionUtils.startWrite(doc);
try {
//Important: the remove and later update have to be done in the same session (since the remove
//will just remove some names and he actual perform will remove the remaining if needed).
//i.e.: from a import b <-- b will be removed by the OrganizeImportsFixesUnused and the
//from a will be removed in the performArrangeImports later on.
boolean removeUnusedImports = false;
if (!automatic) {
//Only go through the removal of unused imports if it's manually activated (not on automatic mode).
removeUnusedImports = ImportsPreferencesPage.getDeleteUnusedImports(projectAdaptable);
if (removeUnusedImports) {
new OrganizeImportsFixesUnused().beforePerformArrangeImports(ps, edit, f);
}
}
boolean pep8 = ImportsPreferencesPage.getPep8Imports(projectAdaptable);
if (pep8) {
if (f == null) {
f = edit.getIFile();
}
IProject p = f != null ? f.getProject() : null;
pep8PerformArrangeImports(doc, removeUnusedImports, endLineDelim, p, indentStr, automatic, edit);
} else {
performArrangeImports(doc, removeUnusedImports, endLineDelim, indentStr, automatic, edit);
}
if (participants != null) {
for (IOrganizeImports organizeImports : participants) {
organizeImports.afterPerformArrangeImports(ps, edit);
}
}
} finally {
TextSelectionUtils.endWrite(doc, session);
}
}
/**
* Actually does the action in the document. Public for testing.
*
* @param doc
* @param removeUnusedImports
* @param endLineDelim
*/
public static void performArrangeImports(IDocument doc, boolean removeUnusedImports, String endLineDelim,
String indentStr, boolean automatic, IPyFormatStdProvider edit) {
new ImportArranger(doc, removeUnusedImports, endLineDelim, indentStr, automatic, edit).perform();
}
/**
* Pep8 compliant version. Actually does the action in the document.
*
* @param doc
* @param removeUnusedImports
* @param endLineDelim
*/
public static void pep8PerformArrangeImports(IDocument doc, boolean removeUnusedImports, String endLineDelim,
IProject prj, String indentStr, boolean automatic, IPyFormatStdProvider edit) {
new Pep8ImportArranger(doc, removeUnusedImports, endLineDelim, prj, indentStr, automatic, edit).perform();
}
/**
* Used by legacy tests.
* @param doc
* @param endLineDelim
* @param indentStr
*/
public static void performArrangeImports(Document doc, String endLineDelim, String indentStr,
IPyFormatStdProvider edit) {
performArrangeImports(doc, false, endLineDelim, indentStr, false, edit);
}
public static void performPep8ArrangeImports(Document doc, String endLineDelim, String indentStr,
boolean automatic, IPyFormatStdProvider edit) {
IProject project = null;
pep8PerformArrangeImports(doc, false, endLineDelim, project, indentStr, automatic, edit);
}
@Override
public void formatAll(IDocument doc, IPyFormatStdProvider edit, IFile f, boolean isOpenedFile,
boolean throwSyntaxError)
throws SyntaxErrorException {
organizeImports((PyEdit) edit, doc, f, new PySelection(doc));
}
@Override
public void formatSelection(IDocument doc, int[] regionsToFormat, IPyFormatStdProvider edit, PySelection ps) {
throw new UnsupportedOperationException();
}
}