Search in sources :

Example 1 with CtxInsensitiveImportComplProposal

use of org.python.pydev.editor.codecompletion.proposals.CtxInsensitiveImportComplProposal in project Pydev by fabioz.

the class OrganizeImports method beforePerformArrangeImports.

/**
 * That's where everything happens.
 *
 * Important: if the document is in a rewrite session, trying to highlight a given session does not work
 * (so, we cannot be in a rewrite session in this case).
 */
@Override
public boolean beforePerformArrangeImports(final PySelection ps, final PyEdit edit, IFile f) {
    if ((!AnalysisPreferences.doAutoImportOnOrganizeImports(edit)) || edit == null) {
        return true;
    }
    didChange = false;
    ArrayList<MarkerAnnotationAndPosition> undefinedVariablesMarkers = getUndefinedVariableMarkers(edit);
    // sort them
    TreeMap<Integer, MarkerAnnotationAndPosition> map = new TreeMap<Integer, MarkerAnnotationAndPosition>();
    for (MarkerAnnotationAndPosition marker : undefinedVariablesMarkers) {
        if (marker.position == null) {
            continue;
        }
        int start = marker.position.offset;
        map.put(start, marker);
    }
    // create the participant that'll help (will not force a reparse)
    final UndefinedVariableFixParticipant variableFixParticipant = new UndefinedVariableFixParticipant(false);
    // These are the completions to apply. We must apply them all at once after finishing it because we can't do
    // it one by one during the processing because that'd make markers change.
    final List<ICompletionProposalExtension2> completionsToApply = new ArrayList<ICompletionProposalExtension2>();
    // keeps the strings we've already treated.
    final HashSet<String> treatedVars = new HashSet<String>();
    // variable to hold whether we should keep on choosing the imports
    final Boolean[] keepGoing = new Boolean[] { true };
    final IDialogSettings dialogSettings = AnalysisUiPlugin.getDialogSettings();
    // analyse the markers (one by one)
    for (final MarkerAnnotationAndPosition marker : map.values()) {
        if (!keepGoing[0]) {
            break;
        }
        try {
            final int start = marker.position.offset;
            final int end = start + marker.position.length;
            if (start >= 0 && end > start) {
                IDocument doc = ps.getDoc();
                ArrayList<ICompletionProposalHandle> props = new ArrayList<ICompletionProposalHandle>();
                try {
                    String string = doc.get(start, end - start);
                    if (treatedVars.contains(string)) {
                        continue;
                    }
                    variableFixParticipant.addProps(marker, null, null, ps, start, edit.getPythonNature(), edit, props);
                    if (props.size() > 0) {
                        // Sorting proposals on Ctrl+Shift+O.
                        ProposalsComparator proposalsComparator = new ProposalsComparator("", new ProposalsComparator.CompareContext(edit.getPythonNature()));
                        props.sort(proposalsComparator);
                        edit.selectAndReveal(start, end - start);
                        treatedVars.add(string);
                        Shell activeShell = Display.getCurrent().getActiveShell();
                        // Changed from ElementListSelectionDialog so that we can control the sorting.
                        TreeSelectionDialog dialog = new TreeSelectionDialog(activeShell, new LabelProvider() {

                            // get the image and text for each completion
                            @Override
                            public Image getImage(Object element) {
                                CtxInsensitiveImportComplProposal comp = ((CtxInsensitiveImportComplProposal) element);
                                return comp.getImage();
                            }

                            @Override
                            public String getText(Object element) {
                                CtxInsensitiveImportComplProposal comp = ((CtxInsensitiveImportComplProposal) element);
                                return comp.getDisplayString();
                            }
                        }, new ListContentProvider()) {

                            // override things to return the last position of the dialog correctly
                            @Override
                            protected Control createContents(Composite parent) {
                                Control ret = super.createContents(parent);
                                org.python.pydev.plugin.PydevPlugin.setCssId(parent, "py-add-imports-dialog", true);
                                return ret;
                            }

                            @Override
                            public boolean isHelpAvailable() {
                                return false;
                            }

                            @Override
                            protected void updateStatus(IStatus status) {
                                super.updateStatus(status);
                                PydevPlugin.fixSelectionStatusDialogStatusLineColor(this, this.getDialogArea().getBackground());
                            }

                            /**
                             * @see org.eclipse.ui.dialogs.SelectionDialog#getDialogBoundsSettings()
                             */
                            @Override
                            protected IDialogSettings getDialogBoundsSettings() {
                                IDialogSettings section = dialogSettings.getSection(DIALOG_SETTINGS);
                                if (section == null) {
                                    section = dialogSettings.addNewSection(DIALOG_SETTINGS);
                                }
                                return section;
                            }

                            /* (non-Javadoc)
                                 * @see org.eclipse.jface.dialogs.Dialog#getInitialSize()
                                 */
                            @Override
                            protected Point getInitialSize() {
                                IDialogSettings settings = getDialogBoundsSettings();
                                if (settings != null) {
                                    try {
                                        // $NON-NLS-1$
                                        int width = settings.getInt("DIALOG_WIDTH");
                                        // $NON-NLS-1$
                                        int height = settings.getInt("DIALOG_HEIGHT");
                                        if (width > 0 & height > 0) {
                                            return new Point(width, height);
                                        }
                                    } catch (NumberFormatException nfe) {
                                    // make the default return
                                    }
                                }
                                return new Point(300, 300);
                            }
                        };
                        dialog.setTitle("Choose import");
                        dialog.setMessage("Which import should be added?");
                        dialog.setInput(props);
                        dialog.setInitialSelection(props.get(0));
                        int returnCode = dialog.open();
                        if (returnCode == Window.OK) {
                            ICompletionProposalExtension2 firstResult = (ICompletionProposalExtension2) dialog.getFirstResult();
                            completionsToApply.add(firstResult);
                        } else if (returnCode == Window.CANCEL) {
                            keepGoing[0] = false;
                            continue;
                        }
                    }
                } catch (Exception e) {
                    Log.log(e);
                }
            }
        } catch (Exception e) {
            Log.log(e);
        }
    }
    for (ICompletionProposalExtension2 comp : completionsToApply) {
        // the offset is not used in this case, because the actual completion does nothing,
        int offset = 0;
        // we'll only add the import.
        comp.apply(edit.getPySourceViewer(), ' ', 0, offset);
        didChange = true;
    }
    return true;
}
Also used : IStatus(org.eclipse.core.runtime.IStatus) ArrayList(java.util.ArrayList) ICompletionProposalExtension2(org.eclipse.jface.text.contentassist.ICompletionProposalExtension2) Image(org.eclipse.swt.graphics.Image) Shell(org.eclipse.swt.widgets.Shell) ListContentProvider(org.python.pydev.ui.dialogs.ListContentProvider) Control(org.eclipse.swt.widgets.Control) ICompletionProposalHandle(org.python.pydev.shared_core.code_completion.ICompletionProposalHandle) MarkerAnnotationAndPosition(org.python.pydev.editor.codefolding.MarkerAnnotationAndPosition) HashSet(java.util.HashSet) TreeSelectionDialog(org.python.pydev.ui.dialogs.TreeSelectionDialog) CtxInsensitiveImportComplProposal(org.python.pydev.editor.codecompletion.proposals.CtxInsensitiveImportComplProposal) Composite(org.eclipse.swt.widgets.Composite) ProposalsComparator(org.python.pydev.ast.codecompletion.ProposalsComparator) Point(org.eclipse.swt.graphics.Point) TreeMap(java.util.TreeMap) Point(org.eclipse.swt.graphics.Point) UndefinedVariableFixParticipant(com.python.pydev.analysis.ctrl_1.UndefinedVariableFixParticipant) IDialogSettings(org.eclipse.jface.dialogs.IDialogSettings) LabelProvider(org.eclipse.jface.viewers.LabelProvider) IDocument(org.eclipse.jface.text.IDocument)

