2
* Created on Feb 18, 2005
4
* @author Fabio Zadrozny
6
package org.python.pydev.editor.actions;
8
import java.util.ArrayList;
9
import java.util.Collections;
10
import java.util.Comparator;
11
import java.util.Iterator;
12
import java.util.List;
14
import org.eclipse.jface.action.IAction;
15
import org.eclipse.jface.text.BadLocationException;
16
import org.eclipse.jface.text.DocumentRewriteSession;
17
import org.eclipse.jface.text.DocumentRewriteSessionType;
18
import org.eclipse.jface.text.IDocument;
19
import org.eclipse.jface.text.IDocumentExtension4;
20
import org.python.pydev.core.ExtensionHelper;
21
import org.python.pydev.core.docutils.PyDocIterator;
22
import org.python.pydev.core.docutils.PySelection;
23
import org.python.pydev.core.docutils.WordUtils;
24
import org.python.pydev.editor.PyEdit;
25
import org.python.pydev.plugin.PydevPlugin;
28
* @author Fabio Zadrozny
30
public class PyOrganizeImports extends PyAction{
33
* @see org.eclipse.ui.IActionDelegate#run(org.eclipse.jface.action.IAction)
35
@SuppressWarnings("unchecked")
36
public void run(IAction action) {
39
PySelection ps = new PySelection ( getTextEditor ( ));
40
String endLineDelim = ps.getEndLineDelim();
41
final IDocument doc = ps.getDoc();
42
DocumentRewriteSession session = startWrite(doc);
45
if (ps.getStartLineIndex() == ps.getEndLineIndex()) {
46
//let's see if someone wants to make a better implementation in another plugin...
47
List<IOrganizeImports> participants = ExtensionHelper.getParticipants(ExtensionHelper.PYDEV_ORGANIZE_IMPORTS);
48
if (participants.size() == 1) {
49
PyEdit pyEdit = getPyEdit();
50
participants.get(0).performArrangeImports(ps, pyEdit);
52
if (participants.size() > 1) {
53
//let's issue a warning... this extension can only have 1 plugin implementing it
54
PydevPlugin.log("The organize imports has more than one plugin with this extension point, therefore, the default is being used.");
56
performArrangeImports(doc, endLineDelim);
59
performSimpleSort(doc, endLineDelim, ps.getStartLineIndex(), ps.getEndLineIndex());
62
endWrite(doc, session);
72
private void endWrite(IDocument doc, DocumentRewriteSession session) {
73
if(doc instanceof IDocumentExtension4){
74
IDocumentExtension4 d = (IDocumentExtension4) doc;
75
d.stopRewriteSession(session);
79
private DocumentRewriteSession startWrite(IDocument doc) {
80
if(doc instanceof IDocumentExtension4){
81
IDocumentExtension4 d = (IDocumentExtension4) doc;
82
return d.startRewriteSession(DocumentRewriteSessionType.UNRESTRICTED);
88
* Actually does the action in the document.
93
@SuppressWarnings("unchecked")
94
public static void performArrangeImports(IDocument doc, String endLineDelim){
95
ArrayList list = new ArrayList();
98
PyDocIterator it = new PyDocIterator(doc, false);
100
String str = it.next();
102
if((str.startsWith("import ") || str.startsWith("from "))){
103
int iToAdd = it.getLastReturnedLine();
104
if(str.indexOf('(') != -1){ //we have something like from os import (pipe,\nfoo)
105
while(it.hasNext() && str.indexOf(')') == -1){
106
String str1 = it.next();
107
str += endLineDelim+str1;
110
if(WordUtils.endsWith(str, '\\')){
111
while(it.hasNext() && WordUtils.endsWith(str, '\\')){
112
//we have to get all until there are no more back-slashes
113
String str1 = it.next();
114
str += endLineDelim+str1;
117
list.add( new Object[]{new Integer(iToAdd), str} );
119
if(firstImport == -1){
120
firstImport = iToAdd;
125
//check if we had any import
126
if(firstImport == -1){
130
//sort in inverse order
131
Collections.sort(list, new Comparator(){
133
public int compare(Object o1, Object o2) {
134
Object[] c1 = (Object[])o1;
135
Object[] c2 = (Object[])o2;
136
Integer i1 = (Integer) c1[0];
137
Integer i2 = (Integer) c2[0];
138
return i2.compareTo(i1);
142
//ok, now we have to delete all lines with imports.
143
for (Iterator iter = list.iterator(); iter.hasNext();) {
144
Object[] element = (Object[]) iter.next();
145
String s = (String) element[1];
146
int i = PySelection.countLineBreaks(s);
148
PySelection.deleteLine(doc, ((Integer)element[0]).intValue());
153
Collections.sort(list, new Comparator(){
155
public int compare(Object o1, Object o2) {
156
Object[] c1 = (Object[])o1;
157
Object[] c2 = (Object[])o2;
158
String s1 = (String) c1[1];
159
String s2 = (String) c2[1];
160
return s1.compareTo(s2);
164
firstImport--; //add line after the the specified
165
StringBuffer all = new StringBuffer();
166
for (Iterator iter = list.iterator(); iter.hasNext();) {
167
Object[] element = (Object[]) iter.next();
168
all.append((String) element[1]);
169
all.append(endLineDelim);
171
PySelection.addLine(doc, endLineDelim, all.toString(), firstImport);
177
* @param endLineDelim
181
@SuppressWarnings("unchecked")
182
public static void performSimpleSort(IDocument doc, String endLineDelim, int startLine, int endLine) {
184
ArrayList list = new ArrayList();
185
for (int i = startLine; i <= endLine; i++) {
186
list.add( PySelection.getLine(doc, i) );
189
Collections.sort(list);
190
StringBuffer all = new StringBuffer();
191
for (Iterator iter = list.iterator(); iter.hasNext();) {
192
String element = (String) iter.next();
195
all.append(endLineDelim);
198
int length = doc.getLineInformation(endLine).getLength();
199
int endOffset = doc.getLineInformation(endLine).getOffset()+length;
200
int startOffset = doc.getLineInformation(startLine).getOffset();
202
doc.replace(startOffset, endOffset-startOffset, all.toString());
204
} catch (BadLocationException e) {