void FindParts(const char* file, const char* part,StrList& dst) { String filename=file; filename.ToLower(); dst.Clean(); StrList tmp; int i; for(i=0;i<files.Count();i++) { if(files[i]->mainaload || files[i]->isLoadBase(filename)) { FindPartsInFile(files[i],part,tmp); } } if(tmp.Count()==0)return; tmp.Sort(dst); i=1; String *s=&dst[0]; while(i<dst.Count()) { if(dst[i]==*s) { dst.Delete(); }else { s=&dst[i]; i++; if(i==dst.Count())break; } } }
int UpdateTagsFile(const char* file) { TagFileInfo *fi=NULL; int i; String filename=file; filename.ToLower(); for(i=0;i<files.Count();i++) { if(files[i]->filename==filename) { fi=files[i]; break; } } if(!fi) { struct stat st; if(stat(filename,&st)==-1)return 0; TagFileInfo tfi; tfi.filename=filename; tfi.modtm=st.st_mtime; if(!FindIdx(&tfi))return 0; if(Load(filename,"")!=1)return 0; } StrList sl; if(!CheckChangedFiles(filename,sl))return 0; if(sl.Count()==0)return 1; sl.SaveToFile("tags.changes"); String cmd=config.exe+" "; String opt=config.opt; opt.Replace("-R",""); RegExp re("/\\*(\\.\\S*)?/"); SMatch m[4]; int n=4; while(re.Search(opt,m,n)) { opt.Delete(m[0].start,m[0].end-m[0].start); } cmd+=opt; cmd+=" -f tags.update -L tags.changes"; //extern int Msg(const char* err); //Msg(cmd); if(!Execute(cmd)) { remove("tags.changes"); return 0; } MergeFiles(file,"tags.update"); remove("tags.changes"); remove("tags.update"); Load(file,""); return 1; }
void Autoload(const char* fn) { String dir; if(fn) { dir=fn; int bs=dir.RIndex("\\"); dir.Delete(bs); } else { char buf[512]; GetCurrentDirectory(sizeof(buf),buf); dir=buf; } dir+="\\.tags-autoload"; dir.ToLower(); //DebugBreak(); StrList sl; int isenv=0; bool mainaload=false; for(;;) { if(GetFileAttributes(dir)!=0xFFFFFFFF) { sl.LoadFromFile(dir); for(int i=0;i<sl.Count();i++) { String fn=sl[i]; if(fn.Length()==0)continue; if(!(fn[0]=='\\' || fn[1]==':')) { int i=dir.RIndex("\\"); if(i!=-1) { fn.Insert(0,dir.Substr(0,i+1)); } } int z=dir.RIndex("\\"); if(z==-1)z=dir.RIndex(":"); Load(fn,isenv && z!=-1?"":dir.Substr(0,z+1),mainaload); } } if(!isenv) { int bs=dir.RIndex("\\"); if(bs!=-1) { dir.Delete(bs); bs=dir.RIndex("\\"); if(bs!=-1) { dir.Delete(bs+1); dir+=".tags-autoload"; }else { isenv=1; } }else { isenv=1; } if(isenv==1) { if(config.autoload.Length()!=0) { dir=config.autoload; mainaload=true; }else { break; } } }else { break; } } }
FARAPI(HANDLE) OpenPlugin(int OpenFrom,int Item) { UpdateConfig(); if(OpenFrom==OPEN_EDITOR) { //DebugBreak(); EditorInfo ei; I.EditorControl(ECTL_GETINFO,&ei); Autoload(ei.FileName); if(Count()==0) { Msg(MENotLoaded); return INVALID_HANDLE_VALUE; } MenuList ml; enum{ miFindSymbol,miUndo,miResetUndo, miComplete,miBrowseFile,miBrowseClass, }; ml<<MI(MFindSymbol,miFindSymbol) <<MI(MCompleteSymbol,miComplete) <<MI(MUndoNavigation,miUndo) <<MI(MResetUndo,miResetUndo) <<MI(MBrowseSymbolsInFile,miBrowseFile) <<MI(MBrowseClass,miBrowseClass); int res=Menu(GetMsg(MPlugin),ml,0); if(res==-1)return INVALID_HANDLE_VALUE; switch(res) { case miFindSymbol: { String word=GetWord(); if(word.Length()==0)return INVALID_HANDLE_VALUE; //Msg(word); PTagArray ta=Find(word,ei.FileName); if(!ta) { Msg(GetMsg(MNotFound)); return INVALID_HANDLE_VALUE; } TagInfo *ti; if(ta->Count()==1) { ti=(*ta)[0]; }else { ti=TagsMenu(ta); } if(ti)NavigateTo(ti); FreeTagsArray(ta); }break; case miUndo: { if(UndoArray.Count()==0)return INVALID_HANDLE_VALUE; /*char b[32]; sprintf(b,"%d",ei.CurState); Msg(b);*/ if(ei.CurState==ECSTATE_SAVED) { I.EditorControl(ECTL_QUIT,NULL); I.AdvControl(I.ModuleNumber,ACTL_COMMIT,(void*)-1); } SUndoInfo ui; UndoArray.Pop(ui); SetPos(ui.file,ui.line,ui.pos,ui.top,ui.left); }break; case miResetUndo: { UndoArray.Clean(); }break; case miComplete: { EditorInfo ei; I.EditorControl(ECTL_GETINFO,&ei); String word=GetWord(1); if(word.Length()==0)return INVALID_HANDLE_VALUE; StrList lst; FindParts(ei.FileName,word,lst); if(lst.Count()==0) { Msg(MNothingFound); return INVALID_HANDLE_VALUE; } int res; if(lst.Count()>1) { MenuList ml; for(int i=0;i<lst.Count();i++) { ml<<MI(lst[i],i); } res=Menu(GetMsg(MSelectSymbol),ml,0,MF_FILTER|MF_SHOWCOUNT,(void*)word.Str()); if(res==-1)return INVALID_HANDLE_VALUE; }else { res=0; } EditorGetString egs; egs.StringNumber=-1; I.EditorControl(ECTL_GETSTRING,&egs); while(isident(egs.StringText[ei.CurPos]))ei.CurPos++; EditorSetPosition esp; esp.CurLine=-1; esp.CurPos=ei.CurPos; esp.CurTabPos=-1; esp.TopScreenLine=-1; esp.LeftPos=-1; esp.Overtype=-1; I.EditorControl(ECTL_SETPOSITION,&esp); I.EditorControl(ECTL_INSERTTEXT,(void*)lst[res].Substr(word.Length()).Str()); }break; case miBrowseFile: { EditorInfo ei; I.EditorControl(ECTL_GETINFO,&ei); PTagArray ta=FindFileSymbols(ei.FileName); if(!ta) { Msg(MNothingFound); return INVALID_HANDLE_VALUE; } TagInfo *ti=TagsMenu(ta); if(ti)NavigateTo(ti); FreeTagsArray(ta); }break; case miBrowseClass: { #ifdef DEBUG //DebugBreak(); #endif String word=GetWord(); if(word.Length()==0) { char buf[256]; if(!I.InputBox(GetMsg(MBrowseClassTitle),GetMsg(MInputClassToBrowse),NULL, "",buf,sizeof(buf),NULL,0))return INVALID_HANDLE_VALUE; word=buf; } EditorInfo ei; I.EditorControl(ECTL_GETINFO,&ei); PTagArray ta=FindClassSymbols(ei.FileName,word); if(!ta) { Msg(MNothingFound); return INVALID_HANDLE_VALUE; } TagInfo *ti=TagsMenu(ta); if(ti)NavigateTo(ti); FreeTagsArray(ta); }break; } } else { int load=OpenFrom==OPEN_COMMANDLINE; if(OpenFrom==OPEN_PLUGINSMENU) { MenuList ml; enum {miLoadTagsFile,miUnloadTagsFile, miUpdateTagsFile,miCreateTagsFile}; ml<<MI(MLoadTagsFile,miLoadTagsFile) <<MI(MUnloadTagsFile,miUnloadTagsFile) <<MI(MCreateTagsFile,miCreateTagsFile) <<MI(MUpdateTagsFile,miUpdateTagsFile); int rc=Menu(GetMsg(MPlugin),ml,0); switch(rc) { case miLoadTagsFile: { load=1; }break; case miUnloadTagsFile: { ml.Clean(); ml<<MI(MAll,0); StrList l; GetFiles(l); for(int i=0;i<l.Count();i++) { ml<<MI(l[i],i+1); } int rc=Menu(GetMsg(MUnloadTagsFile),ml,0); if(rc==-1)return INVALID_HANDLE_VALUE; UnloadTags(rc-1); }break; case miCreateTagsFile: { HANDLE hScreen=I.SaveScreen(0,0,-1,-1); const char *msg[]={GetMsg(MPlugin),GetMsg(MTagingCurrentDirectory)}; I.Message(I.ModuleNumber,0,NULL,msg,2,0); int rc=TagCurrentDir(); I.RestoreScreen(hScreen); }break; case miUpdateTagsFile: { HANDLE hScreen=I.SaveScreen(0,0,-1,-1); const char *msg[]={GetMsg(MPlugin),GetMsg(MUpdatingTagsFile)}; StrList changed; PanelInfo pi; String file; I.Control(INVALID_HANDLE_VALUE,FCTL_GETPANELINFO,&pi); file=pi.CurDir; if(file[-1]!='\\')file+="\\"; file+=pi.PanelItems[pi.CurrentItem].FindData.cFileName; I.Message(I.ModuleNumber,0,NULL,msg,2,0); if(!UpdateTagsFile(file)) { I.RestoreScreen(hScreen); Msg(MUnableToUpdate); return INVALID_HANDLE_VALUE; } I.RestoreScreen(hScreen); }break; } } if(load) { //DebugBreak(); PanelInfo pi; I.Control(INVALID_HANDLE_VALUE,FCTL_GETPANELINFO,&pi); tagfile=pi.CurDir; if(tagfile[-1]!='\\')tagfile+="\\"; if(OpenFrom==OPEN_PLUGINSMENU) { tagfile+=pi.PanelItems[pi.CurrentItem].FindData.cFileName; }else if(OpenFrom==OPEN_COMMANDLINE) { char *cmd=(char*)Item; if(cmd[1]==':') { tagfile=cmd; }else { if(cmd[0]=='\\') { tagfile.Delete(2); tagfile+=cmd; }else { tagfile+=cmd; } } } int rc=Load(tagfile,"",true); if(rc>1) { Msg(GetMsg(rc)); return INVALID_HANDLE_VALUE; } String msg; msg.Sprintf("%s:%d",GetMsg(MLoadOk),Count()); Msg(msg); } } return INVALID_HANDLE_VALUE; }