vim 或 gvim 下 VHDL 代码追踪插件

插件使用方法及功能:

空格 + Left      :  追踪光标所在信号源头

空格 + Right    :  追踪光标所在信号目的

空格 + Down   :  回退

空格 + Up       :  向前

gi                   :    进入子模块

 Shift + t        : (1)显示当前模块拓扑结构(2)打开和收回光标所在模块拓扑子模块的拓扑结构

空格               : (1)光标在拓扑结构窗口,自动打开光标对应模块代码(2)光标在追踪结果窗口,自动定位到追踪结果对应代码行 (3)光标在trace point上时自动跳转到trace point 记录的位置。

空格 + h         : hold住光标所在窗口,该窗口除非手动关闭不会自动关闭。

空格 + a         : add trace point,在右侧显示拓扑栏增加 追踪点的功能,能够通过“空格” 直接跳转到添加追踪点的位置。


安装方式:

    (1) 按照file 0-4 将对于代码复制到对应文件名文件中 

       或 百度网盘下载源码 :http://pan.baidu.com/s/1o6D1ulG

    (2) 输入:chmod 777 install.py ,打开执行权限。

    (3) ./install , 运行install.py。

    (4) 根据提示如果存在库vhdl文件,输入库路径,如果没有输入'~'。

    (5) 按装成功。


#file 0 name: install.py

#! /usr/bin/python
#*________________________________________________________________________*
#*  FILENAME      : install.py                                            *
#*  AUTHOR        : JUN CAO                                               *
#*________________________________________________________________________*
import os
import re
os.system('mkdir -p ~/.vim/vimTrace')
curPath = os.popen('pwd').read()
pwd = os.popen('pwd').read()
usrPath = re.match('(?P<usrPath>^/home/\w+)(/.*|)$', pwd).group('usrPath')
vimPath = usrPath + '/' + '.vim/vimTrace'
libPath = raw_input('Input your Lib VHDL Path :')
fp = open('vhdlTrace.vim_t', 'w')
vimPathInit = False
for l in open('vhdlTrace.vim', 'r').readlines():
	if re.match('^vimPath =.*#install change', l) and (not vimPathInit):
		vimPathInit = True
		l = "vimPath = \"" + vimPath + "\" #install change\n"
	fp.write(l)
fp.close()
os.system('mv vhdlTrace.vim_t ' + vimPath + '/vhdlTrace.vim')
fp = open('vhdlTraceGlobal.py_t', 'w')
assistPathInit = False
libPathInit = False
for l in open('vhdlTraceGlobal.py', 'r').readlines():
	if re.match('^assistPath =.*#install change', l) and (not assistPathInit):
		assistPathInit = True
		l = "assistPath = \"" + vimPath + "\" #install change\n"
	if re.match('^libPath =.*#install change', l) and (not libPathInit):
		libPathInit = True
		l = "libPath = \"" + libPath + "\" #install change\n"
	fp.write(l)
fp.close()
os.system('mv vhdlTraceGlobal.py_t ' + vimPath + '/vhdlTraceGlobal.py')
fp = open('vhdlTraceBaseLib.py_t', 'w')
vimPathInit = False
for l in open('vhdlTraceBaseLib.py', 'r').readlines():
	if re.match('^vimPath =.*#install change', l) and (not vimPathInit):
		vimPathInit = True
		l = "vimPath = \"" + vimPath + "\" #install change\n"
	fp.write(l)
fp.close()
os.system('mv vhdlTraceBaseLib.py_t ' + vimPath + '/vhdlTraceBaseLib.py')
try:
	os.system('mv ~/.vimrc org_vimrc')
	new_vimrc = open('vimrc', 'r').readlines()
	fp = open('vimrc_t', 'w')
	new_vimrc_done = False
	old_vimrc_begin = False
	for l in open('org_vimrc', 'r').readlines():
		if re.search('"vi_vhdl_extend_begin', l):
			old_vimrc_begin = True
			for nl in new_vimrc:
				fp.write(nl)
			new_vimrc_done = True
			continue
		if old_vimrc_begin:
			if re.search('"vi_vhdl_extend_end', l):
				old_vimrc_begin = False
			continue
		fp.write(l)
	if not new_vimrc_done:
		for nl in new_vimrc:
			fp.write(nl)
	fp.close()
	os.system('mv vimrc_t ~/.vimrc')
	os.system('rm org_vimrc')
except:
	os.system('cat vimrc >> ~/.vimrc')



file 1 name : vhdlTrace.vim

