/** * On-save operations : * * <p>* Un-wrapping if needed * * <p>* Auto section markers normalization * * <p>* Auto formating when the editor saves the file * * @param aSourceViewer The editor source viewer */ public void onEditorPerformSave(final ISourceViewer aSourceViewer) { final IDocument document = aSourceViewer.getDocument(); if (pPreferenceStore.getBoolean(IEditorPreferenceConstants.EDITOR_SAVE_RESET_MARKERS)) { // Auto section blocks normalization RestContentOutlinePage outlinePage = null; if (pEditor != null) { outlinePage = pEditor.getOutlinePage(); } if (outlinePage != null) { // Don't forget to refresh the tree ! outlinePage.update(); OutlineUtil.normalizeSectionsMarker( pEditor.getOutlinePage().getContentProvider().getRoot()); } } // Formatting text _must_ be the last thing to do : it modifies the // document content, therefore it may induce unpredictable behavior for // next document readers if (pPreferenceStore.getBoolean(IEditorPreferenceConstants.EDITOR_SAVE_FORMAT)) { // Text format on save // Doc informations IRegion docRegion = new Region(0, document.getLength()); // Store current pointer location Point currentLocation = aSourceViewer.getSelectedRange(); // Format the document pDocFormatter.format(document, docRegion); // Reset point location aSourceViewer.setSelectedRange(currentLocation.x, currentLocation.y); } if (LineWrapUtil.get().isActiveMode(LineWrapMode.SOFT)) { // Soft wrap mode : remove all added end-of-line pAutoEditLineWrap.unregisterListener(); pAutoEditLineWrap.removeWrapping(); } }
/* * @see IContentAssistProcessor#computeCompletionProposals(ITextViewer, int) */ @Override public ICompletionProposal[] computeQuickAssistProposals( IQuickAssistInvocationContext quickAssistContext) { ISourceViewer viewer = quickAssistContext.getSourceViewer(); int documentOffset = quickAssistContext.getOffset(); int length = viewer != null ? viewer.getSelectedRange().y : -1; TextInvocationContext context = new TextInvocationContext(viewer, documentOffset, length); IAnnotationModel model = viewer.getAnnotationModel(); if (model == null) return fgNoSuggestionsProposal; List<ICompletionProposal> proposals = computeProposals(context, model); if (proposals.isEmpty()) return fgNoSuggestionsProposal; return proposals.toArray(new ICompletionProposal[proposals.size()]); }
@Override public ICompletionProposal[] computeQuickAssistProposals( IQuickAssistInvocationContext quickAssistContext) { ISourceViewer viewer = quickAssistContext.getSourceViewer(); int documentOffset = quickAssistContext.getOffset(); IEditorPart part = fAssistant.getEditor(); CompilationUnit cu = DartUI.getWorkingCopyManager().getWorkingCopy(part.getEditorInput()); IAnnotationModel model = DartUI.getDocumentProvider().getAnnotationModel(part.getEditorInput()); AssistContext context = null; if (cu != null) { int length = viewer != null ? viewer.getSelectedRange().y : 0; context = new AssistContext(cu, viewer, part, documentOffset, length); } Annotation[] annotations = fAssistant.getAnnotationsAtOffset(); fErrorMessage = null; ICompletionProposal[] res = null; if (model != null && context != null && annotations != null) { List<IDartCompletionProposal> proposals = Lists.newArrayList(); IStatus status = collectProposals( context, model, annotations, true, !fAssistant.isUpdatedOffset(), proposals); res = proposals.toArray(new ICompletionProposal[proposals.size()]); if (!status.isOK()) { fErrorMessage = status.getMessage(); DartToolsPlugin.log(status); } } if (res == null || res.length == 0) { return new ICompletionProposal[] { new ChangeCorrectionProposal( CorrectionMessages.NoCorrectionProposal_description, new NullChange(""), 0, null) }; //$NON-NLS-1$ } if (res.length > 1) { Arrays.sort(res, new CompletionProposalComparator()); } return res; }
public void start() { if (getActiveLinkedMode() != null) { // for safety; should already be handled in RenameDartElementAction fgActiveLinkedMode.startFullDialog(); return; } ISourceViewer viewer = fEditor.getViewer(); IDocument document = viewer.getDocument(); fOriginalSelection = viewer.getSelectedRange(); int offset = fOriginalSelection.x; try { fLinkedPositionGroup = new LinkedPositionGroup(); prepareElement(); if (fDartElement == null) { return; } if (viewer instanceof ITextViewerExtension6) { IUndoManager undoManager = ((ITextViewerExtension6) viewer).getUndoManager(); if (undoManager instanceof IUndoManagerExtension) { IUndoManagerExtension undoManagerExtension = (IUndoManagerExtension) undoManager; IUndoContext undoContext = undoManagerExtension.getUndoContext(); IOperationHistory operationHistory = OperationHistoryFactory.getOperationHistory(); fStartingUndoOperation = operationHistory.getUndoOperation(undoContext); } } fOriginalName = nameNode.getName(); final int pos = nameNode.getOffset(); final List<ASTNode> sameNodes = Lists.newArrayList(); nameNode .getRoot() .accept( new RecursiveASTVisitor<Void>() { @Override public Void visitSimpleIdentifier(SimpleIdentifier node) { Element element = node.getElement(); element = getCanonicalElement(element); if (Objects.equal(element, fDartElement)) { sameNodes.add(node); } return super.visitSimpleIdentifier(node); } }); // TODO: copied from LinkedNamesAssistProposal#apply(..): // sort for iteration order, starting with the node @ offset Collections.sort( sameNodes, new Comparator<ASTNode>() { @Override public int compare(ASTNode o1, ASTNode o2) { return rank(o1) - rank(o2); } /** * Returns the absolute rank of an <code>ASTNode</code>. Nodes preceding <code>pos * </code> are ranked last. * * @param node the node to compute the rank for * @return the rank of the node with respect to the invocation offset */ private int rank(ASTNode node) { int relativeRank = node.getOffset() + node.getLength() - pos; if (relativeRank < 0) { return Integer.MAX_VALUE + relativeRank; } else { return relativeRank; } } }); for (int i = 0; i < sameNodes.size(); i++) { ASTNode elem = sameNodes.get(i); LinkedPosition linkedPosition = new LinkedPosition(document, elem.getOffset(), elem.getLength(), i); if (i == 0) { fNamePosition = linkedPosition; } fLinkedPositionGroup.addPosition(linkedPosition); } fLinkedModeModel = new LinkedModeModel(); fLinkedModeModel.addGroup(fLinkedPositionGroup); fLinkedModeModel.forceInstall(); fLinkedModeModel.addLinkingListener(new EditorHighlightingSynchronizer(fEditor)); fLinkedModeModel.addLinkingListener(new EditorSynchronizer()); LinkedModeUI ui = new EditorLinkedModeUI(fLinkedModeModel, viewer); ui.setExitPosition(viewer, offset, 0, Integer.MAX_VALUE); ui.setExitPolicy(new ExitPolicy(document)); ui.enter(); viewer.setSelectedRange( fOriginalSelection.x, fOriginalSelection.y); // by default, full word is selected; restore original selection if (viewer instanceof IEditingSupportRegistry) { IEditingSupportRegistry registry = (IEditingSupportRegistry) viewer; registry.register(fFocusEditingSupport); } openSecondaryPopup(); // startAnimation(); fgActiveLinkedMode = this; } catch (BadLocationException e) { DartToolsPlugin.log(e); } }
/** * (non-Javadoc) * * @see org.eclipse.swt.custom.VerifyKeyListener#verifyKey(org.eclipse.swt.events.VerifyEvent) */ @SuppressWarnings("fallthrough") public void verifyKey(VerifyEvent event) { if (!event.doit || getInsertMode() != SMART_INSERT) { return; } ISourceViewer sourceViewer = getSourceViewer(); IDocument document = sourceViewer.getDocument(); final Point selection = sourceViewer.getSelectedRange(); final int offset = selection.x; final int length = selection.y; switch (event.character) { case ']': if (!this.fCloseBrackets) { return; } // Fall through case ')': if (hasCharacterAtOffset(document, offset + length, event.character)) { sourceViewer.setSelectedRange(offset + length + 1, 0); event.doit = false; return; } break; case '(': if (hasCharacterToTheRight(document, offset + length, '(')) return; // fall through case '[': if (!this.fCloseBrackets) return; if (hasIdentifierToTheRight(document, offset + length)) return; // fall through case '\'': if (event.character == '\'') { if (!this.fCloseStrings) return; if (hasCharacterAtOffset(document, offset - 1, '\\')) { return; } if (hasCharacterAtOffset(document, offset + length, '\'')) { sourceViewer.setSelectedRange(offset + length + 1, 0); event.doit = false; return; } if (hasIdentifierToTheLeft(document, offset) || hasIdentifierToTheRight(document, offset + length)) { return; } } // fall through case '"': if (event.character == '"') { if (!this.fCloseStrings) return; if (hasCharacterAtOffset(document, offset - 1, '\\')) { return; } if (hasCharacterAtOffset(document, offset + length, '"')) { sourceViewer.setSelectedRange(offset + length + 1, 0); event.doit = false; return; } if (hasIdentifierToTheLeft(document, offset) || hasIdentifierToTheRight(document, offset + length)) return; } try { // ITypedRegion partition= TextUtilities.getPartition(document, // IJavaPartitions.JAVA_PARTITIONING, offset, true); //// if (! IDocument.DEFAULT_CONTENT_TYPE.equals(partition.getType()) && // partition.getOffset() != offset) // if (! IDocument.DEFAULT_CONTENT_TYPE.equals(partition.getType())) // return; // if (!validateEditorInputState()) { return; } final StringBuffer buffer = new StringBuffer(); buffer.append(event.character); buffer.append(getPeerCharacter(event.character)); document.replace(offset, length, buffer.toString()); // move to the right of the inserted element sourceViewer.setSelectedRange(offset + 1, 0); // // BracketLevel level= new BracketLevel(); // fBracketLevelStack.push(level); // // LinkedPositionGroup group= new LinkedPositionGroup(); // group.addPosition(new LinkedPosition(document, offset + 1, 0, // LinkedPositionGroup.NO_STOP)); // // LinkedModeModel model= new LinkedModeModel(); // model.addLinkingListener(this); // model.addGroup(group); // model.forceInstall(); // // level.fOffset= offset; // level.fLength= 2; // // // set up position tracking for our magic peers // if (fBracketLevelStack.size() == 1) { // document.addPositionCategory(CATEGORY); // document.addPositionUpdater(fUpdater); // } // level.fFirstPosition= new Position(offset, 1); // level.fSecondPosition= new Position(offset + 1, 1); // document.addPosition(CATEGORY, level.fFirstPosition); // document.addPosition(CATEGORY, level.fSecondPosition); // // level.fUI= new EditorLinkedModeUI(model, sourceViewer); // level.fUI.setSimpleMode(true); // level.fUI.setExitPolicy(new ExitPolicy(closingCharacter, // getEscapeCharacter(closingCharacter), fBracketLevelStack)); // level.fUI.setExitPosition(sourceViewer, offset + 2, 0, Integer.MAX_VALUE); // level.fUI.setCyclingMode(LinkedModeUI.CYCLE_NEVER); // level.fUI.enter(); // // // IRegion newSelection= level.fUI.getSelectedRegion(); // sourceViewer.setSelectedRange(newSelection.getOffset(), newSelection.getLength()); event.doit = false; } catch (BadLocationException e) { BPELUIPlugin.log(e); } // catch (BadPositionCategoryException e) { // BPELUIPlugin.log(e); // } break; } }
public void start() { if (getActiveLinkedMode() != null) { // for safety; should already be handled in RenameDartElementAction fgActiveLinkedMode.startFullDialog(); return; } ISourceViewer viewer = fEditor.getViewer(); IDocument document = viewer.getDocument(); fOriginalSelection = viewer.getSelectedRange(); int offset = fOriginalSelection.x; try { DartUnit root = ASTProvider.getASTProvider().getAST(getCompilationUnit(), ASTProvider.WAIT_YES, null); fLinkedPositionGroup = new LinkedPositionGroup(); DartNode selectedNode = NodeFinder.perform(root, fOriginalSelection.x, fOriginalSelection.y); if (!(selectedNode instanceof DartIdentifier)) { return; // TODO: show dialog } DartIdentifier nameNode = (DartIdentifier) selectedNode; if (viewer instanceof ITextViewerExtension6) { IUndoManager undoManager = ((ITextViewerExtension6) viewer).getUndoManager(); if (undoManager instanceof IUndoManagerExtension) { IUndoManagerExtension undoManagerExtension = (IUndoManagerExtension) undoManager; IUndoContext undoContext = undoManagerExtension.getUndoContext(); IOperationHistory operationHistory = OperationHistoryFactory.getOperationHistory(); fStartingUndoOperation = operationHistory.getUndoOperation(undoContext); } } fOriginalName = nameNode.getName(); final int pos = nameNode.getSourceInfo().getOffset(); DartNode[] sameNodes = LinkedNodeFinder.findByNode(root, nameNode); // TODO: copied from LinkedNamesAssistProposal#apply(..): // sort for iteration order, starting with the node @ offset Arrays.sort( sameNodes, new Comparator<DartNode>() { @Override public int compare(DartNode o1, DartNode o2) { return rank(o1) - rank(o2); } /** * Returns the absolute rank of an <code>DartNode</code>. Nodes preceding <code>pos * </code> are ranked last. * * @param node the node to compute the rank for * @return the rank of the node with respect to the invocation offset */ private int rank(DartNode node) { int relativeRank = node.getSourceInfo().getOffset() + node.getSourceInfo().getLength() - pos; if (relativeRank < 0) { return Integer.MAX_VALUE + relativeRank; } else { return relativeRank; } } }); for (int i = 0; i < sameNodes.length; i++) { DartNode elem = sameNodes[i]; LinkedPosition linkedPosition = new LinkedPosition( document, elem.getSourceInfo().getOffset(), elem.getSourceInfo().getLength(), i); if (i == 0) { fNamePosition = linkedPosition; } fLinkedPositionGroup.addPosition(linkedPosition); } fLinkedModeModel = new LinkedModeModel(); fLinkedModeModel.addGroup(fLinkedPositionGroup); fLinkedModeModel.forceInstall(); fLinkedModeModel.addLinkingListener(new EditorHighlightingSynchronizer(fEditor)); fLinkedModeModel.addLinkingListener(new EditorSynchronizer()); LinkedModeUI ui = new EditorLinkedModeUI(fLinkedModeModel, viewer); ui.setExitPosition(viewer, offset, 0, Integer.MAX_VALUE); ui.setExitPolicy(new ExitPolicy(document)); ui.enter(); viewer.setSelectedRange( fOriginalSelection.x, fOriginalSelection.y); // by default, full word is selected; restore original selection if (viewer instanceof IEditingSupportRegistry) { IEditingSupportRegistry registry = (IEditingSupportRegistry) viewer; registry.register(fFocusEditingSupport); } openSecondaryPopup(); // startAnimation(); fgActiveLinkedMode = this; } catch (BadLocationException e) { DartToolsPlugin.log(e); } }
private void checkResourceFix(String name, String caretLocation, String expectedNewPath) throws Exception { IProject project = getProject(); IFile file = getTestDataFile(project, name, FD_RES + "/" + FD_RES_LAYOUT + "/" + name); // Determine the offset final int offset = getCaretOffset(file, caretLocation); String osRoot = project.getLocation().toOSString(); List<String> errors = new ArrayList<String>(); String fileRelativePath = file.getProjectRelativePath().toPortableString(); String filePath = osRoot + File.separator + fileRelativePath; // Run AaptParser such that markers are added... // When debugging these tests, the project gets a chance to build itself // so // the real aapt errors are there. But when the test is run directly, // aapt has // not yet run. I tried waiting for the build (using the code in // SampleProjectTest) // but this had various adverse effects (exception popups from the // Eclipse debugger // etc) so instead this test just hardcodes the aapt errors that should // be // observed on quickfix1.xml. assertEquals("Unit test is hardcoded to errors for quickfix1.xml", "quickfix1.xml", name); errors.add( filePath + ":7: error: Error: No resource found that matches the given name" + " (at 'text' with value '@string/firststring')."); errors.add( filePath + ":7: error: Error: No resource found that matches the given name" + " (at 'layout_width' with value '@dimen/testdimen')."); errors.add( filePath + ":13: error: Error: No resource found that matches the given name" + " (at 'layout' with value '@layout/testlayout')."); AaptParser.parseOutput(errors, project); AaptQuickFix aaptQuickFix = new AaptQuickFix(); // Open file IWorkbenchPage page = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage(); assertNotNull(page); IEditorPart editor = IDE.openEditor(page, file); assertTrue(editor instanceof AndroidXmlEditor); AndroidXmlEditor layoutEditor = (AndroidXmlEditor) editor; final ISourceViewer viewer = layoutEditor.getStructuredSourceViewer(); // Test marker resolution. IMarker[] markers = file.findMarkers(AndmoreAndroidConstants.MARKER_AAPT_COMPILE, true, IResource.DEPTH_ZERO); for (IMarker marker : markers) { int start = marker.getAttribute(IMarker.CHAR_START, 0); int end = marker.getAttribute(IMarker.CHAR_END, 0); if (offset >= start && offset <= end) { // Found the target marker. Now check the marker resolution of // it. assertTrue(aaptQuickFix.hasResolutions(marker)); IMarkerResolution[] resolutions = aaptQuickFix.getResolutions(marker); assertNotNull(resolutions); assertEquals(1, resolutions.length); IMarkerResolution resolution = resolutions[0]; assertNotNull(resolution); assertTrue(resolution.getLabel().contains("Create resource")); // Not running marker yet -- if we create the files here they // already // exist when the quick assist code runs. (The quick fix and the // quick assist // mostly share code for the implementation anyway.) // resolution.run(marker); break; } } // Next test quick assist. IQuickAssistInvocationContext invocationContext = new IQuickAssistInvocationContext() { @Override public int getLength() { return 0; } @Override public int getOffset() { return offset; } @Override public ISourceViewer getSourceViewer() { return viewer; } }; ICompletionProposal[] proposals = aaptQuickFix.computeQuickAssistProposals(invocationContext); assertNotNull(proposals); assertTrue(proposals.length == 1); ICompletionProposal proposal = proposals[0]; assertNotNull(proposal.getAdditionalProposalInfo()); assertNotNull(proposal.getImage()); assertTrue(proposal.getDisplayString().contains("Create resource")); IDocument document = new Document(); String fileContent = AndmoreAndroidPlugin.readFile(file); document.set(fileContent); // Apply quick fix proposal.apply(document); IPath path = new Path(expectedNewPath); IFile newFile = project.getFile(path); assertNotNull(path.toPortableString(), newFile); // Ensure that the newly created file was opened IEditorPart currentFile = AdtUtils.getActiveEditor(); assertEquals( newFile.getProjectRelativePath(), ((FileEditorInput) currentFile.getEditorInput()).getFile().getProjectRelativePath()); // Look up caret offset assertTrue( currentFile != null ? currentFile.getClass().getName() : "null", currentFile instanceof AndroidXmlEditor); AndroidXmlEditor newEditor = (AndroidXmlEditor) currentFile; ISourceViewer newViewer = newEditor.getStructuredSourceViewer(); Point selectedRange = newViewer.getSelectedRange(); String newFileContents = AndmoreAndroidPlugin.readFile(newFile); // Insert selection markers -- [ ] for the selection range, ^ for the // caret String newFileWithCaret = addSelection(newFileContents, selectedRange); newFileWithCaret = removeSessionData(newFileWithCaret); assertEqualsGolden(name, newFileWithCaret); }
/** @see IPainter#paint(int) */ public final void paint(final int reason) { Point selection = mSourceViewer.getSelectedRange(); if (selection.y > 0) { deactivate(true); return; } SexpNavigator explorer = mEditor.getExplorer(); boolean backward = true; boolean closeToParen = false; int offset = selection.x; IDocument document = mEditor.getDocument(); try { char previousChar = '\0'; char nextChar = '\0'; if (selection.x > 0) previousChar = document.getChar(selection.x - 1); if (selection.x > 0 && SchemeScannerUtilities.isClosingParenthesis(previousChar) && SchemeTextUtilities.getPartition(document, selection.x - 1).getType() == IDocument.DEFAULT_CONTENT_TYPE) { closeToParen = true; } else { nextChar = document.getChar(selection.x); if (selection.x < document.getLength() - 1 && SchemeScannerUtilities.isOpeningParenthesis(nextChar) && SchemeTextUtilities.getPartition(document, selection.x).getType() == IDocument.DEFAULT_CONTENT_TYPE) { closeToParen = true; backward = false; } } if (closeToParen && backward && explorer.backwardSexpression(selection.x)) { offset = explorer.getListStart(); char matchingChar = document.getChar(offset); mMismatch = SchemeScannerUtilities.getParenthesisType(previousChar) != SchemeScannerUtilities.getParenthesisType(matchingChar); } else { if (closeToParen && !backward && explorer.forwardSexpression(selection.x)) { offset = explorer.getSexpEnd() - 1; char matchingChar = document.getChar(offset); mMismatch = SchemeScannerUtilities.getParenthesisType(nextChar) != SchemeScannerUtilities.getParenthesisType(matchingChar); } else { deactivate(true); return; } } } catch (BadLocationException exception) { deactivate(true); return; } if (mIsActive) { // only if different if (offset != mBracketPosition.getOffset()) { // remove old highlighting handleDrawRequest(null); // update position mBracketPosition.isDeleted = false; mBracketPosition.offset = offset; mBracketPosition.length = 1; // apply new highlighting handleDrawRequest(null); } } else { mIsActive = true; mBracketPosition.isDeleted = false; mBracketPosition.offset = offset; mBracketPosition.length = 1; mTextWidget.addPaintListener(this); mPositionManager.managePosition(mBracketPosition); handleDrawRequest(null); } }