/** * Compute completion proposals. * * @param viewer the viewer * @param documentOffset the document offset * @return the i completion proposal[] */ @Override public ICompletionProposal[] computeCompletionProposals(ITextViewer viewer, int documentOffset) { String text; String prefix = ""; PropertyLabelLexer lexer = null; PropertyLabelParser parser = null; Collection<ICompletionProposal> result = null; int selectionRange = 0; try { text = viewer.getDocument().get(0, documentOffset); lexer = new PropertyLabelLexer(new ANTLRStringStream(text)); CommonTokenStream tokens = new CommonTokenStream(lexer); parser = new PropertyLabelParser(tokens, property, new SimpleStringErrorReporter()); parser.setValidation(true); selectionRange = viewer.getSelectedRange().y; parser.label(); modifiersUsed = parser.getModifiersUsed(); result = computeCompletions(viewer, parser.getContext(), documentOffset, selectionRange); } catch (BadLocationException e) { e.printStackTrace(); } catch (RuntimeException e) { modifiersUsed = parser.getModifiersUsed(); prefix = getPrefix(viewer, documentOffset); result = computeCompletions(viewer, parser.getContext(), documentOffset, selectionRange); } catch (RecognitionException e) { modifiersUsed = parser.getModifiersUsed(); prefix = getPrefix(viewer, documentOffset); result = computeCompletions(viewer, parser.getContext(), documentOffset, selectionRange); } return result.toArray(new ICompletionProposal[] {}); }
/** * Show completions at caret position. If current position does not contain quick fixes look for * next quick fix on same line by moving from left to right and restarting at end of line if the * beginning of the line is reached. * * @see org.eclipse.jface.text.quickassist.IQuickAssistAssistant#showPossibleQuickAssists() */ public String showPossibleQuickAssists() { fPosition = null; fCurrentAnnotations = null; if (fViewer == null || fViewer.getDocument() == null) // Let superclass deal with this return super.showPossibleQuickAssists(); ArrayList resultingAnnotations = new ArrayList(20); try { Point selectedRange = fViewer.getSelectedRange(); int currOffset = selectedRange.x; int currLength = selectedRange.y; boolean goToClosest = (currLength == 0); int newOffset = collectQuickFixableAnnotations(fEditor, currOffset, goToClosest, resultingAnnotations); if (newOffset != currOffset) { storePosition(currOffset, currLength); fViewer.setSelectedRange(newOffset, 0); fViewer.revealRange(newOffset, 0); } } catch (BadLocationException e) { JavaScriptPlugin.log(e); } fCurrentAnnotations = (Annotation[]) resultingAnnotations.toArray(new Annotation[resultingAnnotations.size()]); return super.showPossibleQuickAssists(); }
/** * Inspects the context of the compilation unit around <code>completionPosition</code> and feeds * the collector with proposals. * * @param viewer the text viewer * @param completionPosition the context position in the document of the text viewer * @param compilationUnit the compilation unit (may be <code>null</code>) */ public void complete(ITextViewer viewer, int completionPosition, IRubyScript compilationUnit) { IDocument document = viewer.getDocument(); if (!(fContextType instanceof RubyScriptContextType)) return; Point selection = viewer.getSelectedRange(); // remember selected text String selectedText = null; if (selection.y != 0) { try { selectedText = document.get(selection.x, selection.y); } catch (BadLocationException e) { } } RubyScriptContext context = ((RubyScriptContextType) fContextType) .createContext(document, completionPosition, selection.y, compilationUnit); context.setVariable("selection", selectedText); // $NON-NLS-1$ int start = context.getStart(); int end = context.getEnd(); IRegion region = new Region(start, end - start); Template[] templates = RubyPlugin.getDefault().getTemplateStore().getTemplates(); if (selection.y == 0) { for (int i = 0; i != templates.length; i++) if (context.canEvaluate(templates[i])) fProposals.add( new TemplateProposal( templates[i], context, region, RubyPluginImages.get(RubyPluginImages.IMG_OBJS_TEMPLATE))); } else { if (context.getKey().length() == 0) context.setForceEvaluation(true); boolean multipleLinesSelected = areMultipleLinesSelected(viewer); for (int i = 0; i != templates.length; i++) { Template template = templates[i]; if (context.canEvaluate(template) && template.getContextTypeId().equals(context.getContextType().getId()) && (!multipleLinesSelected && template.getPattern().indexOf($_WORD_SELECTION) != -1 || (multipleLinesSelected && template.getPattern().indexOf($_LINE_SELECTION) != -1))) { fProposals.add( new TemplateProposal( templates[i], context, region, RubyPluginImages.get(RubyPluginImages.IMG_OBJS_TEMPLATE))); } } } }
@Override public void doubleClicked(ITextViewer part) { int pos = part.getSelectedRange().x; if (pos < 0) return; fText = part; selectWord(pos); }
/** Method declared on ITextDoubleClickStrategy */ public void doubleClicked(ITextViewer text) { fPos = text.getSelectedRange().x; if (fPos < 0) return; fText = text; if (!selectBracketBlock()) selectWord(); }
public void doubleClicked(ITextViewer part) { int pos = part.getSelectedRange().x; if (pos < 0) return; fText = part; if (!selectComment(pos)) { selectWord(pos); } }
/** * Returns <code>true</code> if one line is completely selected or if multiple lines are selected. * Being completely selected means that all characters except the new line characters are * selected. * * @return <code>true</code> if one or multiple lines are selected * @since 2.1 */ private boolean areMultipleLinesSelected(ITextViewer viewer) { if (viewer == null) return false; Point s = viewer.getSelectedRange(); if (s.y == 0) return false; try { IDocument document = viewer.getDocument(); int startLine = document.getLineOfOffset(s.x); int endLine = document.getLineOfOffset(s.x + s.y); IRegion line = document.getLineInformation(startLine); return startLine != endLine || (s.x == line.getOffset() && s.y == line.getLength()); } catch (BadLocationException x) { return false; } }
/* * @see org.eclipse.swt.dnd.DragSourceListener#dragStart(org.eclipse.swt.dnd.DragSourceEvent) */ @Override public void dragStart(DragSourceEvent event) { if (!fIsEnabled) { event.doit = false; return; } // convert screen coordinates to widget offest int offset = getOffsetAtLocation(event.x, event.y, false); // convert further to a document offset offset = getDocumentOffset(offset); Point selection = fViewer.getSelectedRange(); if (selection != null && offset >= selection.x && offset < selection.x + selection.y) { fSelectionPosition = new Position(selection.x, selection.y); if (fViewer instanceof ITextViewerExtension) { ((ITextViewerExtension) fViewer).getRewriteTarget().beginCompoundChange(); } IDocument doc = fViewer.getDocument(); try { // add the drag selection position // the position is used to delete the selection on a DROP_MOVE // and it can be used by the drop target to determine if it should // allow the drop (e.g. if drop location overlaps selection) doc.addPositionCategory(DRAG_SELECTION_CATEGORY); fPositionUpdater = new DefaultPositionUpdater(DRAG_SELECTION_CATEGORY); doc.addPositionUpdater(fPositionUpdater); doc.addPosition(DRAG_SELECTION_CATEGORY, fSelectionPosition); } catch (BadLocationException e) { // should not happen } catch (BadPositionCategoryException e) { // cannot happen } event.doit = true; // this has no effect? event.detail = DND.DROP_COPY; if (isDocumentEditable()) { event.detail |= DND.DROP_MOVE; } } else { event.doit = false; event.detail = DND.DROP_NONE; } }
@Override public IRegion getHoverRegion(ITextViewer textViewer, int offset) { if (textViewer != null) { /* * If the hover offset falls within the selection range return the * region for the whole selection. */ Point selectedRange = textViewer.getSelectedRange(); if (selectedRange.x >= 0 && selectedRange.y > 0 && offset >= selectedRange.x && offset <= selectedRange.x + selectedRange.y) return new Region(selectedRange.x, selectedRange.y); else { return findWord(textViewer.getDocument(), offset); } } return null; }
/** * Returns <code>true</code> if there's only one word on the line * * @return <code>true</code> if only one word is on the line */ private boolean isOnlyWordOnLine(ITextViewer viewer) { if (viewer == null) return false; Point s = viewer.getSelectedRange(); if (s.y == 0) return false; try { IDocument document = viewer.getDocument(); int startLine = document.getLineOfOffset(s.x); IRegion line = document.getLineInformation(startLine); String lineContent = document.get(line.getOffset(), line.getLength()); return lineContent.trim().lastIndexOf(' ', s.x) == -1; } catch (BadLocationException x) { return false; } }
@Override public void apply(ITextViewer viewer, char trigger, int stateMask, int offset) { IDocument document = viewer.getDocument(); if (fTextViewer == null) { fTextViewer = viewer; } // don't apply the proposal if for some reason we're not valid any longer if (!isInDartDoc() && !validate(document, offset, null)) { setCursorPosition(offset); if (trigger != '\0') { try { document.replace(offset, 0, String.valueOf(trigger)); setCursorPosition(getCursorPosition() + 1); if (trigger == '(' && autocloseBrackets()) { document.replace(getReplacementOffset() + getCursorPosition(), 0, ")"); // $NON-NLS-1$ setUpLinkedMode(document, ')'); } } catch (BadLocationException x) { // ignore } } return; } // don't eat if not in preferences, XOR with Ctrl // but: if there is a selection, replace it! Point selection = viewer.getSelectedRange(); fToggleEating = (stateMask & SWT.CTRL) != 0; int newLength = selection.x + selection.y - getReplacementOffset(); if ((insertCompletion() ^ fToggleEating) && newLength >= 0) { setReplacementLength(newLength); } apply(document, trigger, offset); fToggleEating = false; }
/** * Returns <code>true</code> if one line is completely selected or if multiple lines are selected. * Being completely selected means that all characters are selected except the new line characters * and leading/trailing spaces. * * @return <code>true</code> if one or multiple lines are selected */ private boolean areLinesSelected(ITextViewer viewer) { if (viewer == null) return false; Point s = viewer.getSelectedRange(); if (s.y == 0) return false; try { IDocument document = viewer.getDocument(); int startLine = document.getLineOfOffset(s.x); IRegion line = document.getLineInformation(startLine); String lineContent = document.get(line.getOffset(), line.getLength()); Matcher m = fStartOfLineContentPattern.matcher(lineContent); int lineContentStart = 0; if (m.find()) lineContentStart = m.start() + line.getOffset(); int lineContentLength = lineContent.trim().length(); return s.x <= lineContentStart && s.x + s.y >= lineContentStart + lineContentLength; } catch (BadLocationException x) { return false; } }
@Override public void apply(final ITextViewer viewer, char trigger, int stateMask, final int offset) { try { fLocations = null; Point selection = viewer.getSelectedRange(); final int secectionOffset = selection.x; final int selectionLength = selection.y; ASTProvider.getASTProvider() .runOnAST( fTranslationUnit, ASTProvider.WAIT_ACTIVE_ONLY, new NullProgressMonitor(), new ASTRunnable() { @Override public IStatus runOnAST(ILanguage lang, IASTTranslationUnit astRoot) throws CoreException { if (astRoot == null) return Status.CANCEL_STATUS; IASTNodeSelector selector = astRoot.getNodeSelector(null); IASTName name = selector.findEnclosingName(secectionOffset, selectionLength); if (name != null) { fLocations = LinkedNamesFinder.findByName(astRoot, name); } return Status.OK_STATUS; } }); if (fLocations == null || fLocations.length == 0) { return; } // Sort the locations starting with the one @ offset. Arrays.sort( fLocations, new Comparator<IRegion>() { @Override public int compare(IRegion n1, IRegion n2) { return rank(n1) - rank(n2); } /** * Returns the absolute rank of a location. Location preceding {@code offset} are ranked * last. * * @param location the location to compute the rank for * @return the rank of the location with respect to the invocation offset */ private int rank(IRegion location) { int relativeRank = location.getOffset() + location.getLength() - offset; if (relativeRank < 0) { return Integer.MAX_VALUE + relativeRank; } else { return relativeRank; } } }); IDocument document = viewer.getDocument(); LinkedPositionGroup group = new LinkedPositionGroup(); for (int i = 0; i < fLocations.length; i++) { IRegion item = fLocations[i]; group.addPosition(new LinkedPosition(document, item.getOffset(), item.getLength(), i)); } LinkedModeModel model = new LinkedModeModel(); model.addGroup(group); model.forceInstall(); CEditor editor = getCEditor(); if (editor != null) { model.addLinkingListener(new EditorHighlightingSynchronizer(editor)); } LinkedModeUI ui = new EditorLinkedModeUI(model, viewer); ui.setExitPolicy(new DeleteBlockingExitPolicy(document)); ui.setExitPosition(viewer, offset, 0, LinkedPositionGroup.NO_STOP); ui.enter(); if (fValueSuggestion != null) { document.replace(fLocations[0].getOffset(), fLocations[0].getLength(), fValueSuggestion); IRegion selectedRegion = ui.getSelectedRegion(); selection = new Point(selectedRegion.getOffset(), fValueSuggestion.length()); } viewer.setSelectedRange( selection.x, selection.y); // By default full word is selected, restore original selection } catch (BadLocationException e) { CUIPlugin.log(e); } }
/** @see org.eclipse.swt.custom.VerifyKeyListener#verifyKey(org.eclipse.swt.events.VerifyEvent) */ public void verifyKey(VerifyEvent event) { // early pruning to slow down normal typing as little as possible if (!event.doit || !isAutoInsertEnabled() || !isAutoInsertCharacter(event.character)) { return; } IDocument document = textViewer.getDocument(); final Point selection = textViewer.getSelectedRange(); final int offset = selection.x; final int length = selection.y; try { String scope = getScopeAtOffset(document, offset); if (fgCommentSelector.matches(scope)) { return; } if (length > 0) { wrapSelection(event, document, offset, length); return; } // Don't auto-close if next char is a letter or digit if (document.getLength() > offset) { char nextChar = document.getChar(offset); if (Character.isJavaIdentifierPart(nextChar)) { return; } } // Don't auto-close if we have an open pair! if (isUnclosedPair( event, document, offset)) // We have an open string or pair, just insert the single // character, don't do anything special { return; } final char closingCharacter = getPeerCharacter(event.character); // If this is the start char and there's no unmatched close char, insert the close char if (unpairedClose(event.character, closingCharacter, document, offset)) { return; } final StringBuffer buffer = new StringBuffer(); buffer.append(event.character); buffer.append(closingCharacter); if (offset == document.getLength()) { String delim = null; if (document instanceof IDocumentExtension4) { delim = ((IDocumentExtension4) document).getDefaultLineDelimiter(); } if (delim == null) { delim = System.getProperty("line.separator", "\r\n"); // $NON-NLS-1$ //$NON-NLS-2$ } buffer.append(delim); } document.replace(offset, length, buffer.toString()); 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(); // 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, textViewer); level.fUI.setSimpleMode(true); level.fUI.setExitPolicy( new ExitPolicy( textViewer, closingCharacter, getEscapeCharacter(closingCharacter), fBracketLevelStack)); level.fUI.setExitPosition(textViewer, offset + 2, 0, Integer.MAX_VALUE); level.fUI.setCyclingMode(LinkedModeUI.CYCLE_NEVER); level.fUI.enter(); IRegion newSelection = level.fUI.getSelectedRegion(); textViewer.setSelectedRange(newSelection.getOffset(), newSelection.getLength()); event.doit = false; } catch (BadLocationException e) { CommonEditorPlugin.logError(e); } catch (BadPositionCategoryException e) { CommonEditorPlugin.logError(e); } }
/** * Inspects the context of the compilation unit around <code>completionPosition</code> and feeds * the collector with proposals. * * @param viewer the text viewer * @param completionPosition the context position in the document of the text viewer * @param translationUnit the translation unit (may be <code>null</code>) */ public void complete( ITextViewer viewer, int completionPosition, ITranslationUnit translationUnit) { if (!(fContextType instanceof TranslationUnitContextType)) return; IDocument document = viewer.getDocument(); Point selection = viewer.getSelectedRange(); boolean linesSelected = areLinesSelected(viewer); boolean showLineSelectionTemplates = linesSelected; boolean showWordSelectionTemplates = !linesSelected || isOnlyWordOnLine(viewer); if (linesSelected) { // adjust line selection to start at column 1 and end at line delimiter try { IRegion startLine = document.getLineInformationOfOffset(selection.x); IRegion endLine = document.getLineInformationOfOffset(selection.x + selection.y - 1); completionPosition = selection.x = startLine.getOffset(); selection.y = endLine.getOffset() + endLine.getLength() - startLine.getOffset(); } catch (BadLocationException exc) { } } Position position = new Position(completionPosition, selection.y); // remember selected text String selectedText = null; if (selection.y != 0) { try { selectedText = document.get(selection.x, selection.y); document.addPosition(position); fPositions.put(document, position); } catch (BadLocationException e) { } } TranslationUnitContext context = ((TranslationUnitContextType) fContextType) .createContext(document, position, translationUnit); context.setVariable("selection", selectedText); // $NON-NLS-1$ int start = context.getStart(); int end = context.getEnd(); IRegion region = new Region(start, end - start); Template[] templates = CUIPlugin.getDefault().getTemplateStore().getTemplates(); Image image = CDTSharedImages.getImage(CDTSharedImages.IMG_OBJS_TEMPLATE); if (selection.y == 0) { for (int i = 0; i != templates.length; i++) if (context.canEvaluate(templates[i])) fProposals.add(new CTemplateProposal(templates[i], context, region, image)); } else { if (linesSelected || context.getKey().length() == 0) context.setForceEvaluation(true); for (int i = 0; i != templates.length; i++) { Template template = templates[i]; if (context.canEvaluate(template) && template.getContextTypeId().equals(context.getContextType().getId()) && ((showWordSelectionTemplates && template.getPattern().indexOf($_WORD_SELECTION) != -1 || (showLineSelectionTemplates && template.getPattern().indexOf($_LINE_SELECTION) != -1)))) { fProposals.add(new CTemplateProposal(templates[i], context, region, image)); } } } }