"*________________________________________________________________________*
"*  FILENAME      : vhdlTrace.vim                                         *
"*  AUTHOR        : JUN CAO                                               *
"*________________________________________________________________________*
function! VimPythonExtend() 
python << EOF
import re
import vim
import os
import sys
vimPath = "/home/juncao/.vim/vimTrace" #install change
sys.path.insert(0,vimPath)
import vhdlTraceGlobal
G = vhdlTraceGlobal.G
from vhdlTraceBaseLib import*
os.system('rm -rf '+vimPath+'/.*.swp ')
os.system('rm -rf '+vimPath+'/*.vimTrace ')
def goIntoSubModule(Open = True, curCursor = False, curRight = False): #shortcut key <Down> 
    curBuf = vim.current.buffer
    curWin = vim.current.window
    if not curCursor:
        curCursor = curWin.cursor
    curLine = curBuf[curCursor[0]-1]
    if Open:
        updataTrace()
    leftSignal = getLeft(curLine,curRight)
    if not leftSignal:
        return False
    instEntityInf    = getInstEntity(curBuf.name, curCursor) 
    subEntityName    = instEntityInf[0] 
    subEntityLineNum = instEntityInf[1] 
    libName          = instEntityInf[2]
    try:
        subEntityPath = G['AllModules'][subEntityName][0]
    except:
        CmdPrint(str(subEntityLineNum+1)+' : module '+ subEntityName + " not exist !")
        return False
    G['upEntity'][subEntityPath] = {'upEntityPath':curBuf.name,'upInSubCursor':(subEntityLineNum+1, 0)}
    
    if Open:
        goWin(subEntityPath,(1,0),leftSignal)
        updataTrace()
        return True
    else:
        subModule = open(subEntityPath,'r').readlines()
        for i in range(0,len(subModule)):
            SLine = subModule[i]
            match_IO = re.match("(|.*\W)"+leftSignal+"(.*\W|):\s*(?P<type>in|out|inout)\s",SLine.lower())
            if match_IO:
                return {'name':leftSignal,'type':match_IO.group('type'),'path':subEntityPath, 'lineNum':i}
        assert(False),"we should found that line!"
    assert(False),"Should find a entity !"
def use_goIntoSubModule():
    if G['debugMode']:
        goIntoSubModule()
    else:
        try:
            goIntoSubModule()
        except:
            Pass
def TraceSour():
    curBuf = vim.current.buffer
    curWin = vim.current.window
    (cursor_x,cursor_y) = curWin.cursor
    updataTrace() #updata trace
    curLine = curBuf[cursor_x-1]
    curWord = getFullWord(curLine,cursor_y)
    G["MaybeSD"] = []
    G["SDPtr"] = [curWord,0]
    if not curWord:
        CmdPrint("current cursor not upon word !")
        return
    MatchCursorXHis = set()
    while True:
        matchCursor    = MatchFromNextLine(curWord) 
        matchCursorX   = matchCursor[0]
        matchLineNum   = matchCursorX - 1
        if matchCursorX in MatchCursorXHis:
            break
        MatchCursorXHis.add(matchCursorX)
        fullLineInf = getFullLine(curBuf,matchCursor,';')
        if not fullLineInf:
            continue
        fullLine    = fullLineInf[0]
        crossLines  = fullLineInf[1] 
        matchInput = re.match('(\s*'+curWord+'\s*:\s*in\s+)',fullLine.lower())
        if matchInput:
            curPath = curBuf.name
            if curPath in G['upEntity']:
                upEntityPath      = G['upEntity'][curPath]['upEntityPath']
                upSubInstCursor   = G['upEntity'][curPath]['upInSubCursor']
                goWin(upEntityPath, upSubInstCursor, curWord)
                updataTrace()
                return
            else:
                updataTrace()
                return
        matchAssign = re.match('(|.*\W)'+curWord+'(|\W.*)(<=|:=)',fullLine.lower()) # match key := | <= 
        if matchAssign:
            updataTrace()
            return
        if sepMatch(',',fullLine.lower(),".*=>(|.*\W)"+curWord+"(\W.*|)$"):
                subModuleInf = goIntoSubModule(False,matchCursor,curWord)
                if not subModuleInf:
                    G["MaybeSD"].append((curWord,curBuf.name,crossLines))
                    continue
                if subModuleInf['type'] == 'out':
                    goWin(subModuleInf['path'], (2,0), subModuleInf['name'])
                    updataTrace()
                    return
    if len(G["MaybeSD"]) == 0 : 
        CmdPrint("should find assign for this signal ,but not ! "+curWord)
        return
    CmdPrint("------------------- ----maybe dest-------------------------------")
    curWord   = G["MaybeSD"][0][0]
    sourPath  = G["MaybeSD"][0][1]
    startLine = G["MaybeSD"][0][2][0]
    goWin(sourPath, (startLine+1,0), curWord)
    updataTrace() #updata trace
    printSDInf(G["MaybeSD"],"Mybe Sour")
    CmdPrint("----------------------------END----------------------------------")
def use_TraceSour():
    if G['debugMode']:
        TraceSour()
    else:
        try:
            TraceSour()
        except:
            pass
