在Vim中使用ctags导航Python模块?

6 投票
2 回答
7747 浏览
提问于 2025-04-18 07:50

我在用Vim配合ctags来写Python代码,这样可以很方便地找到类、字段等内容。不过,有一点让我困惑的是,它似乎不包括Python文件名,也就是模块名。这样可以吗?我更希望能直接输入ta <module>来跳转到某个模块,而不是像用NERDtree那样一层一层地找文件。我在Java中习惯这样做,因为类名就是文件名。

2 个回答

3

使用“Exuberant tags”(加上 --extra=+f)可以为 Python 文件名生成标签,比如 my_module.py,但是它不会为模块名生成标签,比如 my_module。所以我自己修改了一个 ptags 脚本。你可以把下面的内容保存到一个叫 ptags 的文件里,放在你的路径中,并且让它可以执行:

#! /usr/bin/env python

# ptags
#
# Create a tags file for Python programs, usable with vi.
# Tagged are:
# - functions (even inside other defs or classes)
# - classes
# - filenames
# Warns about files it cannot open.
# No warnings about duplicate tags.

import sys, re, os
import argparse

tags = []    # Modified global variable!

def main():
    for root, folders, files in os.walk(args.folder_to_index):
        for filename in files:
            if filename.endswith('.py'):
                full_path = os.path.join(root, filename)
                treat_file(full_path)
        if not args.recursive:
            break

    if tags:
        fp = open(args.ctags_filename, 'w')
        tags.sort()
        for s in tags: fp.write(s)

expr = '^[ \t]*(def|class)[ \t]+([a-zA-Z0-9_]+)[ \t]*[:\(]'
matcher = re.compile(expr)

def treat_file(filename):
    try:
        fp = open(filename, 'r')
    except:
        sys.stderr.write('Cannot open %s\n' % filename)
        return
    base = os.path.basename(filename)
    if base[-3:] == '.py':
        base = base[:-3]
    s = base + '\t' + filename + '\t' + '1\n'
    tags.append(s)
    while 1:
        line = fp.readline()
        if not line:
            break
        m = matcher.match(line)
        if m:
            content = m.group(0)
            name = m.group(2)
            s = name + '\t' + filename + '\t/^' + content + '/\n'
            tags.append(s)

if __name__ == '__main__':
    p = argparse.ArgumentParser()
    p.add_argument('-f', '--ctags-filename', type=str, default='tags')
    p.add_argument('-R', '--recursive', action='store_true')
    p.add_argument('folder_to_index', type=str, default='.')
    args = p.parse_args()
    main()

接下来,运行下面的命令来生成一个标签文件,这个命令会递归处理当前目录:

ptags -R -f tags_file_to_create /path/to/index

7

如果你是用 exuberant ctags 来生成标签文件(还有其他方法吗?),那么可以试着加上 --extra=+f 这个选项。想了解更多细节,可以查看这个手册页面:http://ctags.sourceforge.net/ctags.html#OPTIONS

撰写回答