~vil/pydev/upstream

« back to all changes in this revision

Viewing changes to org.python.pydev/src/org/python/pydev/editor/actions/PyOrganizeImports.java

  • Committer: Vladimír Lapáček
  • Date: 2006-08-30 18:38:44 UTC
  • Revision ID: vladimir.lapacek@gmail.com-20060830183844-f4d82c1239a7770a
Initial import of upstream

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * Created on Feb 18, 2005
 
3
 *
 
4
 * @author Fabio Zadrozny
 
5
 */
 
6
package org.python.pydev.editor.actions;
 
7
 
 
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;
 
13
 
 
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;
 
26
 
 
27
/**
 
28
 * @author Fabio Zadrozny
 
29
 */
 
30
public class PyOrganizeImports extends PyAction{
 
31
 
 
32
    /**
 
33
     * @see org.eclipse.ui.IActionDelegate#run(org.eclipse.jface.action.IAction)
 
34
     */
 
35
    @SuppressWarnings("unchecked")
 
36
        public void run(IAction action) {
 
37
                try 
 
38
                {
 
39
                        PySelection ps = new PySelection ( getTextEditor ( ));
 
40
                    String endLineDelim = ps.getEndLineDelim();
 
41
                        final IDocument doc = ps.getDoc();
 
42
                        DocumentRewriteSession session = startWrite(doc);
 
43
                        
 
44
                        try {
 
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);
 
51
                                        } else {
 
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.");
 
55
                                                }
 
56
                                                performArrangeImports(doc, endLineDelim);
 
57
                                        }
 
58
                                } else {
 
59
                                        performSimpleSort(doc, endLineDelim, ps.getStartLineIndex(), ps.getEndLineIndex());
 
60
                                }
 
61
                        } finally {
 
62
                                endWrite(doc, session);
 
63
                        }
 
64
                } 
 
65
                catch ( Exception e ) 
 
66
                {
 
67
            PydevPlugin.log(e);
 
68
                        beep ( e );
 
69
                }               
 
70
    }
 
71
 
 
72
        private void endWrite(IDocument doc, DocumentRewriteSession session) {
 
73
                if(doc instanceof IDocumentExtension4){
 
74
                        IDocumentExtension4 d = (IDocumentExtension4) doc;
 
75
                        d.stopRewriteSession(session);
 
76
                }
 
77
        }
 
78
 
 
79
        private DocumentRewriteSession startWrite(IDocument doc) {
 
80
                if(doc instanceof IDocumentExtension4){
 
81
                        IDocumentExtension4 d = (IDocumentExtension4) doc;
 
82
                        return d.startRewriteSession(DocumentRewriteSessionType.UNRESTRICTED);
 
83
                }
 
84
                return null;
 
85
        }
 
86
 
 
87
    /**
 
88
     * Actually does the action in the document.
 
89
     * 
 
90
     * @param doc
 
91
     * @param endLineDelim
 
92
     */
 
93
    @SuppressWarnings("unchecked")
 
94
        public static void performArrangeImports(IDocument doc, String endLineDelim){
 
95
                ArrayList list = new ArrayList();
 
96
                
 
97
                int firstImport = -1;
 
98
                PyDocIterator it = new PyDocIterator(doc, false);
 
99
                while(it.hasNext()){
 
100
                        String str = it.next();
 
101
                    
 
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;
 
108
                    }
 
109
                }
 
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;
 
115
                    }
 
116
                }
 
117
                        list.add( new Object[]{new Integer(iToAdd), str} );
 
118
                        
 
119
                        if(firstImport == -1){
 
120
                            firstImport = iToAdd;
 
121
                        }
 
122
                    }
 
123
        }
 
124
                
 
125
                //check if we had any import
 
126
                if(firstImport == -1){
 
127
                    return;
 
128
                }
 
129
                
 
130
                //sort in inverse order
 
131
                Collections.sort(list, new Comparator(){
 
132
 
 
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);
 
139
            }
 
140
                });
 
141
 
 
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);
 
147
            while(i >= 0){
 
148
                PySelection.deleteLine(doc, ((Integer)element[0]).intValue());
 
149
                i--;
 
150
            }
 
151
        }
 
152
                
 
153
                Collections.sort(list, new Comparator(){
 
154
 
 
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);
 
161
            }
 
162
                });
 
163
                
 
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);
 
170
        }
 
171
            PySelection.addLine(doc, endLineDelim, all.toString(), firstImport);
 
172
    }
 
173
 
 
174
    /**
 
175
     * 
 
176
     * @param doc
 
177
     * @param endLineDelim
 
178
     * @param startLine
 
179
     * @param endLine
 
180
     */
 
181
    @SuppressWarnings("unchecked")
 
182
        public static void performSimpleSort(IDocument doc, String endLineDelim, int startLine, int endLine) {
 
183
        try {
 
184
                ArrayList list = new ArrayList();
 
185
                for (int i = startLine; i <= endLine; i++) {
 
186
                            list.add( PySelection.getLine(doc, i) );
 
187
                }
 
188
                
 
189
                Collections.sort(list);
 
190
                StringBuffer all = new StringBuffer();
 
191
                        for (Iterator iter = list.iterator(); iter.hasNext();) {
 
192
                            String element = (String) iter.next();
 
193
                            all.append(element);
 
194
                            if(iter.hasNext())
 
195
                                all.append(endLineDelim);
 
196
                        }
 
197
                
 
198
            int length = doc.getLineInformation(endLine).getLength();
 
199
            int endOffset = doc.getLineInformation(endLine).getOffset()+length;
 
200
            int startOffset = doc.getLineInformation(startLine).getOffset();
 
201
            
 
202
            doc.replace(startOffset, endOffset-startOffset, all.toString());
 
203
            
 
204
        } catch (BadLocationException e) {
 
205
            PydevPlugin.log(e);
 
206
        }
 
207
 
 
208
    }
 
209
}