def TraceDest(): 
    curBuf = vim.current.buffer
    curWin = vim.current.window
    (cursor_x,cursor_y) = curWin.cursor
    updataTrace() #updata trace
    curLine = curBuf[cursor_x-1]
    curWord = getFullWord(curLine,cursor_y)
    G["MaybeSD"] = []
    G["AllDest"] = []
    G["SDPtr"]   = [curWord,0]
    if not curWord:
        CmdPrint("current cursor not upon word !")
        return
    MatchCursorXHis = set()
    while True:
        matchCursor    = MatchFromNextLine(curWord)
        assert(matchCursor)
        matchCursorX   = matchCursor[0]
        matchLineNum   = matchCursorX - 1
        if matchCursorX in MatchCursorXHis:
            break
        MatchCursorXHis.add(matchCursorX)
        fullLineInf = getFullLine(curBuf,matchCursor,';')
        if not fullLineInf: # not a valid match
            continue
        fullLine    = fullLineInf[0]
        crossLines  = fullLineInf[1]
        matchOutput = re.match('(\s*'+curWord+'\s*:\s*out\s+)',fullLine.lower())
        if matchOutput:
            curPath = curBuf.name
            if curPath in G['upEntity'] :
                upEntityPath     = G['upEntity'][curPath]['upEntityPath']
                upSubInstCursor  = G['upEntity'][curPath]['upInSubCursor']
                upSubInstLine    = upSubInstCursor[0] -1
                upEntity         = open(upEntityPath,'r').readlines()
                findSignInUpInst = False
                for i in range(upSubInstLine,len(upEntity)):
                    upELine = upEntity[i]
                    upELine = re.sub('--.*','',upELine)
                    matchInst = re.match("(|.*\W)"+curWord+"(\W.*|)",upELine.lower())
                    if matchInst:
                        G["AllDest"].append((curWord,upEntityPath,[i]))
                        findSignInUpInst = True
                #CmdPrint('')
                #CmdPrint(str(upSubInstLine)+' '+upEntityPath)
                assert(findSignInUpInst),'We should find that singal:=%s'%(curWord)
            else:
                G["AllDest"].append((curWord,curBuf.name,[matchLineNum]))
                continue
        matchAssign = re.match('(.*(<=|:=)(|.*\W)'+curWord+'(\W.*|)$)',fullLine.lower()) # match key := | <= 
        if matchAssign:
            G["AllDest"].append((curWord,curBuf.name,crossLines))
            continue
        if sepMatch(',',fullLine.lower(),'.*=>(|.*\W)'+curWord+'(\W.*|)$'):
                subModuleInf = goIntoSubModule(False,matchCursor,curWord)
                if not subModuleInf:
                    G["MaybeSD"].append((curWord,curBuf.name,crossLines))
                    continue
                if subModuleInf['type'] == 'in':
                    leftWord = getLeft(fullLine,curWord)
                    G["AllDest"].append((leftWord,subModuleInf['path'],[subModuleInf['lineNum']]))
    if len(G["AllDest"]) + len(G["MaybeSD"]) == 0:
        CmdPrint("Should find assign for this signal ,but not ! "+curWord)
        return
    if len(G["AllDest"]) != 0:
        CmdPrint('')
        CmdPrint("------------------- --------DEST---------------------------------")
        curWord   = G["AllDest"][0][0]
        destPath  = G["AllDest"][0][1]
        startLine = G["AllDest"][0][2][0]
        goWin(destPath, (startLine-1,0), curWord)
        updataTrace() #updata trace
        printSDInf(G["AllDest"],"Dest")
        if len(G["MaybeSD"]) != 0:
            CmdPrint("------------------------Maybe Dest-------------------------------")
            printSDInf(G["MaybeSD"],"Maybe Dest")
        CmdPrint("----------------------------END----------------------------------")
        CmdPrint('')
        return
    if len(G["MaybeSD"]) != 0:
        CmdPrint('')
        CmdPrint("------------------- ----Maybe Dest-------------------------------")
        #CmdPrint("No Dest Find,Go First Assign, MaybeDest !")
        curWord   = G["MaybeSD"][0][0]
        destPath  = G["MaybeSD"][0][1]
        startLine = G["MaybeSD"][0][2][0]
        goWin(destPath, (startLine-1,0), curWord)
        updataTrace() #updata trace
        printSDInf(G["MaybeSD"],"Maybe Dest")
        CmdPrint("----------------------------END----------------------------------")
        CmdPrint('')
def use_TraceDest():
    if G['debugMode']:
        TraceDest()
    else:
        try:
            TraceDest()
        except:
            pass
def rollBack():
    cursorBack = G['CursorNow']-1
    if cursorBack < 0:
        CmdPrint("this already back to the original point !")
        return
    G['CursorNow'] -=1 
    BackFile = G['CursorTrace'][cursorBack][0]
    BackCursor = G['CursorTrace'][cursorBack][1]
    curWord =  G['CursorTrace'][cursorBack][2]  #add new
    goWin(BackFile, BackCursor, curWord)   #add new
def use_rollBack():
    if G['debugMode']:
        rollBack()
    else:
        try:
            rollBack()
        except:
            pass
def goForward():
    cursorForward = G['CursorNow']+1
    if cursorForward >= len(G['CursorTrace']):
        CmdPrint("this already forward to the newest point !")
        return
    G['CursorNow'] +=1 
    ForwardFile = G['CursorTrace'][cursorForward][0]
    ForwardCursor = G['CursorTrace'][cursorForward][1] 
    curWord =  G['CursorTrace'][cursorForward][2]  #add new
    goWin(ForwardFile, ForwardCursor, curWord)
def use_goForward():
    if G['debugMode']:
        goForward()
    else: 
        try:
            goForward()
        except:
            pass
def showLayer():
    debug(("Run showLayer()"))
    curPath = vim.current.buffer.name
    if curPath[-5:] != '.vhdl':
        debug(("End showLayer(): cause current file not .vhdl file!"))
        return
    updataTrace()
    newLayerDb = []
    curEntityName = getEntityNameFromPath(curPath) 
    newLayerDb.append((0,curPath,{'CopyNum':1, 'InstName':'top','libName':'top', 'name':curEntityName, 'matchCursor':(1,0)}))
    if curPath not in G['allTopologys'] :
        getTopology(curPath)
    TPKeys =  G['allTopologys'][curPath].keys()
    TPKeys.sort()
    for key in TPKeys:
        newLayerDb.append((1,key,G['allTopologys'][curPath][key])) 
    G['LayerDB'] = newLayerDb
    PrintLayer()
    updataTrace()
    debug(("End showLayer(): finish correct!"))
