public void startTemplateWithPrefix( final Editor editor, final TemplateImpl template, final int templateStart, @Nullable final PairProcessor<String, String> processor, @Nullable final String argument) { final int caretOffset = editor.getCaretModel().getOffset(); final TemplateState templateState = initTemplateState(editor); CommandProcessor commandProcessor = CommandProcessor.getInstance(); commandProcessor.executeCommand( myProject, () -> { editor.getDocument().deleteString(templateStart, caretOffset); editor.getCaretModel().moveToOffset(templateStart); editor.getScrollingModel().scrollToCaret(ScrollType.RELATIVE); editor.getSelectionModel().removeSelection(); Map<String, String> predefinedVarValues = null; if (argument != null) { predefinedVarValues = new HashMap<String, String>(); predefinedVarValues.put(TemplateImpl.ARG, argument); } templateState.start(template, processor, predefinedVarValues); }, CodeInsightBundle.message("insert.code.template.command"), null); }
@Nullable public Runnable startNonCustomTemplates( final Map<TemplateImpl, String> template2argument, final Editor editor, @Nullable final PairProcessor<String, String> processor) { final int caretOffset = editor.getCaretModel().getOffset(); final Document document = editor.getDocument(); final CharSequence text = document.getCharsSequence(); if (template2argument == null || template2argument.isEmpty()) { return null; } if (!FileDocumentManager.getInstance().requestWriting(editor.getDocument(), myProject)) { return null; } return () -> { if (template2argument.size() == 1) { TemplateImpl template = template2argument.keySet().iterator().next(); String argument = template2argument.get(template); int templateStart = getTemplateStart(template, argument, caretOffset, text); startTemplateWithPrefix(editor, template, templateStart, processor, argument); } else { ListTemplatesHandler.showTemplatesLookup(myProject, editor, template2argument); } }; }
public static PsiFile insertDummyIdentifier(final Editor editor, PsiFile file) { boolean selection = editor.getSelectionModel().hasSelection(); final int startOffset = selection ? editor.getSelectionModel().getSelectionStart() : editor.getCaretModel().getOffset(); final int endOffset = selection ? editor.getSelectionModel().getSelectionEnd() : startOffset; return insertDummyIdentifierIfNeeded( file, startOffset, endOffset, CompletionUtil.DUMMY_IDENTIFIER_TRIMMED); }
public static List<TemplateImpl> listApplicableTemplateWithInsertingDummyIdentifier( Editor editor, PsiFile file, boolean selectionOnly) { int startOffset = editor.getSelectionModel().getSelectionStart(); file = insertDummyIdentifier(editor, file); return listApplicableTemplates(file, startOffset, selectionOnly); }
private TemplateState initTemplateState(@NotNull Editor editor) { clearTemplateState(editor); TemplateState state = new TemplateState(myProject, editor); Disposer.register(this, state); editor.putUserData(TEMPLATE_STATE_KEY, state); return state; }
static void clearTemplateState(@NotNull Editor editor) { TemplateState prevState = getTemplateState(editor); if (prevState != null) { disposeState(prevState); } editor.putUserData(TEMPLATE_STATE_KEY, null); }
@Nullable public Runnable prepareTemplate( final Editor editor, char shortcutChar, @Nullable final PairProcessor<String, String> processor) { if (editor.getSelectionModel().hasSelection()) { return null; } PsiFile file = PsiUtilBase.getPsiFileInEditor(editor, myProject); if (file == null) return null; Map<TemplateImpl, String> template2argument = findMatchingTemplates(file, editor, shortcutChar, TemplateSettings.getInstance()); List<CustomLiveTemplate> customCandidates = ContainerUtil.findAll( CustomLiveTemplate.EP_NAME.getExtensions(), customLiveTemplate -> shortcutChar == customLiveTemplate.getShortcut() && (editor.getCaretModel().getCaretCount() <= 1 || supportsMultiCaretMode(customLiveTemplate))); if (!customCandidates.isEmpty()) { int caretOffset = editor.getCaretModel().getOffset(); PsiFile fileCopy = insertDummyIdentifierIfNeeded(file, caretOffset, caretOffset, ""); Document document = editor.getDocument(); for (final CustomLiveTemplate customLiveTemplate : customCandidates) { if (isApplicable(customLiveTemplate, editor, fileCopy)) { final String key = customLiveTemplate.computeTemplateKey(new CustomTemplateCallback(editor, fileCopy)); if (key != null) { int offsetBeforeKey = caretOffset - key.length(); CharSequence text = document.getImmutableCharSequence(); if (template2argument == null || !containsTemplateStartingBefore( template2argument, offsetBeforeKey, caretOffset, text)) { return () -> customLiveTemplate.expand(key, new CustomTemplateCallback(editor, file)); } } } } } return startNonCustomTemplates(template2argument, editor, processor); }
@Override public boolean startTemplate(@NotNull Editor editor, char shortcutChar) { Runnable runnable = prepareTemplate(editor, shortcutChar, null); if (runnable != null) { PsiDocumentManager.getInstance(myProject).commitDocument(editor.getDocument()); runnable.run(); } return runnable != null; }
public Map<TemplateImpl, String> findMatchingTemplates( final PsiFile file, Editor editor, @Nullable Character shortcutChar, TemplateSettings templateSettings) { final Document document = editor.getDocument(); CharSequence text = document.getCharsSequence(); final int caretOffset = editor.getCaretModel().getOffset(); List<TemplateImpl> candidatesWithoutArgument = findMatchingTemplates(text, caretOffset, shortcutChar, templateSettings, false); int argumentOffset = passArgumentBack(text, caretOffset); String argument = null; if (argumentOffset >= 0) { argument = text.subSequence(argumentOffset, caretOffset).toString(); if (argumentOffset > 0 && text.charAt(argumentOffset - 1) == ' ') { if (argumentOffset - 2 >= 0 && Character.isJavaIdentifierPart(text.charAt(argumentOffset - 2))) { argumentOffset--; } } } List<TemplateImpl> candidatesWithArgument = findMatchingTemplates(text, argumentOffset, shortcutChar, templateSettings, true); if (candidatesWithArgument.isEmpty() && candidatesWithoutArgument.isEmpty()) { return null; } candidatesWithoutArgument = filterApplicableCandidates(file, caretOffset, candidatesWithoutArgument); candidatesWithArgument = filterApplicableCandidates(file, argumentOffset, candidatesWithArgument); Map<TemplateImpl, String> candidate2Argument = new HashMap<TemplateImpl, String>(); addToMap(candidate2Argument, candidatesWithoutArgument, null); addToMap(candidate2Argument, candidatesWithArgument, argument); return candidate2Argument; }
public void startTemplateWithPrefix( final Editor editor, final TemplateImpl template, @Nullable final PairProcessor<String, String> processor, @Nullable String argument) { final int caretOffset = editor.getCaretModel().getOffset(); String key = template.getKey(); int startOffset = caretOffset - key.length(); if (argument != null) { if (!isDelimiter(key.charAt(key.length() - 1))) { // pass space startOffset--; } startOffset -= argument.length(); } startTemplateWithPrefix(editor, template, startOffset, processor, argument); }
private void startTemplate( final Editor editor, final String selectionString, final Template template, boolean inSeparateCommand, TemplateEditingListener listener, final PairProcessor<String, String> processor, final Map<String, String> predefinedVarValues) { final TemplateState templateState = initTemplateState(editor); //noinspection unchecked templateState.getProperties().put(ExpressionContext.SELECTION, selectionString); if (listener != null) { templateState.addTemplateStateListener(listener); } Runnable r = () -> { if (selectionString != null) { ApplicationManager.getApplication() .runWriteAction(() -> EditorModificationUtil.deleteSelectedText(editor)); } else { editor.getSelectionModel().removeSelection(); } templateState.start((TemplateImpl) template, processor, predefinedVarValues); }; if (inSeparateCommand) { CommandProcessor.getInstance() .executeCommand( myProject, r, CodeInsightBundle.message("insert.code.template.command"), null); } else { r.run(); } if (shouldSkipInTests()) { if (!templateState.isFinished()) templateState.gotoEnd(false); } }
@Nullable public static TemplateState getTemplateState(@NotNull Editor editor) { return editor.getUserData(TEMPLATE_STATE_KEY); }