diff --git a/DoxyDoc.sublime-settings b/DoxyDoc.sublime-settings index ddec025..5f6dfd3 100644 --- a/DoxyDoc.sublime-settings +++ b/DoxyDoc.sublime-settings @@ -1,11 +1,11 @@ { - "enabled": true, + "doxydoc_enabled": true, // if set to true, the commands will be prefixed with @ // otherwise they will be prefixed with \ - "javadoc": false, + "doxydoc_javadoc": false, // the maximum amount of lines to parse to retrieve // all the parameters of a function or class - "max_lines": 5 + "doxydoc_max_lines": 5 } diff --git a/doxydoc.py b/doxydoc.py index bbc5281..cdc63d9 100644 --- a/doxydoc.py +++ b/doxydoc.py @@ -2,7 +2,7 @@ import re def get_settings(): - return sublime.load_settings("DoxyDoc.sublime-settings") + return sublime.load_settings('Doxydoc.sublime-settings') def get_setting(key, default=None): @@ -44,13 +44,13 @@ def get_function_args(fn_str): fn_str = re.sub(r"\w+::", "", fn_str) # Remove template arguments in types - fn_str = re.sub(r"([a-zA-Z_]\w*)\s*<.+?>", r"\1", fn_str) + fn_str = re.sub(r"([a-zA-Z_]\w*)\s*<.+>", r"\1", fn_str) # Remove parentheses - fn_str = re.sub(r"\((.*?)\)", r"\1", fn_str) + fn_str = re.sub(r"\((.*)\)", r"\1", fn_str) # Remove arrays - fn_str = re.sub(r"\[.*?\]", "", fn_str) + fn_str = re.sub(r"\[.*\]", "", fn_str) print('After: {0}'.format(fn_str)) arg_regex = r"(?P[a-zA-Z_]\w*)\s*(?P[a-zA-Z_]\w*)" @@ -75,10 +75,20 @@ class DoxydocCommand(sublime_plugin.TextCommand): def set_up(self): identifier = r"([a-zA-Z_]\w*)" function_identifiers = r"\s*(?:(?:inline|static|constexpr|friend|virtual|explicit|\[\[.+\]\])\s+)*" - self.command_type = '@' if setting("javadoc", True) else '\\' + typedef_identifier = r"\s*(typedef)?\s*" + cse_identifier = r"([a-zA-Z_]\w*)?" + if get_setting("doxydoc_javadoc"): + self.command_type = '@' + else: + self.command_type = '\\' self.regexp = { "templates": r"\s*template\s*<(.+)>\s*", - "class": r"\s*(?:class|struct)\s*" + identifier + r"\s*{?", + "class": typedef_identifier + r"\s*class\s*" + cse_identifier + r"\s*{?", + "struct": typedef_identifier + r"\s*struct\s*" + cse_identifier + r"\s*{?", + "enum": typedef_identifier + r"\s*enum\s*" + cse_identifier + r"\s*{?", + "define": r"\s*#\s*define\s*", + "include": r"\s*#\s*include\s*", + "function": function_identifiers + r"(?P(?:typename\s*)?[\w:<>]+)?\s*" r"(?P[A-Za-z_]\w*::)?" r"(?Poperator\s*.{1,2}|[A-Za-z_:]\w*)\s*" @@ -86,14 +96,14 @@ def set_up(self): "constructor": function_identifiers + r"(?P)" # dummy so it doesn't error out r"~?(?P[a-zA-Z_]\w*)(?:\:\:[a-zA-Z_]\w*)?" - r"\((?P[:<>\[\]\(\),.*&\w\s=]*)\).+" + r"\((?P[:<>\[\]\(\),.*&\w\s=]*)\).+", } def write(self, view, string): view.run_command("insert_snippet", {"contents": string }) def run(self, edit, mode = None): - if setting("enabled", True): + if setting("doxydoc_enabled", True): self.set_up() snippet = self.retrieve_snippet(self.view) if snippet: @@ -103,12 +113,11 @@ def run(self, edit, mode = None): def retrieve_snippet(self, view): point = view.sel()[0].begin() - max_lines = setting("max_lines", 5) + max_lines = setting("doxydoc_max_lines", 5) current_line = read_line(view, point) if not current_line or current_line.find("/**") == -1: # Strange bug.. return "\n * ${0}\n */" - point += len(current_line) + 1 next_line = read_line(view, point) @@ -169,6 +178,32 @@ def retrieve_snippet(self, view): function_lines += line function_point += len(line) + 1 + # Check if it's the start of the file by checking + # if we detect an include + regex_start = re.search(self.regexp["include"], next_line) + if regex_start: + return self.start_snippet() + + # Check if it's a define + regex_define = re.search(self.regexp["define"], next_line) + if regex_define: + return self.define_snippet() + + # Check if it's a regular class + regex_class = re.search(self.regexp["class"], next_line) + if regex_class: + return self.class_snippet() + + # Check if it's a regular struct + regex_struct = re.search(self.regexp["struct"], next_line) + if regex_struct: + return self.struct_snippet() + + # Check if it's a regular struct + regex_enum = re.search(self.regexp["enum"], next_line) + if regex_enum: + return self.enum_snippet() + # Check if it's a regular constructor or destructor regex_constructor = re.match(self.regexp["constructor"], function_lines) if regex_constructor: @@ -179,12 +214,6 @@ def retrieve_snippet(self, view): if regex_function: return self.function_snippet(regex_function) - # Check if it's a regular class - regex_class = re.search(self.regexp["class"], next_line) - if regex_class: - # Regular class - return self.regular_snippet() - # if all else fails, just send a closing snippet return "\n * ${0}\n */" @@ -194,6 +223,39 @@ def regular_snippet(self): "\n * {0}details ${{2:[long description]}}\n * \n */".format(self.command_type)) return snippet + def class_snippet(self): + snippet = ("\n * {0}class ${{1:[class name]}}" + "\n * {0}brief ${{2:[brief description]}}" + "\n * {0}details ${{3:[long description]}}\n */".format(self.command_type)) + return snippet + + def struct_snippet(self): + snippet = ("\n * {0}struct ${{1:[struct name]}}" + "\n * {0}brief ${{2:[brief description]}}" + "\n * {0}details ${{3:[long description]}}\n */".format(self.command_type)) + return snippet + + def enum_snippet(self): + snippet = ("\n * {0}enum ${{1:[enum name]}}" + "\n * {0}brief ${{2:[brief description]}}" + "\n * {0}details ${{3:[long description]}}\n */".format(self.command_type)) + return snippet + + def start_snippet(self): + snippet = ("\n * {0}file ${{1:[file name]}}" + "\n * {0}brief ${{2:[brief description]}}" + "\n * {0}details ${{3:[long description]}}\n *" + "\n * {0}author ${{4:[authors name]}}" + "\n * {0}date ${{5:[file date]}}" + "\n * {0}copyright ${{6:[copyright description]}}\n */".format(self.command_type)) + return snippet + + def define_snippet(self): + snippet = ("\n * {0}def ${{1:[macro name]}}" + "\n * {0}brief ${{2:[brief description]}}" + "\n * {0}details ${{3:[long description]}}\n * \n */".format(self.command_type)) + return snippet + def template_snippet(self, template_args): snippet = ("\n * {0}brief ${{1:[brief description]}}" "\n * {0}details ${{2:[long description]}}\n * ".format(self.command_type)) @@ -264,10 +326,11 @@ def function_snippet(self, regex_obj): class DoxygenCompletions(sublime_plugin.EventListener): def __init__(self): - self.command_type = '@' if setting('javadoc', True) else '\\' + self.command_type = '@' if setting('doxydoc_javadoc', True) else '\\' def default_completion_list(self): return [('author', 'author ${1:[author]}'), + ('date', 'exception ${1:[date]}'), ('deprecated', 'deprecated ${1:[deprecated-text]}'), ('exception', 'exception ${1:[exception-object]} ${2:[description]}'), ('param', 'param ${1:[parameter-name]} ${2:[description]}'),