def openLayerFile(shadow = False):
    if not re.search(G['LayerPath'],vim.current.buffer.name) :
        return
    curLine = vim.current.window.cursor[0] - 1
    if G['IgnoreSpace'] == [True,curLine]: #add for unknow space
        G['IgnoreSpace'] = [False, 0]
        return 
    G['IgnoreSpace'] = [False,0]
    if curLine in range( len(G['LayerDB']) ):
        openPath = G['LayerDB'][curLine][1]
        moduleName = G['LayerDB'][curLine][2]['name']
        if shadow:
            goWin(openPath,(1,0),False,True)
            return curLine
        updataTrace()
        goWin(openPath,(2,0),moduleName) 
        updataTrace()
        return
    if curLine in range(len(G['LayerDB'])+2, len(G['LayerDB'])+3+len(G['CursorCheckPoint']) ) and not shadow :
        cursorLine = curLine - 3 - len(G['LayerDB'])
        Path   = G['CursorCheckPoint'][cursorLine]['path']
        cursor = G['CursorCheckPoint'][cursorLine]['cursor']
        Word   = G['CursorCheckPoint'][cursorLine]['word']
        updataTrace()
        goWin(Path, cursor, Word) 
        updataTrace()
        return
        
def openCmdSD():
    if not re.search(G['CmdPath'],vim.current.buffer.name) :
        return
    curLine = vim.current.window.cursor[0] - 1 
    if curLine < 0 and curLine >= len(G['CmdSDDB']):
        return
    openPath  = G['CmdSDDB'][curLine]['path']
    key       = G['CmdSDDB'][curLine]['key']
    startLine = G['CmdSDDB'][curLine]['startLine']
    updataTrace()
    goWin(openPath,(startLine+1,0),key) 
    updataTrace()
def use_SpaceOperate():
    debug(('Run SpaceOperate() at' ,vim.current.buffer.name))
    if G['debugMode']:
        if vim.current.buffer.name == G['LayerPath']:
            openLayerFile()
            return
        if vim.current.buffer.name == G['CmdPath']: 
            openCmdSD()
            return
    else:
        if vim.current.buffer.name == G['LayerPath']:
            try:
                openLayerFile()
            except:
                pass
            return
        if vim.current.buffer.name == G['CmdPath']: 
            try:
                openCmdSD()
            except:
                pass
            return
def rollBackLayer():
    curLine = vim.current.window.cursor[0] - 1
    debug(("Run rollBackLayer(%s)"%(curLine)))
    if curLine not in range(len(G['LayerDB']) - 1):
        return False
    curDepth  = G['LayerDB'][curLine][0]
    nextDepth = G['LayerDB'][curLine+1][0]
    if curDepth + 1 != nextDepth:
        debug(("End rollBackLayer(), False"))
        return False
    delLine = curLine + 1
    while True:
        if delLine == len(G['LayerDB']):
            break
        if G['LayerDB'][delLine][0] >= nextDepth:
            del G['LayerDB'][delLine]
            continue
        break
    PrintLayer()
    reSetLayerWinWidth()
    debug(("End rollBackLayer(), True"))
    G['IgnoreSpace'] = [True,curLine]
    return True
def expendLayer():
    debug(("Run expendLayer()"))
    if vim.current.buffer.name == G['LayerPath']:
        addCheckPoint()
        if rollBackLayer():
            debug(("End expendLayer():cause rollBackLayer() return True"))
            checkPointRecover()
            return True
        curLayerDB = G['LayerDB']
        curLine = openLayerFile(True)
        curDepth = G['LayerDB'][curLine][0]
        subLayerDB = []
        subPath = vim.current.buffer.name
        #if not G['allTopologys'].has_key(subPath):
        if subPath not in G['allTopologys']:
            getTopology(subPath)
        TPKeys = G['allTopologys'][subPath].keys()
        TPKeys.sort()
        for key in TPKeys:
            subLayerDB.append((curDepth+1, key, G['allTopologys'][subPath][key]))
        vim.command('q')
        reSetLayerWinWidth()
        if curLine == len(curLayerDB)-1: #last line
            newLayerDb = curLayerDB + subLayerDB
        else:
            newLayerDb = curLayerDB[:curLine+1] + subLayerDB +curLayerDB[curLine + 1:]
        G['LayerDB'] = newLayerDb
        PrintLayer()
        checkPointRecover()
        debug(("End expendLayer(): True"))
        return True
    debug(("End expendLayer(): False"))
    return False
def use_showLayer():
    debug(("Run use_showLayer()"))
    if G['debugMode']:
        if not expendLayer():
            showLayer()
    else: 
        try:
            if not expendLayer():
                showLayer()
        except:
            pass
    debug(("End use_showLayer()"))
def holdCurrentWin():
    curPath = vim.current.buffer.name
    if not G['holdWin'].has_key(curPath):
        G['holdWin'][curPath] = 'hold is window'
def use_holdCurrentWin():
    if G['debugMode']:
        holdCurrentWin()
    else: 
        try:
            holdCurrentWin()
        except:
            pass
def addCursorTrace():
    curPath   = vim.current.buffer.name
    curCursor = vim.current.window.cursor
    curWord   = getCurWord()
    G["CursorCheckPoint"].insert(0,{'path':curPath, 'cursor':curCursor, 'word':curWord})
    del G["CursorCheckPoint"][G['CursorCheckPointDepth']:]
    addCheckPoint()
    PrintLayer() 
    checkPointRecover()
def use_addCursorTrace():
    if G['debugMode']:
        addCursorTrace()
    else: 
        try:
            addCursorTrace()
        except:
            pass
        
EOF
endfunction



#file 2 name: vhdlTraceBaseLib.py

