@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 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);
 }