void (@NotNull String abbreviation, @NotNull CustomTemplateCallback callback, @NotNull Caret startCaret, @NotNull ZenCodingGenerator defaultGenerator) { CollectCustomTemplateCallback collect = new CollectCustomTemplateCallback(callback.getEditor(), callback.getFile()); Editor editor = callback.getEditor(); ReadAction.nonBlocking(() -> { var result = Ref.create(Boolean.FALSE); runForCaret(startCaret, editor, () -> { String selectedText = editor.getSelectionModel().getSelectedText(); if (selectedText == null) return; ZenCodingNode node = parse(abbreviation, callback, defaultGenerator, selectedText); assert node != null; PsiElement context = callback.getContext(); ZenCodingGenerator generator = findApplicableGenerator(node, callback, true); List<ZenCodingFilter> filters = getFilters(node, context); try { expand(node, generator, filters, selectedText, collect, true, Registry.intValue("emmet.segments.limit")); result.set(true); } catch (EmmetException e) { CommonRefactoringUtil.showErrorHint(callback.getProject(), editor, e.getMessage(), XmlBundle.message("emmet.error"), ""); } }); return result.get() ? collect : null; }).finishOnUiThread(ModalityState.current(), result -> { if (result == null) return; TemplateImpl template = result.getGeneratedTemplate(); if (template == null) return; writeActionForCaret(startCaret, editor, callback.getFile(), () -> { EditorModificationUtilEx.deleteSelectedText(editor); PsiDocumentManager.getInstance(callback.getProject()).commitDocument(editor.getDocument()); callback.startTemplate(template, null, null); }); }) .submit(EMMET_EXECUTOR); }