#*________________________________________________________________________*
#*  FILENAME      : vhdlTraceBaseLib.py                                   *
#*  AUTHOR        : JUN CAO                                               *
#*________________________________________________________________________*
import re
import vim
import os
import sys
vimPath = "/home/juncao/.vim/vimTrace" #install change
sys.path.insert(0,vimPath)
import vhdlTraceGlobal
G = vhdlTraceGlobal.G
def debug(Inf):
    if G['debugMode']:
        FP = open(G['debugPath'],'a')
        for i in Inf:
            FP.write(i.__str__())
        FP.write('\n')
        FP.close()
def getEntityNameFromPath(path):
    return re.match('.*/(?P<entityName>\w+)\.vhdl',path).group('entityName')
def CmdPrint(PrintStr):
    addCheckPoint()
    CmdWinOpen = False
    for i in range(0,len(vim.windows)):
        if vim.windows[i].buffer.name == G['CmdPath']:
            CmdWinOpen = True
            CmdWin = vim.windows[i]
            break 
    if not CmdWinOpen:
        curWinheight = vim.current.window.height
        layWinheight = curWinheight/5
        vim.command('bo sp '+G['CmdPath'])
        vim.current.window.height = layWinheight 
        CmdWin = vim.current.window
    writeLineNum = len(CmdWin.buffer)
    CmdWin.buffer.append(PrintStr)
    goWin(G['CmdPath'],(writeLineNum+1,0))
    vim.command('w!')
    vim.command('e')
    checkPointRecover() 
    return writeLineNum
def getFullWord(Line,Pos):
    if not Line:
        return ''
    cWord = ''
    for i in range(Pos,-1,-1):
        if re.match('\w',Line[i]):
            cWord = Line[i]+cWord 
        else:
            break
    for i in range(Pos+1,len(Line)):
        if re.match('\w',Line[i]):
            cWord = cWord + Line[i]
        else:
            break
    return cWord
def getFullLine(buf,cursor,septor):
    curLineNum = cursor[0] - 1
    curCharNum = cursor[1]
    curLine = buf[curLineNum]
    curLine = curLine.rstrip('\n')
    curLine = re.sub('--.*','',curLine) #clear note
    if re.match('^\s*$',curLine): #empty line
        return False
    if curCharNum >= len(curLine):
        return False
    t_result = ''
    crossLines = [curLineNum]
    LineEnd = False
    for i in range(curCharNum,len(curLine)):
        c = curLine[i]
        if re.match(septor,c):
            LineEnd = True
            break
        t_result = t_result + c
    LineStart = False
    for i in range(curCharNum-1,-1,-1):
        c = curLine[i]
        if re.match(septor,c):
            LineStart = True
            break
        t_result = c + t_result
    if not LineEnd:
        for i in range(curLineNum+1,len(buf)):
            t_line = buf[i].rstrip('\n')
            t_line = re.sub('--.*','',t_line) #clear note
            t_line = re.subn('\s+',' ',t_line)[0]#all empty to space
            if re.match('^\s*$',t_line): #empty line
                continue
            sep = re.split(septor,t_line)
            t_result = t_result + sep[0]
            if len(sep) > 1: 
                if not re.match('^\s*$',sep[0]):
                    crossLines.append(i)
                break
            crossLines.append(i)
    if not LineStart:
        for i in range(curLineNum-1,-1,-1):
            t_line = buf[i].rstrip('\n')
            t_line = re.sub('--.*','',t_line) #clear note
            t_line = re.subn('\s+',' ',t_line)[0]#all empty to space
            if re.match('^\s*$',t_line): #empty line
                continue
            sep = re.split(septor,t_line)
            t_result = sep[-1] + t_result
            if len(sep) > 1: 
                if not re.match('^\s*$',sep[-1]):
                    crossLines.append(i)
                break
            crossLines.append(i)
    crossLines.sort()
    return (t_result,crossLines)
def getCurFullLine():
    return getFullLine(vim.current.buffer, vim.current.window.cursor, ';')
def getFullLines(sep_sign,pre_lines):
    lines  = []
    t_line = ''
    t_line_begin_num = 0
    crossLines = []
    for i in range(0,len(pre_lines)):
        pre_line = pre_lines[i]
        pre_line = pre_line.strip('\n')
        pre_line = pre_line.lower()
        pre_line = re.sub('--.*','',pre_line) #clear note
        pre_line = re.subn('\s+',' ',pre_line)[0]#all empty to space
        if re.match('^\s*$',pre_line): #empty line
            continue
        crossLines.append(i)
        sep = re.split(sep_sign,pre_line)
        if len(sep) > 1:
            t_line = t_line + sep[0]
            lines.append((t_line_begin_num,t_line,crossLines))
            crossLines = []
            t_line = ''
            for j in range(1,len(sep)-1):
                lines.append((i,sep[j],[i]))
            if re.match('^\s*$',sep[-1]):
                t_line_begin_num = i + 1
                continue
            t_line = t_line + sep[-1]
            t_line_begin_num = i
            crossLines.append(i)
        else:
            t_line = t_line + pre_line
    lines.append((t_line_begin_num,t_line,crossLines)) #if last line no ";" or ","
    return lines
def getCurWord():
    curBuf = vim.current.buffer
    curWin = vim.current.window
    (cursor_x,cursor_y) = curWin.cursor #cursor position
    curLine = curBuf[cursor_x-1]
    curWord = getFullWord(curLine,cursor_y)
    return curWord 