Example 2 with CtxInsensitiveImportComplProposal

use of org.python.pydev.editor.codecompletion.proposals.CtxInsensitiveImportComplProposal in project Pydev by fabioz.

the class CtxInsensitiveImportComplProposalTest method testApplyLocal18.

public void testApplyLocal18() throws Exception {
    Document doc = new Document("def test(\n" + "    rara\n" + "):\n" + "\n" + "\n" + "    '''testing\n" + "'''\n" + "    import bar\n" + "\n" + "    from x import \\\n" + "    foo\n" + "\n" + "    ");
    CtxInsensitiveImportComplProposal prop = (CtxInsensitiveImportComplProposal) CompletionProposalFactory.get().createCtxInsensitiveImportComplProposal("sys", doc.getLength(), 0, doc.getLength(), IInfo.ATTRIBUTE_WITH_IMPORT_TYPE, "Import sys", null, null, 0, "import sys", null);
    prop.setAddLocalImport(true);
    prop.indentString = "    ";
    prop.apply(doc, '\n', 0, doc.getLength());
    assertEquals("def test(\n" + "    rara\n" + "):\n" + "\n" + "\n" + "    '''testing\n" + "'''\n" + "    import bar\n" + "\n" + "    from x import \\\n" + "    foo\n" + "    import sys\n" + "\n" + "    sys" + "", doc.get().replace("\r\n", "\n").replace('\r', '\n'));
}
Also used : CtxInsensitiveImportComplProposal(org.python.pydev.editor.codecompletion.proposals.CtxInsensitiveImportComplProposal) Document(org.eclipse.jface.text.Document)

