/**
   * Computes the relevance to match the relevance values generated by the core content assistant.
   *
   * @return a sensible relevance value.
   */
  private int computeRelevance() {
    // see org.eclipse.jdt.internal.codeassist.RelevanceConstants
    final int R_DEFAULT = 0;
    final int R_INTERESTING = 5;
    final int R_CASE = 10;
    final int R_NON_RESTRICTED = 3;
    final int R_EXACT_NAME = 4;
    final int R_INLINE_TAG = 31;

    int base = R_DEFAULT + R_INTERESTING + R_NON_RESTRICTED;

    try {
      if (fContext instanceof DocumentTemplateContext) {
        DocumentTemplateContext templateContext = (DocumentTemplateContext) fContext;
        IDocument document = templateContext.getDocument();

        String content = document.get(fRegion.getOffset(), fRegion.getLength());
        if (content.length() > 0 && fTemplate.getName().startsWith(content)) base += R_CASE;
        if (fTemplate.getName().equalsIgnoreCase(content)) base += R_EXACT_NAME;
        if (fContext instanceof JavaDocContext) base += R_INLINE_TAG;
      }
    } catch (BadLocationException e) {
      // ignore - not a case sensitive match then
    }

    // see CompletionProposalCollector.computeRelevance
    // just under keywords, but better than packages
    final int TEMPLATE_RELEVANCE = 1;
    return base * 16 + TEMPLATE_RELEVANCE;
  }
 /*
  * @see org.eclipse.jface.text.contentassist.ICompletionProposalExtension6#getStyledDisplayString()
  * @since 3.4
  */
 @Override
 public StyledString getStyledDisplayString() {
   if (fDisplayString == null) {
     String[] arguments = new String[] {fTemplate.getName(), fTemplate.getDescription()};
     String decorated =
         Messages.format(TemplateContentAssistMessages.TemplateProposal_displayString, arguments);
     StyledString string = new StyledString(fTemplate.getName(), StyledString.COUNTER_STYLER);
     fDisplayString =
         StyledCellLabelProvider.styleDecoratedString(
             decorated, StyledString.QUALIFIER_STYLER, string);
   }
   return fDisplayString;
 }
  /*
   * @see TemplateContext#canEvaluate(Template templates)
   */
  @Override
  public boolean canEvaluate(Template template) {
    if (!hasCompatibleContextType(template)) return false;

    if (fForceEvaluation) return true;

    String key = getKey();
    return (key.length() > 0 || !isAfterDot())
        && template.getName().toLowerCase().startsWith(key.toLowerCase());
  }
 private int getRelevance(Template template, int lineOffset, String prefix) {
   boolean blockTemplate = templates == null ? false : templates.isBlock(template);
   if (blockTemplate) {
     if (template.getName().startsWith(prefix)) {
       return lineOffset == 0 ? 95 : 75;
     }
     return lineOffset == 0 ? 85 : 0;
   }
   return super.getRelevance(template, prefix);
 }
 public CodeClipDialog(
     Shell parentShell, Shell contextShell, TemplatePersistenceData templatePersistenceData) {
   super(parentShell);
   this.contextShell = contextShell;
   this.templatePersistenceData = templatePersistenceData;
   Template template = templatePersistenceData.getTemplate();
   abbrev = template.getName();
   description = template.getDescription();
   expansion = template.getPattern();
   contentType = template.getContextTypeId();
   setHelpAvailable(false);
 }
 private Template indentTemplatePattern(final Template template, final boolean indentFrom0) {
   String pattern = template.getPattern();
   final String whiteSpacePrefix = indentFrom0 ? "" : getWhiteSpacePrefix();
   try {
     pattern = IndentAction.indentLines(0, 0, pattern, true, whiteSpacePrefix);
   } catch (final RpcException e) {
     ErlLogger.error(e);
   }
   return new Template(
       template.getName(),
       template.getDescription(),
       template.getContextTypeId(),
       pattern,
       template.isAutoInsertable());
 }
 /*
  * @see org.eclipse.jface.text.contentassist.ICompletionProposalExtension2#validate(org.eclipse.jface.text.IDocument, int, org.eclipse.jface.text.DocumentEvent)
  */
 @Override
 public boolean validate(IDocument document, int offset, DocumentEvent event) {
   try {
     int replaceOffset = getReplaceOffset();
     if (offset >= replaceOffset) {
       String content = document.get(replaceOffset, offset - replaceOffset);
       String templateName = fTemplate.getName().toLowerCase();
       boolean valid = templateName.startsWith(content.toLowerCase());
       if (!valid
           && fContext instanceof JavaDocContext
           && templateName.startsWith("<")) { // $NON-NLS-1$
         valid = templateName.startsWith(content.toLowerCase(), 1);
       }
       return valid;
     }
   } catch (BadLocationException e) {
     // concurrent modification - ignore
   }
   return false;
 }
 @NotNull
 private ICompletionProposal[] makeTemplateProposals(
     ITextViewer viewer, int documentOffset, String wordPart) {
   wordPart = wordPart.toLowerCase();
   final List<SQLTemplateCompletionProposal> templateProposals = new ArrayList<>();
   // Templates
   for (Template template : editor.getTemplatesPage().getTemplateStore().getTemplates()) {
     if (template.getName().toLowerCase().startsWith(wordPart)) {
       templateProposals.add(
           new SQLTemplateCompletionProposal(
               template,
               new SQLContext(
                   SQLTemplatesRegistry.getInstance()
                       .getTemplateContextRegistry()
                       .getContextType(template.getContextTypeId()),
                   viewer.getDocument(),
                   new Position(wordDetector.getStartOffset(), wordDetector.getLength()),
                   editor),
               new Region(documentOffset, 0),
               null));
     }
   }
   return templateProposals.toArray(new ICompletionProposal[templateProposals.size()]);
 }
  /**
   * Saves the templates as XML.
   *
   * @param templates the templates to save
   * @param result the stream result to write to
   * @throws IOException if writing the templates fails
   */
  private void save(TemplatePersistenceData[] templates, StreamResult result) throws IOException {
    try {
      DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
      DocumentBuilder builder = factory.newDocumentBuilder();
      Document document = builder.newDocument();

      Node root = document.createElement(TEMPLATE_ROOT);
      document.appendChild(root);

      for (int i = 0; i < templates.length; i++) {
        TemplatePersistenceData data = templates[i];
        Template template = data.getTemplate();

        Node node = document.createElement(TEMPLATE_ELEMENT);
        root.appendChild(node);

        NamedNodeMap attributes = node.getAttributes();

        String id = data.getId();
        if (id != null) {
          Attr idAttr = document.createAttribute(ID_ATTRIBUTE);
          idAttr.setValue(id);
          attributes.setNamedItem(idAttr);
        }

        if (template != null) {
          Attr name = document.createAttribute(NAME_ATTRIBUTE);
          name.setValue(template.getName());
          attributes.setNamedItem(name);
        }

        if (template != null) {
          Attr proposalDesc = document.createAttribute(PROPOSAL_POPUP_DESCRIPTION);
          if (template instanceof SQLTemplate) {
            proposalDesc.setValue(((SQLTemplate) template).getProposalPopupDescription());
          }
          attributes.setNamedItem(proposalDesc);
        }

        if (template != null) {
          Attr description = document.createAttribute(DESCRIPTION_ATTRIBUTE);
          description.setValue(template.getDescription());
          attributes.setNamedItem(description);
        }

        if (template != null) {
          Attr context = document.createAttribute(CONTEXT_ATTRIBUTE);
          context.setValue(template.getContextTypeId());
          attributes.setNamedItem(context);
        }

        Attr enabled = document.createAttribute(ENABLED_ATTRIBUTE);
        enabled.setValue(data.isEnabled() ? Boolean.toString(true) : Boolean.toString(false));
        attributes.setNamedItem(enabled);

        Attr deleted = document.createAttribute(DELETED_ATTRIBUTE);
        deleted.setValue(data.isDeleted() ? Boolean.toString(true) : Boolean.toString(false));
        attributes.setNamedItem(deleted);

        if (template != null) {
          Attr autoInsertable = document.createAttribute(AUTO_INSERTABLE_ATTRIBUTE);
          autoInsertable.setValue(
              template.isAutoInsertable() ? Boolean.toString(true) : Boolean.toString(false));
          attributes.setNamedItem(autoInsertable);
        }

        if (template != null) {
          Text pattern = document.createTextNode(template.getPattern());
          node.appendChild(pattern);
        }
      }

      Transformer transformer = TransformerFactory.newInstance().newTransformer();
      transformer.setOutputProperty(OutputKeys.METHOD, "xml"); // $NON-NLS-1$
      transformer.setOutputProperty(OutputKeys.ENCODING, "UTF-8"); // $NON-NLS-1$
      DOMSource source = new DOMSource(document);

      transformer.transform(source, result);

    } catch (ParserConfigurationException e) {
      Assert.isTrue(false);
    } catch (TransformerException e) {
      if (e.getException() instanceof IOException) throw (IOException) e.getException();
      Assert.isTrue(false);
    }
  }
  /** Override to improve matching accuracy */
  @Override
  public ICompletionProposal[] computeCompletionProposals(ITextViewer viewer, int offset) {

    ITextSelection selection = (ITextSelection) viewer.getSelectionProvider().getSelection();

    // adjust offset to end of normalized selection
    if (selection.getOffset() == offset) {
      offset = selection.getOffset() + selection.getLength();
    }

    String prefix = extractPrefix(viewer, offset);
    Region region = new Region(offset - prefix.length(), prefix.length());
    TemplateContext context = createContext(viewer, region);
    if (context == null) {
      return new ICompletionProposal[0];
    }
    Region selectionRegion = new Region(selection.getOffset(), selection.getLength());
    TemplateContext selectionContext = createContext(viewer, selectionRegion);

    int lineOffset = 0;
    try {
      IRegion lineInformationOfOffset = viewer.getDocument().getLineInformationOfOffset(offset);
      lineOffset = offset - lineInformationOfOffset.getOffset();
    } catch (BadLocationException e1) {
      // ignore
    }

    String selectionText = selection.getText();
    context.setVariable("selection", selectionText); // $NON-NLS-1$
    selectionContext.setVariable("selection", selectionText); // $NON-NLS-1$
    context.setVariable("text", selectionText); // $NON-NLS-1$
    selectionContext.setVariable("text", selectionText); // $NON-NLS-1$

    Template[] templates = getTemplates(context.getContextType().getId());

    List<ICompletionProposal> matches = new ArrayList<>(templates.length);
    for (Template template : templates) {
      try {
        context.getContextType().validate(template.getPattern());
      } catch (TemplateException e) {
        continue;
      }
      if (!template.matches(prefix, context.getContextType().getId())) {
        continue;
      }
      boolean selectionBasedMatch = isSelectionBasedMatch(template, context);
      if (template.getName().startsWith(prefix) || selectionBasedMatch) {

        int relevance = getRelevance(template, lineOffset, prefix);
        if (selectionBasedMatch) {
          matches.add(
              createProposal(template, selectionContext, (IRegion) selectionRegion, relevance));
        } else {
          matches.add(createProposal(template, context, (IRegion) region, relevance));
        }
      }
    }

    Collections.sort(matches, proposalComparator);

    return matches.toArray(new ICompletionProposal[matches.size()]);
  }
 /*
  * @see org.eclipse.jface.text.contentassist.ICompletionProposalExtension3#getReplacementString()
  */
 @Override
 public CharSequence getPrefixCompletionText(IDocument document, int completionOffset) {
   // bug 114360 - don't make selection templates prefix-completable
   if (isSelectionTemplate()) return ""; // $NON-NLS-1$
   return fTemplate.getName();
 }
 @Override
 public boolean canEvaluate(final Template template) {
   final String key = getKey();
   return key.length() != 0 && template.getName().toLowerCase().startsWith(key.toLowerCase());
 }