def updataTrace(nextTrace = False):
    if not nextTrace:
        curWord = getCurWord() # if not on word return ''
        nextTrace = (vim.current.buffer.name, vim.current.window.cursor, curWord)
    assert(G['CursorNow'] < len(G['CursorTrace']))
    if G['CursorNow'] != -1: # not initial
        curTrace = G['CursorTrace'][G['CursorNow']] #except when initial
        if curTrace[0] == nextTrace[0] and curTrace[1][0] == nextTrace[1][0]:
            #debug('same file and same line !')
            return
    del G['CursorTrace'][G['CursorNow'] + 1:]
    G['CursorTrace'].append(nextTrace)
    G['CursorNow'] += 1
    #debug("add new trace "+nextTrace[0]+' '+str(G['CursorNow']))
def getLeft(Line,Right = False):
    Lines = re.split(';|,',Line)
    if not Right:
        Right = '.*'
    for L in Lines:
        match_assign = re.match("\s*(?P<left>\w+)(\W.*|)=>(.*\W|)"+Right+"(\W.*|)$",L)
        if match_assign:
            return match_assign.group('left')
    CmdPrint("Current line not across module !"+ Line +" "+ Right)
    return
def MatchFromCurLine(key , startCursor = False, patten = False):
    try:
        if not startCursor:
            startCursor = vim.current.window.cursor
        if startCursor[0] == 1:
            startCursor = (len(vim.current.buffer)+1,startCursor[1])
        vim.current.window.cursor = (startCursor[0]-1,startCursor[1])
        if not patten:
            patten = '/\c\<'+key+'\>'
        vim.command(patten)
        curCursor    = vim.current.window.cursor
        matchLineNum = curCursor[0]-1
        matchLine    = vim.current.buffer[matchLineNum]
        matchColmNum = len(re.match('(?P<pre>|.*\W)'+key+'(\W.*|)',matchLine).group('pre'))
        matchCursor  = (matchLineNum+1,matchColmNum) 
        vim.current.window.cursor = matchCursor
        return matchCursor 
    except:
        return False
def MatchFromNextLine(key, patten = False):
    try:
        if not patten:
            patten = '/\c\<'+key+'\>'
        vim.command(patten)
        curCursor    = vim.current.window.cursor
        matchLineNum = curCursor[0]-1
        matchLine    = vim.current.buffer[matchLineNum]
        matchColmNum = len(re.match('(?P<pre>|.*\W)'+key+'(\W.*|)',matchLine.lower()).group('pre'))
        matchCursor  = (matchLineNum+1,matchColmNum) 
        vim.current.window.cursor = matchCursor
        return matchCursor 
    except:
        return False
def isAssistWin(path = False):
    if not path:
        path = vim.current.buffer.name
    if re.search(G['LayerPath']+'|'+G['CmdPath'], path):
        return True
    return False
def reSetLayerWinWidth():
    for i in range(0, len(vim.windows)):
        if vim.windows[i].buffer.name == G['LayerPath']:
            vim.windows[i].width = G['LayerWinWidth']
def resortWinQueue(path):
    i = 0
    match = False
    for i in range(0, len(G["WinQueue"])):
        if path == G["WinQueue"][i]:
            match = True
            break
    if match:
        del G["WinQueue"][i]
        G["WinQueue"].insert(0, path)
def closeWin(path):
    #addCheckPoint()
    for i in range(0,len(vim.windows)):
        if vim.current.buffer.name == path:
            vim.command('q')
            reSetLayerWinWidth()
            break
        vim.command("wincmd w")
    #checkPointRecover()
def delCloseWin():
    openWin = {}
    for i in range(0, len(vim.windows)):
        openWin[vim.windows[i].buffer.name] = 0
    i = 0
    while True:
        if i >= len(G["WinQueue"]):
            break
        t_path = G["WinQueue"][i]
        if openWin.has_key(t_path):
            i += 1
            continue
        del G["WinQueue"][i]
    i = 0
    keys = G["holdWin"].keys()
    debug(('debug 00:',keys))
    while True:
        if i >= len(keys):
            break
        t_path = keys[i]
        if openWin.has_key(t_path):
            i += 1
            continue
        del G["holdWin"][keys[i]]
        i += 1
def addNewWin():
    QueueWin = {}
    for i in G["WinQueue"]:
        QueueWin[i] = 0
    for i in range(0, len(vim.windows)):
        t_path = vim.windows[i].buffer.name
        if (not isAssistWin(t_path)) and (not QueueWin.has_key(t_path)):
            G["WinQueue"].insert(0, t_path)
            QueueWin[t_path] = 0
    
def goWin(path, cursor = (1,0), searchWord = False, shadow = False):
    reSetLayerWinWidth()
    delCloseWin()
    addNewWin()
    for i in range(0,len(vim.windows)):
        if vim.current.buffer.name == path:
            resortWinQueue(path)
            if searchWord:
                MatchFromCurLine(searchWord,cursor)
                return
            vim.current.window.cursor = cursor
            return
        vim.command("wincmd w")
    if not os.path.isfile(path):
        CmdPrint(path+" not exit !")
        return 
    debug(('0_0 0:curWin:', G["WinQueue"]))
    debug(('0_0 0.1:', shadow,G["holdWin"]))
    if not isAssistWin(path) and not shadow:
        G["WinQueue"].insert(0,path)
        i = len(G["WinQueue"])-1
        while len(G["WinQueue"]) > G["MaxWinNum"] + len(G["holdWin"]):
            if G["holdWin"].has_key(G["WinQueue"][i]):
                i -=1
                if i < 0:
                    break
                continue
            t_path =  G["WinQueue"][i]
            closeWin(t_path)
            i -=2
            if i < 0:
                break
    if isAssistWin():
        vim.command("wincmd w")
        if isAssistWin():
            vim.command("wincmd w")
    vim.command("bel vsp "+path)
    debug(('0_0 1:curWin:', G["WinQueue"]))
    debug(('0_0 2:add a new win path = ', path))
    if searchWord:
        MatchFromCurLine(searchWord,cursor)
        reSetLayerWinWidth()
        return
    vim.current.window.cursor = cursor
    reSetLayerWinWidth()