Example 3 with CtxInsensitiveImportComplProposal

use of org.python.pydev.editor.codecompletion.proposals.CtxInsensitiveImportComplProposal in project Pydev by fabioz.

the class CtxInsensitiveImportComplProposalTest method testApplyLocal13.

public void testApplyLocal13() throws Exception {
    Document doc = new Document("def test(\n" + "    rara\n" + "):\n" + "    '''testing\n" + "'''\n" + "    " + "");
    CtxInsensitiveImportComplProposal prop = (CtxInsensitiveImportComplProposal) CompletionProposalFactory.get().createCtxInsensitiveImportComplProposal("sys", doc.getLength(), 0, doc.getLength(), IInfo.ATTRIBUTE_WITH_IMPORT_TYPE, "Import sys", null, null, 0, "import sys", null);
    prop.setAddLocalImport(true);
    prop.indentString = "    ";
    prop.apply(doc, '\n', 0, doc.getLength());
    assertEquals("def test(\n" + "    rara\n" + "):\n" + "    '''testing\n" + "'''\n" + "    import sys\n" + "    sys" + "", doc.get().replace("\r\n", "\n").replace('\r', '\n'));
}
Also used : CtxInsensitiveImportComplProposal(org.python.pydev.editor.codecompletion.proposals.CtxInsensitiveImportComplProposal) Document(org.eclipse.jface.text.Document)

Example 4 with CtxInsensitiveImportComplProposal

use of org.python.pydev.editor.codecompletion.proposals.CtxInsensitiveImportComplProposal in project Pydev by fabioz.

the class CtxInsensitiveImportComplProposalTest method testCompletionGroupFromImport4.

public void testCompletionGroupFromImport4() throws Exception {
    // yeap, lot's of spaces there (more than 80 to test it)
    Document doc = new Document("from XXX import YYY,                                                                     ZZZ\n");
    CtxInsensitiveImportComplProposal prop = (CtxInsensitiveImportComplProposal) CompletionProposalFactory.get().createCtxInsensitiveImportComplProposal("BBB", doc.getLength(), 0, doc.getLength(), IInfo.ATTRIBUTE_WITH_IMPORT_TYPE, "Import BBB (from XXX)", null, null, 0, "from XXX import BBB", null);
    prop.indentString = "\t";
    prop.apply(doc, '\n', 0, doc.getLength());
    assertEquals("from XXX import YYY,                                                                     ZZZ,\\\n\tBBB\nBBB", doc.get());
}
Also used : CtxInsensitiveImportComplProposal(org.python.pydev.editor.codecompletion.proposals.CtxInsensitiveImportComplProposal) Document(org.eclipse.jface.text.Document)

Example 5 with CtxInsensitiveImportComplProposal

use of org.python.pydev.editor.codecompletion.proposals.CtxInsensitiveImportComplProposal in project Pydev by fabioz.

the class CompletionParticipantTest method testImportCompletion.

