########## # COMMON # ########## # The smart def and smart class snippets use a global option called # "g:ultisnips_python_style" which, if set to "doxygen" will use doxygen # style comments in docstrings. global !p NORMAL = 0x1 DOXYGEN = 0x2 SPHINX = 0x3 GOOGLE = 0x4 NUMPY = 0x5 JEDI = 0x6 SINGLE_QUOTES = "'" DOUBLE_QUOTES = '"' class Arg(object): def __init__(self, arg): self.arg = arg name_and_type = arg.split('=')[0].split(':') self.name = name_and_type[0].strip() self.type = name_and_type[1].strip() if len(name_and_type) == 2 else None def __str__(self): return self.name def __unicode__(self): return self.name def is_kwarg(self): return '=' in self.arg def is_vararg(self): return '*' in self.name def get_args(arglist): args = [Arg(arg) for arg in arglist.split(',') if arg] args = [arg for arg in args if arg.name != 'self'] return args def get_quoting_style(snip): style = snip.opt("g:ultisnips_python_quoting_style", "double") if style == 'single': return SINGLE_QUOTES return DOUBLE_QUOTES def triple_quotes(snip): style = snip.opt("g:ultisnips_python_triple_quoting_style") if not style: return get_quoting_style(snip) * 3 return (SINGLE_QUOTES if style == 'single' else DOUBLE_QUOTES) * 3 def triple_quotes_handle_trailing(snip, quoting_style): """ Generate triple quoted strings and handle any trailing quote char, which might be there from some autoclose/autopair plugin, i.e. when expanding ``"|"``. """ if not snip.c: # Do this only once, otherwise the following error would happen: # RuntimeError: The snippets content did not converge: … _, col = vim.current.window.cursor line = vim.current.line # Handle already existing quote chars after the trigger. _ret = quoting_style * 3 while True: try: nextc = line[col] except IndexError: break if nextc == quoting_style and len(_ret): _ret = _ret[1:] col = col+1 else: break snip.rv = _ret else: snip.rv = snip.c def get_style(snip): style = snip.opt("g:ultisnips_python_style", "normal") if style == "doxygen": return DOXYGEN elif style == "sphinx": return SPHINX elif style == "google": return GOOGLE elif style == "numpy": return NUMPY elif style == "jedi": return JEDI else: return NORMAL def format_arg(arg, style): if style == DOXYGEN: return "@param %s TODO" % arg elif style == SPHINX: return ":param %s: TODO" % arg elif style == NORMAL: return ":%s: TODO" % arg elif style == GOOGLE: return "%s (TODO): TODO" % arg elif style == JEDI: return ":type %s: TODO" % arg elif style == NUMPY: return "%s : TODO" % arg def format_return(style): if style == DOXYGEN: return "@return: TODO" elif style in (NORMAL, SPHINX, JEDI): return ":returns: TODO" elif style == GOOGLE: return "Returns: TODO" def write_docstring_args(args, snip): if not args: snip.rv += ' {0}'.format(triple_quotes(snip)) return snip.rv += '\n' + snip.mkline('', indent='') style = get_style(snip) if style == GOOGLE: write_google_docstring_args(args, snip) elif style == NUMPY: write_numpy_docstring_args(args, snip) else: for arg in args: snip += format_arg(arg, style) def write_google_docstring_args(args, snip): kwargs = [arg for arg in args if arg.is_kwarg()] args = [arg for arg in args if not arg.is_kwarg()] if args: snip += "Args:" snip.shift() for arg in args: snip += format_arg(arg, GOOGLE) snip.unshift() snip.rv += '\n' + snip.mkline('', indent='') if kwargs: snip += "Kwargs:" snip.shift() for kwarg in kwargs: snip += format_arg(kwarg, GOOGLE) snip.unshift() snip.rv += '\n' + snip.mkline('', indent='') def write_numpy_docstring_args(args, snip): if args: snip += "Parameters" snip += "----------" kwargs = [arg for arg in args if arg.is_kwarg()] args = [arg for arg in args if not arg.is_kwarg()] if args: for arg in args: snip += format_arg(arg, NUMPY) if kwargs: for kwarg in kwargs: snip += format_arg(kwarg, NUMPY) + ', optional' snip.rv += '\n' + snip.mkline('', indent='') def write_init_body(args, parents, snip): parents = [p.strip() for p in parents.split(",")] parents = [p for p in parents if p != 'object'] for p in parents: snip += p + ".__init__(self)" if parents: snip.rv += '\n' + snip.mkline('', indent='') for arg in filter(lambda arg: not arg.is_vararg(), args): snip += "self._%s = %s" % (arg, arg) def write_slots_args(args, snip): quote = get_quoting_style(snip) arg_format = quote + '_%s' + quote args = [arg_format % arg for arg in args] snip += '__slots__ = (%s,)' % ', '.join(args) def write_function_docstring(t, snip): """ Writes a function docstring with the current style. :param t: The values of the placeholders :param snip: UltiSnips.TextObjects.SnippetUtil object instance """ snip.rv = "" snip >> 1 args = get_args(t[2]) if args: write_docstring_args(args, snip) style = get_style(snip) if style == NUMPY: snip += 'Returns' snip += '-------' snip += 'TODO' else: snip += format_return(style) snip.rv += '\n' + snip.mkline('', indent='') snip += triple_quotes(snip) def get_dir_and_file_name(snip): return os.getcwd().split(os.sep)[-1] + '.' + snip.basename endglobal snippet ! "entry function with docstrings and if __name__" b def ${1:main}(`!p if snip.indent: snip.rv = 'self' + (", " if len(t[2]) else "")`${2:arg1}): `!p snip.rv = triple_quotes(snip)`${4:Main entry function.}`!p write_function_docstring(t, snip) ` ${5:${VISUAL:pass}} if __name__ == `!p snip.rv = get_quoting_style(snip)`__main__`!p snip.rv = get_quoting_style(snip)`: $1() endsnippet snippet ifarg " with docstrings" b if len(sys.argv) > $1 and sys.argv[$1] == "${2:something}": $0 endsnippet