• 用python实现一个按需生成用于vim跳转的tags文件的小程序


    初学python,找个有用的来练手。选定了一个我早就想做的让vim按需生成tags跳转文件的小程序。

    vim的tags用于跳转的好处自是不用多说,但是如何生成tags确实困扰我的一大问题,用VS的都知道,VS会为每个解决方案生成一个ncb文件用于自动提示,相当于tags的功能,这个ncb文件很智能,它会根据你所包含的头文件来自动处理。这样,你只需包含一个头文件,就可以出现该头文件相关的自动提示了。

    但是vim就没有像VS这么智能了,目前我的做法就是在某个目录下调用ctags,然后加上递归参数,这样的缺点就是会生成一个很大的tags文件,里面很多都是项目根本没用到的头文件的tags。为了改善这种情况,需要有一个按所用到的头文件来生成tags的方法,让ctags按需生成tags。

    ctags本身是支持从一个文件中读入需要生成tags的文件列表的,因此剩下的问题就是如何找到项目所用到的所有相关的C++文件,然后让ctags从这些文件中生成tags。这就是我拿来练手的小程序了。

    python的好处就是不用像C++那样考虑那么多不相关的细节,专注于你想做的。代码如下,应该还算精简吧。有更好的方法不妨评论分享下,:)

    # -*- coding: utf8 -*-  
    # by absolute8511 2010-12-04
    import os,sys
    from os import path
    import string,re
    
    #在系统头文件目录下查找系统头文件,可以自行添加头文件路径
    def findsysinclude(filename,includepath):
        if filename==None:
            return None
        sysincludepath = ['/usr/include/','/usr/include/c++/4.4/',
                '/usr/lib/gcc/i486-linux-gnu/4.4/include/','/usr/include/c++/4.4/i486-linux-gnu/']   #系统头文件目录
        includepath += sysincludepath
        for onepath in includepath:
            if path.isfile(onepath+filename):
                return onepath+filename
        print 'Not found: '+filename
        return None
    
    #读取用户传入的头文件路径参数
    args = sys.argv
    print args
    retest = re.compile(r'\.cpp$|\.c$|\.h$|\.hpp$|\.cc$',re.IGNORECASE)
    cppfiles = []
    #查找用户项目路径下的所有源文件
    for root,dirs,files in os.walk(os.getcwd()):
        oldlen = len(cppfiles)
        cppfiles += filter(lambda x:retest.search(x)<>None,files)        #过滤非C/C++文件
        for index in range(oldlen,len(cppfiles)):
            cppfiles[index] = root + '/' + cppfiles[index];
    
    oldstdout = sys.stdout
    sys.stdout= logfile = open('maketags.log','w')
    
    print 'total cpp files: ' + str(len(cppfiles))
    includetest = re.compile(r'\s*#include\s*((<(?P<sysincludefile>.*?)>)|("(?P<userincludefile>.*?)"))')  ## *?代表不贪婪匹配
    
    #对每个C++源文件,查找它包含的头文件以及它的头文件所包含的头文件,以次递归直到全部包含
    #由于已经遍历过用户目录了,因次只需要再把系统头文件加近来即可
    for cppfile in cppfiles:
        try:
            fp = open(cppfile,'r')
            print 'finding in file: '+cppfile
            for line in fp:
                result = includetest.search(line)   #正则匹配头文件
                if result <> None:
                    print 'Matched include line is:'+result.group()
                    tmp = findsysinclude(result.group('sysincludefile'),args[1:])
                    tmp2 = findsysinclude(result.group('userincludefile'),args[1:]) #用户头文件也去找系统目录
                    if tmp<>None and cppfiles.count(tmp)==0:
                        cppfiles += [tmp]
                        print 'Added sys files: '+tmp
                    # tmp2 = path.abspath(path.dirname(cppfile)+'/'+result.group('userincludefile'))
                    if tmp2<>None and cppfiles.count(tmp2)==0:
                        cppfiles += [tmp2]
                        print 'Added user files: '+tmp2
        finally:
            fp.close()
    try:
        filelist = open('python_tags_filelist','w')
        filelist.writelines('\n'.join(cppfiles))
    finally:
        filelist.close()
    
    print 'total cpp and include files:'+str(len(cppfiles))
    # print 'after delete duplicate files: ' + str(len(set(cppfiles)))
    sys.stdout = oldstdout
    logfile.close()
    
    os.system('ctags --c++-kinds=+p --fields=+iaS --extra=+q -L python_tags_filelist')
    

  • 相关阅读:
    nginx详解
    keeplived高可用集群
    mysql主从同步
    elasticsearch基础
    redis集群管理--sentinel
    socket阻塞与非阻塞,同步与异步,select,pool,epool
    django+channels+dephne实现websockrt部署
    Django+Nginx+uWSGI生产环境部署
    进制转换
    对golang指针的理解
  • 原文地址:https://www.cnblogs.com/absolute8511/p/1896671.html
Copyright © 2020-2023  润新知