public void testImportCompletion() throws Exception {
    participant = new ImportsCompletionParticipant();
    // check simple
    ICompletionProposalHandle[] proposals = requestCompl("unittest", -1, -1, // the unittest module and testlib.unittest
    new String[] { "unittest", "unittest - testlib" });
    Document document = new Document("unittest");
    ICompletionProposalHandle p0 = null;
    ICompletionProposalHandle p1 = null;
    for (ICompletionProposalHandle p : proposals) {
        String displayString = p.getDisplayString();
        if (displayString.equals("unittest")) {
            p0 = p;
        } else if (displayString.equals("unittest - testlib")) {
            p1 = p;
        }
    }
    if (p0 == null) {
        fail("Could not find unittest import");
    }
    if (p1 == null) {
        fail("Could not find unittest - testlib import");
    }
    ((CtxInsensitiveImportComplProposal) p0).indentString = "    ";
    ((CtxInsensitiveImportComplProposal) p0).apply(document, ' ', 0, 8);
    PySelectionTest.checkStrEquals("import unittest\r\nunittest", document.get());
    document = new Document("unittest");
    ((CtxInsensitiveImportComplProposal) p1).indentString = "    ";
    ((CtxInsensitiveImportComplProposal) p1).apply(document, ' ', 0, 8);
    PySelectionTest.checkStrEquals("from testlib import unittest\r\nunittest", document.get());
    document = new Document("unittest");
    final IEclipsePreferences prefs = new InMemoryEclipsePreferences();
    PyCodeCompletionPreferences.getPreferencesForTests = () -> prefs;
    document = new Document("unittest");
    prefs.putBoolean(PyCodeCompletionPreferences.APPLY_COMPLETION_ON_DOT, false);
    ((CtxInsensitiveImportComplProposal) p1).indentString = "    ";
    ((CtxInsensitiveImportComplProposal) p1).apply(document, '.', 0, 8);
    PySelectionTest.checkStrEquals("unittest.", document.get());
    document = new Document("unittest");
    prefs.putBoolean(PyCodeCompletionPreferences.APPLY_COMPLETION_ON_DOT, true);
    ((CtxInsensitiveImportComplProposal) p1).indentString = "    ";
    ((CtxInsensitiveImportComplProposal) p1).apply(document, '.', 0, 8);
    PySelectionTest.checkStrEquals("from testlib import unittest\r\nunittest.", document.get());
    // for imports, the behavior never changes
    AnalysisPreferences.TESTS_DO_IGNORE_IMPORT_STARTING_WITH_UNDER = true;
    try {
        proposals = requestCompl("_priv3", new String[] { "_priv3 - relative.rel1._priv1._priv2" });
        document = new Document("_priv3");
        ((CtxInsensitiveImportComplProposal) proposals[0]).indentString = "    ";
        ((CtxInsensitiveImportComplProposal) proposals[0]).apply(document, ' ', 0, 6);
        PySelectionTest.checkStrEquals("from relative.rel1._priv1._priv2 import _priv3\r\n_priv3", document.get());
    } finally {
        AnalysisPreferences.TESTS_DO_IGNORE_IMPORT_STARTING_WITH_UNDER = false;
    }
    // check on actual file
    requestCompl(new File(TestDependent.TEST_PYSRC_TESTING_LOC + "/testlib/unittest/guitestcase.py"), "guite", -1, 0, new String[] {});
    Import importTok = new Import(new aliasType[] { new aliasType(new NameTok("unittest", NameTok.ImportModule), null) });
    this.imports = new TokensList(new IToken[] { new SourceToken(importTok, "unittest", "", "", "", null) });
    // none because the import for unittest is already there
    requestCompl("import unittest\nunittest", new String[] {});
    // the local import for unittest (won't actually show anything because we're only exercising the participant test)
    requestCompl("import unittest\nunittes", new String[] {});
    this.imports = null;
}
Also used : CtxInsensitiveImportComplProposal(org.python.pydev.editor.codecompletion.proposals.CtxInsensitiveImportComplProposal) Import(org.python.pydev.parser.jython.ast.Import) IEclipsePreferences(org.eclipse.core.runtime.preferences.IEclipsePreferences) Document(org.eclipse.jface.text.Document) IToken(org.python.pydev.core.IToken) org.python.pydev.parser.jython.ast.aliasType(org.python.pydev.parser.jython.ast.aliasType) ICompletionProposalHandle(org.python.pydev.shared_core.code_completion.ICompletionProposalHandle) File(java.io.File) InMemoryEclipsePreferences(org.python.pydev.shared_core.preferences.InMemoryEclipsePreferences) NameTok(org.python.pydev.parser.jython.ast.NameTok) TokensList(org.python.pydev.core.TokensList) SourceToken(org.python.pydev.ast.codecompletion.revisited.modules.SourceToken)

Aggregations

CtxInsensitiveImportComplProposal (org.python.pydev.editor.codecompletion.proposals.CtxInsensitiveImportComplProposal)32 Document (org.eclipse.jface.text.Document)31 ICompletionProposalHandle (org.python.pydev.shared_core.code_completion.ICompletionProposalHandle)6 PySelection (org.python.pydev.core.docutils.PySelection)3 File (java.io.File)2 IContextInformation (org.eclipse.jface.text.contentassist.IContextInformation)2 UndefinedVariableFixParticipant (com.python.pydev.analysis.ctrl_1.UndefinedVariableFixParticipant)1 CtxParticipant (com.python.pydev.codecompletion.ctxinsensitive.CtxParticipant)1 ArrayList (java.util.ArrayList)1 HashSet (java.util.HashSet)1 TreeMap (java.util.TreeMap)1 IStatus (org.eclipse.core.runtime.IStatus)1 IEclipsePreferences (org.eclipse.core.runtime.preferences.IEclipsePreferences)1 IDialogSettings (org.eclipse.jface.dialogs.IDialogSettings)1 IDocument (org.eclipse.jface.text.IDocument)1 ICompletionProposalExtension2 (org.eclipse.jface.text.contentassist.ICompletionProposalExtension2)1 LabelProvider (org.eclipse.jface.viewers.LabelProvider)1 Image (org.eclipse.swt.graphics.Image)1 Point (org.eclipse.swt.graphics.Point)1 Composite (org.eclipse.swt.widgets.Composite)1