def printSDInf(SDInf, prefix, start = 0):
    curBuf = vim.current.buffer 
    L = len(SDInf)
    if  start >= L :
        return
    #CmdPrint("-"*20+prefix+" total:"+str(L)+" Start"+'-'*20)
    for i in range(start,L):
        tempBuf = curBuf
        key   = SDInf[i][0]
        path  = SDInf[i][1]
        lineNums = SDInf[i][2]
        entity = getEntityNameFromPath(path)
        if curBuf.name != path:
            tempBuf = open(path,'r').readlines()
        CmdWriteLineNum = CmdPrint(prefix+' '+str(i)+":|"+entity+' '+str(lineNums[0])+": "+tempBuf[lineNums[0]])
        G['CmdSDDB'][CmdWriteLineNum] = {'path':path,'key':key,'startLine':lineNums[0]}
    #CmdPrint("-"*20+prefix+" End"+'-'*20)
def ChoseNextSD(SDInf,TraceWord):
    if G["SDPtr"][0] == TraceWord:
        if len(SDInf) == 0:
            return
        G["SDPtr"][1] = (G["SDPtr"][1] + 1) % len(SDInf)
        NextMatch = SDInf[G["SDPtr"][1]]
        CmdPrint("Next Trace "+str(G["SDPtr"][1])+":")
        curWord   = NextMatch[0]
        SDPath    = NextMatch[1]
        startLine = NextMatch[2][0]
        goWin(SDPath, (startLine - 1,0), curWord) #why not startLine
        updataTrace()
        return True
    return
def getRealPos(Buf,SearchWord,Start):
    for i in range(Start, len(Buf)):
        tempLine = Buf[i]
        if re.match("(.*\W|)"+SearchWord+"(\W.*|)$",tempLine):
            return i
    assert(False),"We shoild find that patten"
def getInstEntity(path, cursor):
    lineNum = cursor[0] - 1
    Lines = open(path,'r').readlines()
    for i in range(lineNum, -1, -1):
        line = Lines[i]
        line = re.sub('--.*','',line) #clear note
        line = re.subn('\s+',' ',line)[0]#all empty to space
        if re.match('^\s*$',line): #empty line
            continue
        matchInst = re.search('\s*(?P<instName>\s*:\s*(((?P<isEntity>entity\s+)(?P<lib_name>\w+)\.(?P<sub_entity_name>\w+))|(?P<compName>\w+))(\s+|$))',line.lower())
        if matchInst:
            instName = matchInst.group('instName')
            isEntity = matchInst.group('isEntity')
            lib_name = matchInst.group('lib_name')
            sub_entity_name = matchInst.group('sub_entity_name')
            compName = matchInst.group('compName')
            moduleName = sub_entity_name if isEntity else compName
            return (moduleName, i, lib_name)
    assert(False),"We should find entity !"
def getCurInstEntity():
    curBuf = vim.current.buffer
    curWin = vim.current.window
    return getInstEntity(curBuf.name,curWin.cursor)  
def sepMatch(septor,fullLine,patten):
    sepLines = re.split(septor,fullLine)
    for i in range(0,len(sepLines)):
        match = re.match(patten,sepLines[i])
        if match:
            return match
    return False
def addCheckPoint():
    curPath = vim.current.buffer.name
    cursor = vim.current.window.cursor
    curWord = getCurWord() 
    G['checkPoint'].append((curPath,cursor,curWord))
def checkPointRecover():
    CP = G['checkPoint'].pop()
    #goWin(CP[0],CP[1],CP[2],True)
    goWin(CP[0],CP[1],CP[2])
def getTopology(path):
    addCheckPoint()
    goWin(path)
    MatchCursorXHis = set()
    TopologyDS      = {}
    while True:
        matchCursor    = MatchFromNextLine('port\s*map')
        
        if not matchCursor: #no match found
            break
        
        matchCursorX   = matchCursor[0]
        matchLineNum   = matchCursorX - 1
        if matchCursorX in MatchCursorXHis: # found all module
            break
        MatchCursorXHis.add(matchCursorX)
        
        matchLine = vim.current.buffer[matchLineNum].rstrip('\n')
        if re.match(".*--.*\Wport\s+map(\W.*|$)" ,matchLine): #this is not valid line
            continue
        instName      = '' 
        isEntity      = ''
        libName       = ''
        entityName    = ''
        compName      = ''
        subEntityName = ''
        subInstLineNum= ''
        for l in range(matchLineNum, -1 ,-1):
            c_pre_line =  vim.current.buffer[l].rstrip('\n')
            c_pre_line =  re.sub('--.*','',c_pre_line) #clear note
            if re.match('^\s*$',c_pre_line): #empty line
                continue
            matchInst = re.search('\s*(?P<instName>\s*:\s*(((?P<isEntity>entity\s+)(?P<libName>\w+)\.(?P<entityName>\w+))|(?P<compName>\w+))(\s+|$))',c_pre_line.lower())
            if matchInst:
                instName      = matchInst.group('instName')
                isEntity      = matchInst.group('isEntity')
                libName       = matchInst.group('libName')
                entityName    = matchInst.group('entityName')
                compName      = matchInst.group('compName')
                subInstLineNum = l
                subEntityName = entityName if isEntity else compName
                break
        assert(subInstLineNum),'%d : port map...'%(matchLineNum)
        
        if subEntityName in G['ModuleNotShowInTopo']: #this module should not show in topo
            continue
        subEntityPath = ( G['AllModules'].get(subEntityName, ['']) )[0] # get the first module path
        if subEntityPath in TopologyDS:
            TopologyDS[subEntityPath]['CopyNum'] += 1
            TopologyDS[subEntityPath]['InstName'].append(instName)
        else:
            TopologyDS[subEntityPath] = {'CopyNum':1, 'InstName':[instName],'libName':libName, 'name':subEntityName, 'matchCursor':(subInstLineNum+1, 0)}
        
    G['allTopologys'][path] = TopologyDS
    for key in TopologyDS: # add for topology trace
        iterm = TopologyDS[key]
        matchCursor = iterm['matchCursor']
        G['upEntity'][key] = {'upEntityPath':path, 'upInSubCursor':matchCursor}
    checkPointRecover() 
