如何使用 vim 来促进 sqlalchemy 模型中的 class 定义?

How to use vim to facilitate class definitions in sqlalchemy models?

我正在为 SQLAlchemy 定义数据库-classes,如下所示:

class People(Base):
    __tablename__ = 'people'
    id = Column(Integer, primary_key=True, unique=True)
    name = Column(Text)
    haircolor = Column(Text)
    height = Column(Numeric)

    def __init__(self, id, name, haircolor, height):
        self.id = id
        self.name = name
        self.haircolor = haircolor
        self.height = height

对于许多表来说,手动写出来是一项繁琐的重复工作。由于 class 定义的结构始终相同,因此必须有一种方法可以配置 vim 为您编写定义的一部分,例如添加列时,初始化函数会同时自动定义。

vim 提供了哪些工具来促进稍微复杂的代码结构的自动化?

snippets 就像类固醇的内置 :abbreviate 一样,通常在其中包含参数插入、镜像和多个停止。 snipMate (inspired by the TextMate editor); unfortunately, it's not maintained any more; though there is a fork. A modern alternative (that requires Python though) is UltiSnips. There are more, see this list on the Vim Tips Wiki.

是第一个非常有名(并且仍然被广泛使用)的 Vim 插件

评价三点:一是snippet引擎本身的特点,二是作者或他人提供的snippet的质量和广度;第三,添加新片段是多么容易。

作者note/solution:

这可以通过 UltiSnips together with python.snippets 来完成。除了上面的答案之外,这里是我如何扩展 python.snippets 以使用问题中的代码示例。

如上例所示,要创建特定于 SQLAlchemy 的 class,请将以下代码添加到 python.snippets 文件(通常位于 .vim/UltiSnips/python.snippets):

########################################
# Custom snippets                      #
########################################

global !p

def write_init_body_sa(args, parents, snip):
    parents = [p.strip() for p in parents.split(",")]
    parents = [p for p in parents if p != 'object']

    for arg in args:
        snip += "self.%s = %s" % (arg, arg)

def write_sqlalchemy_columns(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 += "__tablename__ = '%s'" % (p.lower())

   for arg in args:
       snip += "%s = Column()" % (arg)


endglobal

snippet saclass "SQLAlchemy class" b
class ${1:MyClass}(${2:Base}):`!p
snip >> 1
snip.rv = ""
args = get_args(t[3])
write_sqlalchemy_columns(args, t[1], snip)
`

    def __init__(self):`!p
snip.rv = ""
snip >> 2

args = get_args(t[3])
write_init_body_sa(args, t[2], snip)
`
     [=10=]
endsnippet