private boolean controlUndoBehavior(int offset, int length) { LinkedPosition position = fModel.findPosition(new LinkedPosition(fCurrentTarget.getViewer().getDocument(), offset, length, LinkedPositionGroup.NO_STOP)); if (position != null) { // if the last position is not the same and there is an open // change: close it. if (!position.equals(fPreviousPosition)) endCompoundChangeIfNeeded(); beginCompoundChangeIfNeeded(); } fPreviousPosition = position; return fPreviousPosition != null; }
public void selectionChanged(SelectionChangedEvent event) { ISelection selection = event.getSelection(); if (selection instanceof ITextSelection) { ITextSelection textsel = (ITextSelection) selection; if (event.getSelectionProvider() instanceof ITextViewer) { IDocument doc = ((ITextViewer) event.getSelectionProvider()).getDocument(); if (doc != null) { int offset = textsel.getOffset(); int length = textsel.getLength(); if (offset >= 0 && length >= 0) { LinkedPosition find = new LinkedPosition(doc, offset, length, LinkedPositionGroup.NO_STOP); LinkedPosition pos = fModel.findPosition(find); if (pos == null && fExitPosition != null && fExitPosition.includes(find)) pos = fExitPosition; if (pos != null) switchPosition(pos, false, false); } } } } }
@Override public ExitFlags doExit(LinkedModeModel model, VerifyEvent event, int offset, int length) { if (length == 0 && (event.character == SWT.BS || event.character == SWT.DEL)) { LinkedPosition position= model.findPosition(new LinkedPosition(fDocument, offset, 0, LinkedPositionGroup.NO_STOP)); if (position != null) { if (event.character == SWT.BS) { if (offset - 1 < position.getOffset()) { //skip backspace at beginning of linked position event.doit= false; } } else /* event.character == SWT.DEL */ { if (offset + 1 > position.getOffset() + position.getLength()) { //skip delete at end of linked position event.doit= false; } } } } return null; // don't change behavior }
/** * Sets up a simple linked mode at {@link #getCursorPosition()} and an exit policy that will * exit the mode when <code>closingCharacter</code> is typed and an exit position at * <code>getCursorPosition() + 1</code>. * * @param document the document */ protected void setUpLinkedMode(IDocument document) { try { LinkedPositionGroup group= new LinkedPositionGroup(); group.addPosition(new LinkedPosition(document, getSelectionStart(), getSelectionLength(), LinkedPositionGroup.NO_STOP)); LinkedModeModel model= new LinkedModeModel(); model.addGroup(group); model.forceInstall(); LinkedModeUI ui= new LinkedModeUI(model, viewer); // ui.setSimpleMode(true); ui.setExitPolicy(new ExitPolicy(exitChars)); ui.setExitPosition(viewer, getCursorPosition() + getReplacementOffset(), 0, Integer.MAX_VALUE); ui.setCyclingMode(LinkedModeUI.CYCLE_NEVER); ui.enter(); } catch (BadLocationException e) { log.info(e.getMessage(), e); } }
public ExitFlags doExit(LinkedModeModel model, VerifyEvent event, int offset, int length) { showPreview = (event.stateMask & SWT.CTRL) != 0 && (event.character == SWT.CR || event.character == SWT.LF); if (length == 0 && (event.character == SWT.BS || event.character == SWT.DEL)) { LinkedPosition position = model.findPosition(new LinkedPosition(document, offset, 0, LinkedPositionGroup.NO_STOP)); if (position != null) { if (event.character == SWT.BS) { if (offset - 1 < position.getOffset()) { // skip backspace at beginning of linked position event.doit = false; } } else /* event.character == SWT.DEL */{ if (offset + 1 > position.getOffset() + position.getLength()) { // skip delete at end of linked position event.doit = false; } } } } return null; // don't change behavior }
/** * Helper to generate an iterator based <code>for</code> loop to iterate over an {@link Iterable}. * * @param ast the {@link AST} instance to rewrite the loop to * @return the complete {@link ASTRewrite} object */ private ASTRewrite generateIteratorBasedForRewrite(AST ast) { ASTRewrite rewrite = ASTRewrite.create(ast); ForStatement loopStatement = ast.newForStatement(); ITypeBinding loopOverType = extractElementType(ast); SimpleName loopVariableName = resolveLinkedVariableNameWithProposals(rewrite, "iterator", null, true); // $NON-NLS-1$ loopStatement.initializers().add(getIteratorBasedForInitializer(rewrite, loopVariableName)); MethodInvocation loopExpression = ast.newMethodInvocation(); loopExpression.setName(ast.newSimpleName("hasNext")); // $NON-NLS-1$ SimpleName expressionName = ast.newSimpleName(loopVariableName.getIdentifier()); addLinkedPosition( rewrite.track(expressionName), LinkedPositionGroup.NO_STOP, expressionName.getIdentifier()); loopExpression.setExpression(expressionName); loopStatement.setExpression(loopExpression); Block forLoopBody = ast.newBlock(); Assignment assignResolvedVariable = getIteratorBasedForBodyAssignment(rewrite, loopOverType, loopVariableName); forLoopBody.statements().add(ast.newExpressionStatement(assignResolvedVariable)); forLoopBody.statements().add(createBlankLineStatementWithCursorPosition(rewrite)); loopStatement.setBody(forLoopBody); rewrite.replace(fCurrentNode, loopStatement, null); return rewrite; }
/** * Generates the Assignment in an iterator based for, used in the first statement of an iterator * based <code>for</code> loop body, to retrieve the next element of the {@link Iterable} * instance. * * @param rewrite the current instance of {@link ASTRewrite} * @param loopOverType the {@link ITypeBinding} of the loop variable * @param loopVariableName the name of the loop variable * @return an {@link Assignment}, which retrieves the next element of the {@link Iterable} using * the active {@link Iterator} */ private Assignment getIteratorBasedForBodyAssignment( ASTRewrite rewrite, ITypeBinding loopOverType, SimpleName loopVariableName) { AST ast = rewrite.getAST(); Assignment assignResolvedVariable = ast.newAssignment(); // left hand side SimpleName resolvedVariableName = resolveLinkedVariableNameWithProposals( rewrite, loopOverType.getName(), loopVariableName.getIdentifier(), false); VariableDeclarationFragment resolvedVariableDeclarationFragment = ast.newVariableDeclarationFragment(); resolvedVariableDeclarationFragment.setName(resolvedVariableName); VariableDeclarationExpression resolvedVariableDeclaration = ast.newVariableDeclarationExpression(resolvedVariableDeclarationFragment); resolvedVariableDeclaration.setType( getImportRewrite() .addImport( loopOverType, ast, new ContextSensitiveImportRewriteContext(fCurrentNode, getImportRewrite()))); assignResolvedVariable.setLeftHandSide(resolvedVariableDeclaration); // right hand side MethodInvocation invokeIteratorNextExpression = ast.newMethodInvocation(); invokeIteratorNextExpression.setName(ast.newSimpleName("next")); // $NON-NLS-1$ SimpleName currentElementName = ast.newSimpleName(loopVariableName.getIdentifier()); addLinkedPosition( rewrite.track(currentElementName), LinkedPositionGroup.NO_STOP, currentElementName.getIdentifier()); invokeIteratorNextExpression.setExpression(currentElementName); assignResolvedVariable.setRightHandSide(invokeIteratorNextExpression); assignResolvedVariable.setOperator(Assignment.Operator.ASSIGN); return assignResolvedVariable; }
/** * Creates an {@link Assignment} as first expression appearing in a <code>for</code> loop's body. * This Assignment declares a local variable and initializes it using the array's current element * identified by the loop index. * * @param rewrite the current {@link ASTRewrite} instance * @param loopVariableName the name of the index variable in String representation * @return a completed {@link Assignment} containing the mentioned declaration and initialization */ private Assignment getForBodyAssignment(ASTRewrite rewrite, SimpleName loopVariableName) { AST ast = rewrite.getAST(); ITypeBinding loopOverType = extractElementType(ast); Assignment assignResolvedVariable = ast.newAssignment(); // left hand side SimpleName resolvedVariableName = resolveLinkedVariableNameWithProposals( rewrite, loopOverType.getName(), loopVariableName.getIdentifier(), false); VariableDeclarationFragment resolvedVariableDeclarationFragment = ast.newVariableDeclarationFragment(); resolvedVariableDeclarationFragment.setName(resolvedVariableName); VariableDeclarationExpression resolvedVariableDeclaration = ast.newVariableDeclarationExpression(resolvedVariableDeclarationFragment); resolvedVariableDeclaration.setType( getImportRewrite() .addImport( loopOverType, ast, new ContextSensitiveImportRewriteContext(fCurrentNode, getImportRewrite()))); assignResolvedVariable.setLeftHandSide(resolvedVariableDeclaration); // right hand side ArrayAccess access = ast.newArrayAccess(); access.setArray((Expression) rewrite.createCopyTarget(fCurrentExpression)); SimpleName indexName = ast.newSimpleName(loopVariableName.getIdentifier()); addLinkedPosition( rewrite.track(indexName), LinkedPositionGroup.NO_STOP, indexName.getIdentifier()); access.setIndex(indexName); assignResolvedVariable.setRightHandSide(access); assignResolvedVariable.setOperator(Assignment.Operator.ASSIGN); return assignResolvedVariable; }
/** * Creates an {@link InfixExpression} which is linked to the group of the variableToIncrement. * * @param rewrite the current {@link ASTRewrite} instance * @param variableToIncrement the name of the variable to generate the {@link InfixExpression} for * @param rightHandSide the right hand side expression which shall be included in the {@link * InfixExpression} * @param operator the {@link org.eclipse.jdt.core.dom.InfixExpression.Operator} to use in the * {@link InfixExpression} to create * @return a filled, new {@link InfixExpression} instance */ private InfixExpression getLinkedInfixExpression( ASTRewrite rewrite, String variableToIncrement, Expression rightHandSide, InfixExpression.Operator operator) { AST ast = rewrite.getAST(); InfixExpression loopExpression = ast.newInfixExpression(); SimpleName name = ast.newSimpleName(variableToIncrement); addLinkedPosition(rewrite.track(name), LinkedPositionGroup.NO_STOP, name.getIdentifier()); loopExpression.setLeftOperand(name); loopExpression.setOperator(operator); loopExpression.setRightOperand(rightHandSide); return loopExpression; }
/** * Creates an {@link Assignment} as first expression appearing in an index based <code>for</code> * loop's body. This Assignment declares a local variable and initializes it using the {@link * List}'s current element identified by the loop index. * * @param rewrite the current {@link ASTRewrite} instance * @param loopVariableName the name of the index variable in String representation * @return a completed {@link Assignment} containing the mentioned declaration and initialization */ private Expression getIndexBasedForBodyAssignment( ASTRewrite rewrite, SimpleName loopVariableName) { AST ast = rewrite.getAST(); ITypeBinding loopOverType = extractElementType(ast); Assignment assignResolvedVariable = ast.newAssignment(); // left hand side SimpleName resolvedVariableName = resolveLinkedVariableNameWithProposals( rewrite, loopOverType.getName(), loopVariableName.getIdentifier(), false); VariableDeclarationFragment resolvedVariableDeclarationFragment = ast.newVariableDeclarationFragment(); resolvedVariableDeclarationFragment.setName(resolvedVariableName); VariableDeclarationExpression resolvedVariableDeclaration = ast.newVariableDeclarationExpression(resolvedVariableDeclarationFragment); resolvedVariableDeclaration.setType( getImportRewrite() .addImport( loopOverType, ast, new ContextSensitiveImportRewriteContext(fCurrentNode, getImportRewrite()))); assignResolvedVariable.setLeftHandSide(resolvedVariableDeclaration); // right hand side MethodInvocation invokeGetExpression = ast.newMethodInvocation(); invokeGetExpression.setName(ast.newSimpleName("get")); // $NON-NLS-1$ SimpleName indexVariableName = ast.newSimpleName(loopVariableName.getIdentifier()); addLinkedPosition( rewrite.track(indexVariableName), LinkedPositionGroup.NO_STOP, indexVariableName.getIdentifier()); invokeGetExpression.arguments().add(indexVariableName); invokeGetExpression.setExpression((Expression) rewrite.createCopyTarget(fCurrentExpression)); assignResolvedVariable.setRightHandSide(invokeGetExpression); assignResolvedVariable.setOperator(Assignment.Operator.ASSIGN); return assignResolvedVariable; }
/** * Sets up a simple linked mode at {@link #getCursorPosition()} and an exit policy that will * exit the mode when <code>closingCharacter</code> is typed and an exit position at * <code>getCursorPosition() + 1</code>. * * @param document the document * @param closingCharacter the exit character */ protected void setUpLinkedMode(IDocument document, char closingCharacter) { if (getTextViewer() != null && autocloseBrackets()) { int offset= getReplacementOffset() + getCursorPosition(); int exit= getReplacementOffset() + getReplacementString().length(); try { LinkedPositionGroup group= new LinkedPositionGroup(); group.addPosition(new LinkedPosition(document, offset, 0, LinkedPositionGroup.NO_STOP)); LinkedModeModel model= new LinkedModeModel(); model.addGroup(group); model.forceInstall(); LinkedModeUI ui= new EditorLinkedModeUI(model, getTextViewer()); ui.setSimpleMode(true); ui.setExitPolicy(new ExitPolicy(closingCharacter, document)); ui.setExitPosition(getTextViewer(), exit, 0, Integer.MAX_VALUE); ui.setCyclingMode(LinkedModeUI.CYCLE_NEVER); ui.enter(); } catch (BadLocationException x) { JavaPlugin.log(x); } } }
/** * Generates the Assignment in an iterator based for, used in the first statement of an iterator * based <code>for</code> loop body, to retrieve the next element of the {@link Iterable} * instance. * * @param rewrite the current instance of {@link ASTRewrite} * @param loopOverType the {@link ITypeBinding} of the loop variable * @param loopVariableName the name of the loop variable * @return an {@link Assignment}, which retrieves the next element of the {@link Iterable} using * the active {@link Iterator} */ private Assignment getIteratorBasedForBodyAssignment(ASTRewrite rewrite, ITypeBinding loopOverType, SimpleName loopVariableName) { AST ast= rewrite.getAST(); Assignment assignResolvedVariable= ast.newAssignment(); // left hand side SimpleName resolvedVariableName= resolveLinkedVariableNameWithProposals(rewrite, loopOverType.getName(), loopVariableName.getIdentifier(), false); VariableDeclarationFragment resolvedVariableDeclarationFragment= ast.newVariableDeclarationFragment(); resolvedVariableDeclarationFragment.setName(resolvedVariableName); VariableDeclarationExpression resolvedVariableDeclaration= ast.newVariableDeclarationExpression(resolvedVariableDeclarationFragment); resolvedVariableDeclaration.setType(getImportRewrite().addImport(loopOverType, ast, new ContextSensitiveImportRewriteContext(fCurrentNode, getImportRewrite()))); assignResolvedVariable.setLeftHandSide(resolvedVariableDeclaration); // right hand side MethodInvocation invokeIteratorNextExpression= ast.newMethodInvocation(); invokeIteratorNextExpression.setName(ast.newSimpleName("next")); //$NON-NLS-1$ SimpleName currentElementName= ast.newSimpleName(loopVariableName.getIdentifier()); addLinkedPosition(rewrite.track(currentElementName), LinkedPositionGroup.NO_STOP, currentElementName.getIdentifier()); invokeIteratorNextExpression.setExpression(currentElementName); assignResolvedVariable.setRightHandSide(invokeIteratorNextExpression); assignResolvedVariable.setOperator(Assignment.Operator.ASSIGN); return assignResolvedVariable; }
public ExitFlags doExit(LinkedModeModel model, VerifyEvent event, int offset, int length) { if (length == 0 && (event.character == SWT.BS || event.character == SWT.DEL)) { LinkedPosition position= model.findPosition(new LinkedPosition(fDocument, offset, 0, LinkedPositionGroup.NO_STOP)); if (position != null) { if (event.character == SWT.BS) { if (offset - 1 < position.getOffset()) { //skip backspace at beginning of linked position event.doit= false; } } else /* event.character == SWT.DEL */ { if (offset + 1 > position.getOffset() + position.getLength()) { //skip delete at end of linked position event.doit= false; } } } } return null; // don't change behavior }
private void startLinkedEdit(List<IRegion> selections, ITextViewer viewer, Point originalSelection) throws BadLocationException { final LinkedPositionGroup linkedPositionGroup = new LinkedPositionGroup(); for (IRegion selection : selections) { linkedPositionGroup.addPosition(new LinkedPosition(viewer.getDocument(), selection.getOffset(), selection .getLength())); } LinkedModeModel model = new LinkedModeModel(); model.addGroup(linkedPositionGroup); model.forceInstall(); //FIXME can add a listener here to listen for the end of linked mode //model.addLinkingListener(null); LinkedModeUI ui = new EditorLinkedModeUI(model, viewer); ui.setExitPolicy(new DeleteBlockingExitPolicy(viewer.getDocument())); ui.enter(); // by default the text being edited is selected so restore original selection viewer.setSelectedRange(originalSelection.x, originalSelection.y); }
protected LinkedModeModel getLinkedModeModel(ITextViewer viewer) throws BadLocationException { Indexable<SourceRange> sourceSubElements = proposal.getSourceSubElements(); if(sourceSubElements == null || sourceSubElements.isEmpty()) { return null; } LinkedModeModel model = new LinkedModeModel(); IDocument document = viewer.getDocument(); int replaceOffset = getReplaceOffset(); firstLinkedModeGroupPosition = -1; for (SourceRange sr : sourceSubElements) { LinkedPositionGroup group = new LinkedPositionGroup(); int posOffset = replaceOffset + sr.getOffset(); group.addPosition(new LinkedPosition(document, posOffset, sr.getLength())); if(firstLinkedModeGroupPosition == -1) { firstLinkedModeGroupPosition = posOffset; } model.addGroup(group); } return model; }
public void apply(IDocument document) { try { if (fentry.arguments > 0) { StringBuffer displayKey = new StringBuffer(fentry.key); for (int j=0; j < fentry.arguments; j++) displayKey.append("{}"); document.replace(fReplacementOffset, fReplacementLength, displayKey.toString()); if (TexlipsePlugin.getDefault().getPreferenceStore() .getBoolean(TexlipseProperties.SMART_PARENS)){ LinkedModeModel model= new LinkedModeModel(); for (int j=0; j < fentry.arguments; j++){ int newOffset = fReplacementOffset + fentry.key.length() + j*2 + 1; LinkedPositionGroup group = new LinkedPositionGroup(); group.addPosition(new LinkedPosition(document, newOffset, 0, LinkedPositionGroup.NO_STOP)); model.addGroup(group); } model.forceInstall(); LinkedModeUI ui = new EditorLinkedModeUI(model, fviewer); ui.setSimpleMode(false); ui.setExitPolicy(new ExitPolicy('}', fviewer)); ui.setExitPosition(fviewer, fReplacementOffset + displayKey.length(), 0, Integer.MAX_VALUE); ui.setCyclingMode(LinkedModeUI.CYCLE_NEVER); ui.enter(); } } else { document.replace(fReplacementOffset, fReplacementLength, fentry.key); } } catch (BadLocationException x) { } }
protected LinkedPositionGroup createLinkedGroupFromReplaceEdits(List<ReplaceEdit> edits, XtextEditor xtextEditor, final String originalName, SubMonitor progress) { if (edits == null) return null; final IXtextDocument document = xtextEditor.getDocument(); LinkedPositionGroup group = new LinkedPositionGroup(); Iterable<LinkedPosition> linkedPositions = filter( Iterables.transform(edits, new Function<ReplaceEdit, LinkedPosition>() { public LinkedPosition apply(ReplaceEdit edit) { try { String textToReplace = document.get(edit.getOffset(), edit.getLength()); int indexOf = textToReplace.indexOf(originalName); if (indexOf != -1) { int calculatedOffset = edit.getOffset() + indexOf; return new LinkedPosition(document, calculatedOffset, originalName.length()); } } catch (BadLocationException exc) { LOG.error("Skipping invalid text edit " + notNull(edit), exc); } return null; } }), Predicates.notNull()); progress.worked(10); final int invocationOffset = xtextEditor.getInternalSourceViewer().getSelectedRange().x; int i = 0; for (LinkedPosition position : sortPositions(linkedPositions, invocationOffset)) { try { position.setSequenceNumber(i); i++; group.addPosition(position); } catch (BadLocationException e) { LOG.error(e.getMessage(), e); return null; } } return group; }
public VariablePosition( IDocument document, int offset, int length, MultiVariableGuess guess, MultiVariable variable) { this(document, offset, length, LinkedPositionGroup.NO_STOP, guess, variable); }
/** * Creates a {@link PostfixExpression} used to increment the loop variable of a <code>for</code> * loop to iterate over an array. * * @param rewrite the current {@link ASTRewrite} instance * @param variableToIncrement the name of the variable to increment * @return a filled {@link PostfixExpression} realizing an incrementation of the specified * variable */ private Expression getLinkedIncrementExpression(ASTRewrite rewrite, String variableToIncrement) { AST ast = rewrite.getAST(); PostfixExpression incrementLoopVariable = ast.newPostfixExpression(); SimpleName name = ast.newSimpleName(variableToIncrement); addLinkedPosition(rewrite.track(name), LinkedPositionGroup.NO_STOP, name.getIdentifier()); incrementLoopVariable.setOperand(name); incrementLoopVariable.setOperator(PostfixExpression.Operator.INCREMENT); return incrementLoopVariable; }
@Override public void apply(ITextViewer viewer, char trigger, int stateMask, int offset) { apply(viewer.getDocument()); try { LinkedModeModel model = new LinkedModeModel(); StringBuffer insert = new StringBuffer(); insert.append(macro.name); insert.append("("); int parameterOffset = position.offset + insert.length(); for (int k = 0; k < macro.parameters.length; k++) { LinkedPositionGroup group = new LinkedPositionGroup(); if (k > 0) // space between parameters parameterOffset++; group.addPosition(new LinkedPosition(viewer.getDocument(), parameterOffset, macro.parameters[k].length(), LinkedPositionGroup.NO_STOP)); model.addGroup(group); parameterOffset += macro.parameters[k].length(); } model.forceInstall(); LinkedModeUI ui = new EditorLinkedModeUI(model, viewer); ui.setExitPosition(viewer, parameterOffset + 1, 0, Integer.MAX_VALUE); ui.setCyclingMode(LinkedModeUI.CYCLE_ALWAYS); ui.enter(); fSelectedRegion = ui.getSelectedRegion(); } catch (Exception e) { e.printStackTrace(); } }
/** * Special code added to allow tabstop positions so we can easily tab past the quotes for Events/Attributes. */ @Override public void apply(ITextViewer viewer, char trigger, int stateMask, int offset) { super.apply(viewer, trigger, stateMask, offset); // See if there are any positions that should be linked. Last is always exit, first is cursor position if (_positions != null && _positions.length > 0) { IDocument document = viewer.getDocument(); boolean validPrefix = isValidPrefix(getPrefix(document, offset), getDisplayString()); int shift = (validPrefix) ? offset - this._replacementOffset : 0; try { LinkedModeModel.closeAllModels(document); // Exit out of any existing linked mode LinkedModeModel model = new LinkedModeModel(); int i = 0; for (int pos : _positions) { LinkedPositionGroup group = new LinkedPositionGroup(); group.addPosition(new LinkedPosition(document, (offset - shift) + pos, 0, i++)); model.addGroup(group); } model.forceInstall(); LinkedModeUI ui = new LinkedModeUI(model, viewer); ui.setCyclingMode(LinkedModeUI.CYCLE_ALWAYS); ui.setExitPosition(viewer, (offset - shift) + _positions[_positions.length - 1], 0, Integer.MAX_VALUE); ui.enter(); } catch (BadLocationException e) { IdeLog.logError(XMLPlugin.getDefault(), e); } } }
/** * Special code added to allow tabstop positions so we can easily tab past the quotes for Events/Attributes. */ @Override public void apply(ITextViewer viewer, char trigger, int stateMask, int offset) { super.apply(viewer, trigger, stateMask, offset); // See if there are any positions that should be linked. Last is always exit, first is cursor position if (_positions != null && _positions.length > 0) { IDocument document = viewer.getDocument(); boolean validPrefix = isValidPrefix(getPrefix(document, offset), getDisplayString()); int shift = (validPrefix) ? offset - this._replacementOffset : 0; try { LinkedModeModel.closeAllModels(document); // Exit out of any existing linked mode LinkedModeModel model = new LinkedModeModel(); int i = 0; for (int pos : _positions) { LinkedPositionGroup group = new LinkedPositionGroup(); group.addPosition(new LinkedPosition(document, (offset - shift) + pos, 0, i++)); model.addGroup(group); } model.forceInstall(); LinkedModeUI ui = new LinkedModeUI(model, viewer); ui.setCyclingMode(LinkedModeUI.CYCLE_ALWAYS); ui.setExitPosition(viewer, (offset - shift) + _positions[_positions.length - 1], 0, Integer.MAX_VALUE); ui.enter(); } catch (BadLocationException e) { IdeLog.logError(HTMLPlugin.getDefault(), e); } } }
@Override public void apply(IDocument document, char trigger, int offset) { super.apply(document, trigger, offset); int baseOffset= getReplacementOffset(); String replacement= getReplacementString(); if (fArgumentOffsets != null && getTextViewer() != null) { try { LinkedModeModel model= new LinkedModeModel(); for (int i= 0; i != fArgumentOffsets.length; i++) { LinkedPositionGroup group= new LinkedPositionGroup(); group.addPosition(new LinkedPosition(document, baseOffset + fArgumentOffsets[i], fArgumentLengths[i], LinkedPositionGroup.NO_STOP)); model.addGroup(group); } model.forceInstall(); JavaEditor editor= getJavaEditor(); if (editor != null) { model.addLinkingListener(new EditorHighlightingSynchronizer(editor)); } LinkedModeUI ui= new EditorLinkedModeUI(model, getTextViewer()); ui.setExitPosition(getTextViewer(), baseOffset + replacement.length(), 0, Integer.MAX_VALUE); ui.setExitPolicy(new ExitPolicy(')', document)); ui.setDoContextInfo(true); ui.setCyclingMode(LinkedModeUI.CYCLE_WHEN_NO_PARENT); ui.enter(); fSelectedRegion= ui.getSelectedRegion(); } catch (BadLocationException e) { JavaPlugin.log(e); openErrorDialog(e); } } else { fSelectedRegion= new Region(baseOffset + replacement.length(), 0); } }
/** * Helper to generate an iterator based <code>for</code> loop to iterate over an * {@link Iterable}. * * @param ast the {@link AST} instance to rewrite the loop to * @return the complete {@link ASTRewrite} object */ private ASTRewrite generateIteratorBasedForRewrite(AST ast) { ASTRewrite rewrite= ASTRewrite.create(ast); ForStatement loopStatement= ast.newForStatement(); ITypeBinding loopOverType= extractElementType(ast); SimpleName loopVariableName= resolveLinkedVariableNameWithProposals(rewrite, "iterator", null, true); //$NON-NLS-1$ loopStatement.initializers().add(getIteratorBasedForInitializer(rewrite, loopVariableName)); MethodInvocation loopExpression= ast.newMethodInvocation(); loopExpression.setName(ast.newSimpleName("hasNext")); //$NON-NLS-1$ SimpleName expressionName= ast.newSimpleName(loopVariableName.getIdentifier()); addLinkedPosition(rewrite.track(expressionName), LinkedPositionGroup.NO_STOP, expressionName.getIdentifier()); loopExpression.setExpression(expressionName); loopStatement.setExpression(loopExpression); Block forLoopBody= ast.newBlock(); Assignment assignResolvedVariable= getIteratorBasedForBodyAssignment(rewrite, loopOverType, loopVariableName); forLoopBody.statements().add(ast.newExpressionStatement(assignResolvedVariable)); forLoopBody.statements().add(createBlankLineStatementWithCursorPosition(rewrite)); loopStatement.setBody(forLoopBody); rewrite.replace(fCurrentNode, loopStatement, null); return rewrite; }
/** * Creates an {@link Assignment} as first expression appearing in a <code>for</code> loop's * body. This Assignment declares a local variable and initializes it using the array's current * element identified by the loop index. * * @param rewrite the current {@link ASTRewrite} instance * @param loopVariableName the name of the index variable in String representation * @return a completed {@link Assignment} containing the mentioned declaration and * initialization */ private Assignment getForBodyAssignment(ASTRewrite rewrite, SimpleName loopVariableName) { AST ast= rewrite.getAST(); ITypeBinding loopOverType= extractElementType(ast); Assignment assignResolvedVariable= ast.newAssignment(); // left hand side SimpleName resolvedVariableName= resolveLinkedVariableNameWithProposals(rewrite, loopOverType.getName(), loopVariableName.getIdentifier(), false); VariableDeclarationFragment resolvedVariableDeclarationFragment= ast.newVariableDeclarationFragment(); resolvedVariableDeclarationFragment.setName(resolvedVariableName); VariableDeclarationExpression resolvedVariableDeclaration= ast.newVariableDeclarationExpression(resolvedVariableDeclarationFragment); resolvedVariableDeclaration.setType(getImportRewrite().addImport(loopOverType, ast, new ContextSensitiveImportRewriteContext(fCurrentNode, getImportRewrite()))); assignResolvedVariable.setLeftHandSide(resolvedVariableDeclaration); // right hand side ArrayAccess access= ast.newArrayAccess(); access.setArray((Expression) rewrite.createCopyTarget(fCurrentExpression)); SimpleName indexName= ast.newSimpleName(loopVariableName.getIdentifier()); addLinkedPosition(rewrite.track(indexName), LinkedPositionGroup.NO_STOP, indexName.getIdentifier()); access.setIndex(indexName); assignResolvedVariable.setRightHandSide(access); assignResolvedVariable.setOperator(Assignment.Operator.ASSIGN); return assignResolvedVariable; }
/** * Creates an {@link InfixExpression} which is linked to the group of the variableToIncrement. * * @param rewrite the current {@link ASTRewrite} instance * @param variableToIncrement the name of the variable to generate the {@link InfixExpression} * for * @param rightHandSide the right hand side expression which shall be included in the * {@link InfixExpression} * @param operator the {@link org.eclipse.jdt.core.dom.InfixExpression.Operator} to use in the * {@link InfixExpression} to create * @return a filled, new {@link InfixExpression} instance */ private InfixExpression getLinkedInfixExpression(ASTRewrite rewrite, String variableToIncrement, Expression rightHandSide, InfixExpression.Operator operator) { AST ast= rewrite.getAST(); InfixExpression loopExpression= ast.newInfixExpression(); SimpleName name= ast.newSimpleName(variableToIncrement); addLinkedPosition(rewrite.track(name), LinkedPositionGroup.NO_STOP, name.getIdentifier()); loopExpression.setLeftOperand(name); loopExpression.setOperator(operator); loopExpression.setRightOperand(rightHandSide); return loopExpression; }
/** * Creates a {@link PostfixExpression} used to increment the loop variable of a <code>for</code> * loop to iterate over an array. * * @param rewrite the current {@link ASTRewrite} instance * @param variableToIncrement the name of the variable to increment * @return a filled {@link PostfixExpression} realizing an incrementation of the specified * variable */ private Expression getLinkedIncrementExpression(ASTRewrite rewrite, String variableToIncrement) { AST ast= rewrite.getAST(); PostfixExpression incrementLoopVariable= ast.newPostfixExpression(); SimpleName name= ast.newSimpleName(variableToIncrement); addLinkedPosition(rewrite.track(name), LinkedPositionGroup.NO_STOP, name.getIdentifier()); incrementLoopVariable.setOperand(name); incrementLoopVariable.setOperator(PostfixExpression.Operator.INCREMENT); return incrementLoopVariable; }
/** * Creates an {@link Assignment} as first expression appearing in an index based * <code>for</code> loop's body. This Assignment declares a local variable and initializes it * using the {@link List}'s current element identified by the loop index. * * @param rewrite the current {@link ASTRewrite} instance * @param loopVariableName the name of the index variable in String representation * @return a completed {@link Assignment} containing the mentioned declaration and * initialization */ private Expression getIndexBasedForBodyAssignment(ASTRewrite rewrite, SimpleName loopVariableName) { AST ast= rewrite.getAST(); ITypeBinding loopOverType= extractElementType(ast); Assignment assignResolvedVariable= ast.newAssignment(); // left hand side SimpleName resolvedVariableName= resolveLinkedVariableNameWithProposals(rewrite, loopOverType.getName(), loopVariableName.getIdentifier(), false); VariableDeclarationFragment resolvedVariableDeclarationFragment= ast.newVariableDeclarationFragment(); resolvedVariableDeclarationFragment.setName(resolvedVariableName); VariableDeclarationExpression resolvedVariableDeclaration= ast.newVariableDeclarationExpression(resolvedVariableDeclarationFragment); resolvedVariableDeclaration.setType(getImportRewrite().addImport(loopOverType, ast, new ContextSensitiveImportRewriteContext(fCurrentNode, getImportRewrite()))); assignResolvedVariable.setLeftHandSide(resolvedVariableDeclaration); // right hand side MethodInvocation invokeGetExpression= ast.newMethodInvocation(); invokeGetExpression.setName(ast.newSimpleName("get")); //$NON-NLS-1$ SimpleName indexVariableName= ast.newSimpleName(loopVariableName.getIdentifier()); addLinkedPosition(rewrite.track(indexVariableName), LinkedPositionGroup.NO_STOP, indexVariableName.getIdentifier()); invokeGetExpression.arguments().add(indexVariableName); invokeGetExpression.setExpression((Expression) rewrite.createCopyTarget(fCurrentExpression)); assignResolvedVariable.setRightHandSide(invokeGetExpression); assignResolvedVariable.setOperator(Assignment.Operator.ASSIGN); return assignResolvedVariable; }
private void goToLinkedMode(ITextViewer viewer, int offset, IDocument doc, int exitPos, int iPar, List<Integer> offsetsAndLens) throws BadLocationException { if (!goToLinkedMode) { return; } if (offsetsAndLens.size() > 0) { LinkedModeModel model = new LinkedModeModel(); for (int i = 0; i < offsetsAndLens.size(); i++) { Integer offs = offsetsAndLens.get(i); i++; Integer len = offsetsAndLens.get(i); if (i == 1) { firstParameterLen = len; } int location = offset + iPar + offs + 1; LinkedPositionGroup group = new LinkedPositionGroup(); ProposalPosition proposalPosition = new ProposalPosition(doc, location, len, 0, new ICompletionProposal[0]); group.addPosition(proposalPosition); model.addGroup(group); } model.forceInstall(); final LinkedModeUI ui = new EditorLinkedModeUI(model, viewer); ui.setDoContextInfo(true); //set it to request the ctx info from the completion processor ui.setExitPosition(viewer, exitPos, 0, Integer.MAX_VALUE); Runnable r = new Runnable() { @Override public void run() { ui.enter(); } }; RunInUiThread.async(r); } }
/** * Really do apply the proposal. Assumed to be run within the prevent flickering mode. */ private int doApply(QualifiedName qualifiedName, String alias, IDocument document, ConfigurableCompletionProposal proposal) throws BadLocationException { String shortSemanticReplacementString = alias != null ? alias : lastSegmentOrDefaultHost(qualifiedName); String shortSyntacticReplacementString = valueConverter.toString(shortSemanticReplacementString); ImportRewriter importRewriter = importRewriterFactory.create(document, context); ReplaceEdit replaceEdit = new ReplaceEdit( proposal.getReplacementOffset(), proposal.getReplacementLength(), shortSyntacticReplacementString); MultiTextEdit compound = new MultiTextEdit(); AliasLocation aliasLocation = null; if (alias != null) { aliasLocation = importRewriter.addSingleImport(qualifiedName, alias, compound); } else { importRewriter.addSingleImport(qualifiedName, compound); } compound.addChild(replaceEdit); Position caret = new Position(proposal.getReplacementOffset(), 0); document.addPosition(caret); compound.apply(document); document.removePosition(caret); int cursorPosition = caret.getOffset(); proposal.setReplacementOffset(cursorPosition - shortSemanticReplacementString.length()); proposal.setCursorPosition(shortSemanticReplacementString.length()); if (aliasLocation != null) { final int aliasOffset = aliasLocation.getBaseOffset() + aliasLocation.getRelativeOffset(); final int aliasLength = shortSyntacticReplacementString.length(); N4JSCompletionProposal castedProposal = (N4JSCompletionProposal) proposal; castedProposal.setLinkedModeBuilder((appliedProposal, currentDocument) -> { try { LinkedPositionGroup group = new LinkedPositionGroup(); group.addPosition(new LinkedPosition( currentDocument, aliasOffset, aliasLength, LinkedPositionGroup.NO_STOP)); group.addPosition(new LinkedPosition( currentDocument, proposal.getReplacementOffset(), proposal.getCursorPosition(), LinkedPositionGroup.NO_STOP)); proposal.setSelectionStart(proposal.getReplacementOffset()); proposal.setSelectionLength(proposal.getCursorPosition()); LinkedModeModel model = new LinkedModeModel(); model.addGroup(group); model.forceInstall(); LinkedModeUI ui = new LinkedModeUI(model, viewer); ui.setExitPolicy(new IdentifierExitPolicy('\n')); ui.setExitPosition( viewer, proposal.getCursorPosition() + proposal.getReplacementOffset(), 0, Integer.MAX_VALUE); ui.setCyclingMode(LinkedModeUI.CYCLE_NEVER); ui.enter(); } catch (BadLocationException e) { logger.error(e.getMessage(), e); } }); } return cursorPosition; }
/** * Switches the focus position to <code>position</code> given the * <code>LinkedModeModel env</code>. The slave positions for <code>position</code> is extracted * from the environment and set accordingly, the target positions are updated as well. * * @param env the linked mode model * @param position the linked position */ public void switchToPosition(LinkedModeModel env, LinkedPosition position) { if (fDocument == null || (position != null && getPosition(fFocusAnnotation) == position) || (position == null && fFocusAnnotation == null)) return; LinkedPositionGroup linkedGroup= null; if (position != null) linkedGroup= env.getGroupForPosition(position); List targets= new ArrayList(); targets.addAll(Arrays.asList(fTargets)); List group; if (linkedGroup != null) group= new ArrayList(Arrays.asList(linkedGroup.getPositions())); else group= new ArrayList(); if (position == null || !fDocument.equals(position.getDocument())) // position is not valid if not in this document position= null; LinkedPosition exit= fExitPosition; if (exit == null || !fDocument.equals(exit.getDocument())) // position is not valid if not in this document exit= null; if (exit != null) { group.remove(exit); targets.remove(exit); } group.removeAll(targets); targets.remove(position); group.remove(position); prune(targets); prune(group); try { setFocusPosition(position); setExitPosition(exit); setGroupPositions(group); setTargetPositions(targets); } catch (BadLocationException e) { // will never happen as we don't actually add/remove positions from the document // see the addPosition / removePosition methods Assert.isTrue(false); } fireModelChanged(); }
public void start() { if (getActiveLinkedMode() != null) { // for safety; should already be handled in RenameJavaElementAction fgActiveLinkedMode.startFullDialog(); return; } ISourceViewer viewer = fEditor.getViewer(); IDocument document = viewer.getDocument(); ITypeScriptFile tsFile = fEditor.getTypeScriptFile(); tsFile.setDisableChanged(true); fOriginalSelection = viewer.getSelectedRange(); int offset = fOriginalSelection.x; try { fLinkedPositionGroup = new LinkedPositionGroup(); 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); } } // Find occurrences List<OccurrencesResponseItem> occurrences = tsFile.occurrences(offset).get(1000, TimeUnit.MILLISECONDS); // Create Eclipse linked position from the occurrences list. int start, length; for (int i = 0; i < occurrences.size(); i++) { OccurrencesResponseItem item = occurrences.get(i); start = tsFile.getPosition(item.getStart()); length = tsFile.getPosition(item.getEnd()) - start; LinkedPosition linkedPosition = new LinkedPosition(document, start, length, i); if (i == 0) { fOriginalName = document.get(start, length); 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 (Exception e) { JSDTTypeScriptUIPlugin.log(e); } }
public LinkedPositionGroup getLinkedPositionGroup(IRenameElementContext renameElementContext, IProgressMonitor monitor);
public LinkedPositionGroup getLinkedPositionGroup(IRenameElementContext renameElementContext, IProgressMonitor monitor) { SubMonitor progress = SubMonitor.convert(monitor, 100); XtextEditor editor = (XtextEditor) renameElementContext.getTriggeringEditor(); IProject project = projectUtil.getProject(renameElementContext.getContextResourceURI()); if (project == null) throw new IllegalStateException("Could not determine project for context resource " + renameElementContext.getContextResourceURI()); ResourceSet resourceSet = resourceSetProvider.get(project); EObject targetElement = resourceSet.getEObject(renameElementContext.getTargetElementURI(), true); if (targetElement == null) throw new IllegalStateException("Target element could not be loaded"); IRenameStrategy.Provider strategyProvider = globalServiceProvider.findService(targetElement, IRenameStrategy.Provider.class); IRenameStrategy renameStrategy = null; try { renameStrategy = strategyProvider.get(targetElement, renameElementContext); } catch(NoSuchStrategyException exc) { // handle in next line } if(renameStrategy == null) throw new IllegalArgumentException("Cannot find a rename strategy for " + notNull(renameElementContext.getTargetElementURI())); String newName = renameStrategy.getOriginalName(); IResourceServiceProvider resourceServiceProvider = resourceServiceProviderRegistry.getResourceServiceProvider(renameElementContext.getTargetElementURI()); IDependentElementsCalculator dependentElementsCalculator = resourceServiceProvider.get(IDependentElementsCalculator.class); Iterable<URI> dependentElementURIs = dependentElementsCalculator.getDependentElementURIs(targetElement, progress.newChild(10)); LocalResourceRefactoringUpdateAcceptor updateAcceptor = updateAcceptorProvider.get(); updateAcceptor.setLocalResourceURI(renameElementContext.getContextResourceURI()); renameStrategy.createDeclarationUpdates(newName, resourceSet, updateAcceptor); Map<URI, URI> original2newEObjectURI = renamedElementTracker.renameAndTrack( concat(Collections.singleton(renameElementContext.getTargetElementURI()), dependentElementURIs), newName, resourceSet, renameStrategy, progress.newChild(10)); ElementRenameArguments elementRenameArguments = new ElementRenameArguments( renameElementContext.getTargetElementURI(), newName, renameStrategy, original2newEObjectURI); final List<IReferenceDescription> referenceDescriptions = newArrayList(); IAcceptor<IReferenceDescription> referenceAcceptor = new IAcceptor<IReferenceDescription>() { public void accept(IReferenceDescription referenceDescription) { referenceDescriptions.add(referenceDescription); } }; referenceFinder.findReferences(elementRenameArguments.getRenamedElementURIs(), singleton(renameElementContext.getContextResourceURI()), new SimpleLocalResourceAccess(resourceSet), referenceAcceptor, progress.newChild(60)); referenceUpdater.createReferenceUpdates(elementRenameArguments, referenceDescriptions, updateAcceptor, progress.newChild(10)); List<ReplaceEdit> textEdits = updateAcceptor.getTextEdits(); LinkedPositionGroup linkedGroup = createLinkedGroupFromReplaceEdits(textEdits, editor, renameStrategy.getOriginalName(), progress.newChild(10)); return linkedGroup; }
/** * Enters the linked mode for editing the namespace prefix we generated. */ private void enterLinkedModeForPrefix(IDocument document, ITextViewer viewer, IDOMElement rootElement, String prefix) throws BadLocationException { int linkedPosSequence = 0; // The prefix is the first thing entered at the start position LinkedPosition pos1 = new LinkedPosition(document, startPosition, prefix.length(), linkedPosSequence++); // The prefix is also at the cursor position + 2 (those two following // characters are '<' and '/') LinkedPosition pos2 = new LinkedPosition(document, cursorPosition + 2, prefix.length(), linkedPosSequence++); IDOMElement rootDomElement = (IDOMElement) rootElement; // TODO: use UiBinderConstants.XMLNS_PREFIX, but that has been modified in // a parallel CL. Will switch to using that constant in the latter of this // and that other CL. final String xmlnsPrefix = "xmlns:"; String fullPrefixName = xmlnsPrefix + prefix; IDOMAttr domAttribute = (IDOMAttr) rootDomElement.getAttributeNode(fullPrefixName); LinkedPosition pos3 = new LinkedPosition(document, domAttribute.getStartOffset() + xmlnsPrefix.length(), prefix.length(), linkedPosSequence++); LinkedPositionGroup group = new LinkedPositionGroup(); group.addPosition(pos1); group.addPosition(pos2); group.addPosition(pos3); // Boilerplate stuff below LinkedModeModel model = new LinkedModeModel(); model.addGroup(group); model.forceInstall(); LinkedModeUI ui = new LinkedModeUI(model, viewer); ui.enter(); wasLinkedModeEntered = true; }