def PrintLayer():
    curWinWidth = vim.current.window.width
    layWinWidth = curWinWidth/6
    LayerWinOpen = False
    for i in range(0, len(vim.windows)):
        if vim.current.buffer.name == G['LayerPath']:
            LayerWinOpen = True
            break
        vim.command("wincmd w")
    if not LayerWinOpen:
        vim.command('top vsp '+G['LayerPath'])
        vim.current.window.width = layWinWidth
    LayBuf = vim.current.buffer
    del LayBuf[0:]
    topLineDB = G['LayerDB'][0]
    LayBuf[0] = '    '*topLineDB[0] + topLineDB[2]['name']
    for i in range(1,len(G['LayerDB'])):
        LineDB = G['LayerDB'][i]
        LayBuf.append('    '*LineDB[0]+'|'+LineDB[2]['name'])
    if len(G['CursorCheckPoint']) > 0:
        LayBuf.append('')
        LayBuf.append('')
        LayBuf.append('Check Point:')
        for i in range(len(G['CursorCheckPoint'])):
            LayBuf.append('P'+str(i)+' : '+G['CursorCheckPoint'][i]['word'])
    vim.command('w!')



#file 3 name:  vhdlTraceGlobal.py

#*________________________________________________________________________*
#*  FILENAME      : vhdlTraceGlobal.py                                    *
#*  AUTHOR        : JUN CAO                                               *
#*________________________________________________________________________*
import re
import vim
import os
import sys
assistPath = "/home/juncao/.vim/vimTrace" #install change
libPath = "/home/juncao/Work/src/lib" #install change
libPath    = libPath.rstrip('/') + '/'
workPath = os.getcwd()
def getAllVhdlModule(dirs):
    vhdl_modules = {}  # { vhdl module name : vhdl file paths }
    for d in dirs:
        vhdl_files_path = os.popen('find ' + d +' -name \'*.vhdl\' -type f  2>/dev/null').readlines()
        for vhdl_file in vhdl_files_path:
            vhdl_file = vhdl_file.strip('\n')
            match = re.match("(?P<path>.*/)(?P<name>\w+)\.vhdl$",vhdl_file)
            if match:
                moduel_name = match.group("name")
                file_path   = vhdl_file
                vhdl_modules.setdefault(moduel_name, []).append(file_path)
    return vhdl_modules     
all_vhdl_modules = getAllVhdlModule([libPath, workPath])
G = {
     "AllModules"   :all_vhdl_modules
    ,"ModuleNotShowInTopo" : {} 
    ,"FullLines"    :{}
    ,"CursorTrace"  :[]
    ,"CursorNow"    :-1
    ,"AllDest"      :[]
    ,"SDPtr"        :['',0]
    ,"MaybeSD"      :[]
    ,"upEntity"     :{}
    ,"checkPoint"   :[]
    ,"allTopologys" :{}
    ,"LayerPath"    :assistPath+'/layer.vimTrace'
    ,"LayerDB"      :[]
    ,"LayerWinWidth":40
    ,"CmdPath"      :assistPath+'/Cmd.vimTrace'
    ,"CmdSDDB"      :{}
    ,"WinQueue"     :[]
    ,"MaxWinNum"    :1
    ,"debugPath"    :assistPath+'/debug.vimTrace'
    ,"debugMode"    :True
    ,"holdWin"      :{}
    ,"IgnoreSpace"  :[False,0]
    ,"CursorCheckPoint" :[]
    ,"CursorCheckPointDepth" :10
}


#file 4 name :  vimrc

注:会在~/.vimrc中添加快捷键,不会更改原来vimrc内容。

"vi_vhdl_extend_begin-----------------------------------
source ~/.vim/vimTrace/vhdlTrace.vim
call VimPythonExtend()
map <Space><Right>       :py use_TraceDest()        <CR>
map <Space><Left>        :py use_TraceSour()        <CR>
map <Space><Down>        :py use_rollBack()         <CR>
map <Space><Up>          :py use_goForward()        <CR>
map gi                   :py use_goIntoSubModule()  <CR>
map <Space>              :py use_SpaceOperate()     <CR>
map <S-t>                :py use_showLayer()        <CR> 
map <Space>h		     :py use_holdCurrentWin()   <CR>
map <Space>a		     :py use_addCursorTrace()   <CR>
"vi_vhdl_extend_end-------------------------------------


你可能感兴趣的:(vim,gvim,gvim,vhdl,vhdl,信号追踪)