/** * Complete constructor with minimal type information. * * <p>This is important when we're autocompleting new ? with a class that we haven't yet * imported. We don't yet have detailed type information or javadocs, and it's expensive to * retrieve them. So we autocomplete a minimal constructor, and let signature-help fill in the * details. */ private CompletionItem completeConstructor( String packageName, String className, boolean hasTypeParameters) { CompletionItem item = new CompletionItem(); String qualifiedName = packageName.isEmpty() ? className : packageName + "." + className; String key = String.format("%s#<init>", className); String insertText = className; if (hasTypeParameters) insertText += "<>"; insertText += "($0)"; item.setKind(CompletionItemKind.Constructor); item.setLabel(className); item.setDetail(packageName); item.setInsertText(insertText); item.setInsertTextFormat(InsertTextFormat.Snippet); item.setCommand(TRIGGER_SIGNATURE_HELP); item.setFilterText(className); item.setAdditionalTextEdits(addImport(qualifiedName)); item.setSortText("3/" + className); item.setData(key); return item; }
/** * The format of the insert text. The format applies to both the `insertText` property * and the `newText` property of a provided `textEdit`. */ @Pure public InsertTextFormat getInsertTextFormat() { return this.insertTextFormat; }
/** * Updates the replacement and any additional replacement for the given item. * * @param proposal * @param item * @param trigger */ public void updateReplacement(CompletionProposal proposal, CompletionItem item, char trigger) { // reset importRewrite this.importRewrite = TypeProposalUtils.createImportRewrite(compilationUnit); List<org.eclipse.lsp4j.TextEdit> additionalTextEdits = new ArrayList<>(); StringBuilder completionBuffer = new StringBuilder(); Range range = null; if (isSupportingRequiredProposals(proposal)) { CompletionProposal[] requiredProposals= proposal.getRequiredProposals(); if (requiredProposals != null) { for (CompletionProposal requiredProposal : requiredProposals) { switch(requiredProposal.getKind()) { case CompletionProposal.TYPE_IMPORT: case CompletionProposal.METHOD_IMPORT: case CompletionProposal.FIELD_IMPORT: appendImportProposal(completionBuffer, requiredProposal, proposal.getKind()); break; case CompletionProposal.TYPE_REF: org.eclipse.lsp4j.TextEdit edit = toRequiredTypeEdit(requiredProposal, trigger, proposal.canUseDiamond(context)); if (proposal.getKind() == CompletionProposal.CONSTRUCTOR_INVOCATION || proposal.getKind() == CompletionProposal.ANONYMOUS_CLASS_CONSTRUCTOR_INVOCATION || proposal.getKind() == CompletionProposal.ANONYMOUS_CLASS_DECLARATION) { completionBuffer.append(edit.getNewText()); range = edit.getRange(); } else { additionalTextEdits.add(edit); } break; default: /* * In 3.3 we only support the above required proposals, see * CompletionProposal#getRequiredProposals() */ Assert.isTrue(false); } } } } if (range == null) { range = toReplacementRange(proposal); } if(proposal.getKind() == CompletionProposal.METHOD_DECLARATION){ appendMethodOverrideReplacement(completionBuffer, proposal); } else if (proposal.getKind() == CompletionProposal.POTENTIAL_METHOD_DECLARATION && proposal instanceof GetterSetterCompletionProposal) { appendMethodPotentialReplacement(completionBuffer, (GetterSetterCompletionProposal) proposal); } else if (proposal.getKind() == CompletionProposal.ANONYMOUS_CLASS_CONSTRUCTOR_INVOCATION || proposal.getKind() == CompletionProposal.ANONYMOUS_CLASS_DECLARATION) { appendAnonymousClass(completionBuffer, proposal, range); } else { appendReplacementString(completionBuffer, proposal); } //select insertTextFormat. if( client.isCompletionSnippetsSupported()){ item.setInsertTextFormat(InsertTextFormat.Snippet); }else{ item.setInsertTextFormat(InsertTextFormat.PlainText); } String text = completionBuffer.toString(); if(range != null){ item.setTextEdit(new org.eclipse.lsp4j.TextEdit(range, text)); }else{ // fallback item.setInsertText(text); } addImports(additionalTextEdits); if(!additionalTextEdits.isEmpty()){ item.setAdditionalTextEdits(additionalTextEdits); } }
@Override public void apply(Document document) { List<TextEdit> edits = new ArrayList<>(); TextPosition cursorPosition = document.getCursorPosition(); if (completionItem.getTextEdit() != null) { edits.add(adjustForOffset(completionItem.getTextEdit(), cursorPosition, offset)); } else if (completionItem.getInsertText() == null) { edits.add( new TextEdit( newRange( cursorPosition.getLine(), cursorPosition.getCharacter() - currentWord.length(), cursorPosition.getLine(), cursorPosition.getCharacter()), completionItem.getLabel())); } else { edits.add( new TextEdit( newRange( cursorPosition.getLine(), cursorPosition.getCharacter() - offset, cursorPosition.getLine(), cursorPosition.getCharacter()), completionItem.getInsertText())); } if (completionItem.getAdditionalTextEdits() != null) { completionItem .getAdditionalTextEdits() .forEach(e -> edits.add(adjustForOffset(e, cursorPosition, offset))); } TextEdit firstEdit = edits.get(0); if (completionItem.getInsertTextFormat() == InsertTextFormat.Snippet) { Position startPos = firstEdit.getRange().getStart(); TextPosition startTextPosition = new TextPosition(startPos.getLine(), startPos.getCharacter()); int startOffset = document.getIndexFromPosition(startTextPosition); Pair<String, LinkedModel> resolved = new SnippetResolver(new DocumentVariableResolver(document, startTextPosition)) .resolve(firstEdit.getNewText(), editor, startOffset); firstEdit.setNewText(resolved.first); ApplyWorkspaceEditAction.applyTextEdits(document, edits); if (resolved.second != null) { editor.getLinkedMode().enterLinkedMode(resolved.second); lastSelection = null; } else { lastSelection = computeLastSelection(document, firstEdit); } } else { ApplyWorkspaceEditAction.applyTextEdits(document, edits); lastSelection = computeLastSelection(document, firstEdit); } }
/** * The format of the insert text. The format applies to both the `insertText` property * and the `newText` property of a provided `textEdit`. */ public void setInsertTextFormat(final InsertTextFormat insertTextFormat) { this.insertTextFormat = insertTextFormat; }