// Labeljmp.vdm // Do NOT change the first part of this line // // Christian Ziemski 24.03.2004 // 25.03.2004 // // // Helps to navigate in a VEDIT macro file containing label(s) :LABEL: // // Assigns the following two keys: // // F12 - if on a line with a // // Call("label") : // Goto label : try to jump to that label in current file // Call(r, "label") : // // Call_File(r, "file") : open file // Call_File(r, "file", "label") : open file and jump to label // Chain_File(r, "file") : open file // // Shft-F12 - jump back via list with calls to current label // // F11 - jump back, if possible (via stack) // //----------------------------------------------------------------------------- // // #90 number of register running this macro // // #103 temp. Cur_Pos // #103 Cur_Pos in current line, just before EoL or comment // #104 temp. Cur_Pos // temp Buf num // #105 Match_Item of {call_file,callfile,chain_file,chainfile,call} // temp. number // #106 original cursor pos // temp. number // // @90 history of jumps (in fact of the starting points of the jumps) // // @101 temp string delimiter // @103 temp: first string param // label name // @104 temp: second string param // file name // @105 temp. for history line //----------------------------------------------------------------------------- #90=Macro_Num Reg_Empty(90) Key_Add("F11" , `[VISUAL EXIT] RS(103,"Labeljmp.vdm") RS(104, "// ") RS(104, @103, APPEND) Reg_Compare(#90, @104) if(Chars_Matched!=Reg_Size(104)){#90=100 Reg_Load(#90, @103, EXTRA) } Call(#90, "JUMPBACK") `,OK) Key_Add("F12" , `[VISUAL EXIT] RS(103,"Labeljmp.vdm") RS(104, "// ") RS(104, @103, APPEND) Reg_Compare(#90, @104) if(Chars_Matched!=Reg_Size(104)){#90=100 Reg_Load(#90, @103, EXTRA) } Call(#90, "JUMP") `,OK) Key_Add("Shft-F12", `[VISUAL EXIT] RS(103,"Labeljmp.vdm") RS(104, "// ") RS(104, @103, APPEND) Reg_Compare(#90, @104) if(Chars_Matched!=Reg_Size(104)){#90=100 Reg_Load(#90, @103, EXTRA) } Call(#90, "JUMPLIST") `,OK) return // // SUBROUTINES ---------------------------------------------------------------- // :JUMP: #106=Cur_Pos #103=EoL_Pos Search_Block("//", Cur_Pos, #103, BEGIN+NOERR) // check if comment in line if (!EM) { // if comment: check line only up to here #103=Cur_Pos } Goto_Pos(#106) Search_Block("|{call,goto,chain|[_]file}", BoL_Pos, #103, BEGIN+NOERR) if (EM) { return } if (Match("goto|[|W]", ADVANCE) == 0) { // goto Mark_Word Reg_Copy_Block(103, BB, BE) BB(CLEAR) Reg_Set(105, "@@@ ") // indicator for jump history entry Num_Str(Buf_Num, 105, LEFT+APPEND) // remember buffer number } else { // not goto #104=Cur_Pos if (Match("|{call_file,callfile,chain_file,chainfile,call}", ADVANCE) != 0) { Goto_Pos(#104) return } #105=Match_Item // to distinct "...file" from simple "Call" Match("|[|W](|[|W]", ADVANCE+NOERR) if (EM) { // if no opening parenthesis "(" Goto_Pos(#104) return } // now on first param Search_Block(%|{|,,",',`,´,/}%, Cur_Pos, #103, NOERR) // search for comma or string delimiter if (Match_Item == 1) { // if comma found => more than one param, first is register num Char(1) // after comma } Match("|W", NOERR+ADVANCE) if (Match(%|{",',`,´,/}%, ADVANCE)==0) { // 1st string parameter Reg_Copy_Block(101, Cur_Pos-1, Cur_Pos) BB(Cur_Pos) Search(@101) BE(Cur_Pos) Reg_Copy_Block(103, BB, BE) BB(CLEAR) } else { // ??? // to do: what here? } Char(1) // after closing string delimiter Reg_Empty(104) // optional register for file name Search_Block(%|{|,,)}%, Cur_Pos, #103, NOERR) // search for comma or ")" if (Match_Item==1) { // comma => another param follows Char(1) Match("|W", NOERR+ADVANCE) if (Match(%|{",',`,´,/}%, ADVANCE)==0) { // 2nd string parameter Reg_Copy_Block(101, Cur_Pos-1, Cur_Pos) BB(Cur_Pos) Search(@101) BE(Cur_Pos) Reg_Copy_Block(104, BB, BE) // the label Reg_Push(103,103) // switch registers for "file" and "label" Reg_Set(103, @104) Reg_Pop(104,104) BB(CLEAR) } } Reg_Set(105, "@@@ ") // indicator for jump history entry Num_Str(Buf_Num, 105, LEFT+APPEND) // remember buffer number if(#105 < 5) { // ..._File() if (Reg_Size(104) == 0) { // no label here ..._File(100, "file") Reg_Set(104, @103) Reg_Empty(103) } if (File_Exist(@104, NOERR)) { File_Open(@104) } else { Reg_Empty(103) // no label Reg_Empty(105) // no history Statline_Message("File not found") Goto_Pos(#106) } } } if (Reg_Size(103) > 0) { // if there is a label to search for Search("|@(103):", BEGIN+NOERR) // search label in text if (EM) { Statline_Message("Label not found") Reg_Empty(105) // no history Goto_Pos(#106) } else { Set_Visual_Line(0) } } if (Reg_Size(105) > 0) { // fill history only if really jumping Reg_Set(105, " ", APPEND) // continue to build history line Num_Str(#106, 105, LEFT+APPEND) // Cur_Pos Out_Reg(105, APPEND) Type_Newline(1) Out_Reg(CLEAR) Reg_Set(90, @105, INSERT) // insert the line into history } return // ------------------------------------------------------ :JUMPBACK: Reg_Compare(90, "@@@ ") // check if T-Reg really contains history entry if (Chars_Matched < 4) { return } #104=Buf_Num Buf_Switch(Buf_Free(EXTRA)) Reg_Ins(90, BEGIN) Char(4) #105=Num_Eval(SUPPRESS+ADVANCE) // buf num Match("|W", NOERR+ADVANCE) #106=Num_Eval(SUPPRESS+ADVANCE) // cur_pos BoF Del_Line(1) // delete this history entry Reg_Copy_Block(90, 0, File_Size) // re-save history Buf_Quit(OK) if (Buf_Status(#105) < 1) { // target buffer open/visible? Buf_Switch(#104) // no => switch to original buffer again } else { Buf_Switch(#105) // yes => switch to target buffer Goto_Pos(#106) // and cursor position } return // ------------------------------------------------------ //---------------------------------------------------------------------------- // Display list of goto/call's in a window. Use cursor keys to select bookmark. // Based on Markers.vdm by Pauli Lindgren //---------------------------------------------------------------------------- // :JUMPLIST: Num_Push(80,89) // save numeric used registers Reg_Push(90,91) // save used text register #87=50 // width of list window #80 = Buf_Num // #80 = original edit buffer #85 = Cur_Pos // #85 = original edit position Search("^:?[A-Za-z_1-2]+:", REGEXP+REVERSE+NOERR) // search current label if (EM) { Goto_Pos(#85) // go to original position Reg_Pop(90,91) // restore text register Num_Pop(80,89) // restore numeric registers return } Match(":", NOERR+ADVANCE) #83=Cur_Pos Search(":", NOERR) Reg_Copy_Block(91, #83, Cur_Pos) // save label Search_Block("//", BoL_Pos, Cur_Pos, BEGIN+REVERSE+NOERR) if (!EM) { // if label within comment: ignore it (Note: it's allowed by VEDIT, but not here (yet)) Goto_Pos(#85) // go to original position Reg_Pop(90,91) // restore text register Num_Pop(80,89) // restore numeric registers return } Win_Create(*,1,Win_Cols-#87-1,11,#87) // Create window Win_Switch(*) Win_Color(240) Win_Clear() Buf_Switch(#81=Buf_Free) Config(PG_E_SYNTAX,0,LOCAL) // disable syntax highlighting Win_Attach(*) // Attach special window IT(" Select target: ") #89=Config( D_H_CR_LINE, "Highlight cursor line (1=Full, 2=Partial)", 1 ) // // Display Calls/Gotos: // Buf_Switch(#80) // switch to original buffer #82 = 0 // counter BoF Repeat(ALL) { Search("|{call,goto,chain|[_]file}", NOERR+ERRBREAK) if (EM) { Line(1, NOERR+ERRBREAK) Continue } #83=Cur_Pos // Search_Block("//", BoL_Pos, Cur_Pos, BEGIN+REVERSE+NOERR) // if (!EM) { // if label within comment: ignore it (Note: it's allowed by VEDIT, but not here (yet)) // Line(1, NOERR+ERRBREAK) // Continue // } Search_Block("|{//,|>}", Cur_Pos, EoL_Pos, NOERR) // ignore comments; may not be foolproof! Search_Block(%|@(91)|{|S,|>}%, #83, Cur_Pos, BEGIN+NOERR) // search label here if (EM) { Line(1, NOERR+ERRBREAK) Continue } #84=Cur_Line // build the entry for display #88=EoL_Pos Goto_Pos(#83) if((Cur_Pos+#87-10)<#88){ // text example max. to EoL #88=Cur_Pos+#87-10 } Reg_Copy_Block(90, Cur_Pos, #88) Line(1, NOERR+ERRBREAK) Buf_Switch(#81) // switch to list Num_Ins(#84,NOCR) // insert line number IC(58) IC(32) // insert colon + space Reg_Ins(90) // insert the text block Ins_Newline(1) Buf_Switch(#80) // switch to original buffer #82++ // number of entries in list } // // Select a target from list: // Key_Purge() // clear keyboard buffer Buf_Switch(#81) // switch to marker list BOF Goto_Line(3) repeat (ALL) { // Loop until or Begin_Of_Line() #84 = Num_Eval(SUPPRESS) // #84 = line number Block_Begin(Cur_Pos) Block_End(EOL_Pos) Begin_Of_Line() Update() // Highlight current occurrence line #86 = Get_Key(" = Select, = Go, = jump back/to target, = Cancel",STATLINE) if (#86=='R'+'T'*256) { // Return Break // Break out of Repeat Loop } if (#86=='E'+'S'*256) { // Escape #84 = -1 // cancel (do not jump) Break // Break out of Repeat Loop } if (#86=='C'+'D'*256) { // Cursor Down if (Cur_Line<#82+2) { Line(1,NOERR) } } if (#86=='C'+'U'*256) { // Cursor Up if (Cur_Line>3) { Line(-1,NOERR) } else {Set_Visual_Line(3)} // scroll back to top } if (#86=='C'+'R'*256) { // Cursor Right Config( D_H_CR_LINE, "Highlight cursor line (1=Full, 2=Partial)", 1 ) Buf_Switch(#80) // return to original buffer Goto_Line(#84) // go to selected entry Update() Buf_Switch(#81) // switch to list } if (#86=='C'+'L'*256) { // Cursor Left Config( D_H_CR_LINE, "Highlight cursor line (1=Full, 2=Partial)", #89 ) Buf_Switch(#80) // return to original buffer Goto_Pos(#85) // go to original pos Update() Buf_Switch(#81) // switch to list } } Buf_Quit(DELETE+OK) // close window Buf_Switch(#80) // return to original buffer BB(CLEAR) // remove block markers if (#84!=-1) { // if ESC not pressed AND marker used Goto_Line(#84) // go to selected bookmark } else { Goto_Pos(#85) // go to original position } Config( D_H_CR_LINE, "Highlight cursor line (1=Full, 2=Partial)", #89 ) Reg_Pop(90,91) // restore text register Num_Pop(80,89) // restore numeric registers return //------------------------------------------------------------------------------- //---- for testing ---------------- goto test goto jump goto jumpback call("test") call ( 'test' ) Call_File (101, "C:\Vedit\user-mac\compdir.vdm") Chain(100) Call(100, "label") Call_File(100, "file") Chain_File(100, "file") Call_File(100, "file", "label") Call_File (101, "C:\Vedit\macros\compdir.vdm", "RUN") Chain_File (101, "D:\Vedit\macros\compdir.vdm", "SHELL")