private static List<CompletionItem> getNTagCompletion(
      int startOffset, int caretOffset, String filter) {
    List<CompletionItem> list = new ArrayList<CompletionItem>();

    if (!filter.startsWith("<n:")) {
      return list;
    }

    for (LatteMacro macro : MacroDefinitions.macros) {
      boolean hasParam = MacroDefinitions.tagMacros.containsKey(macro.getMacroName());
      if ((macro.getClass() == LatteMacro.class || hasParam)
          && Character.isLetter(macro.getMacroName().charAt(0))) {
        String name = macro.getMacroName();
        if (("<n:" + name).startsWith(filter)) {
          if (!hasParam) {
            list.add(
                new MacroCompletionItem(
                    "<n:" + name, startOffset, caretOffset, true, name.length() + 3));
          } else {
            String tag = "<n:" + name;
            for (String s : MacroDefinitions.tagMacros.get(macro.getMacroName())) {
              tag += " " + s + "=\"\"";
            }
            list.add(
                new MacroCompletionItem(tag, startOffset, caretOffset, true, tag.length() - 1));
          }
        }
      }
    }
    return list;
  }