// // COLLEXP.VDM Christian Ziemski 14.11.2005 // 22.11.2005 // // // Collapses lines of text into labels like %<--00013-- -->% // and expands that label again. // // That should mimic "code folding" of other editors. // // If there is a block highlighted, this block of complete lines(!) is // collapsed = cut out = folded. // // If there is no block higlighted the block delimited by curly braces {} // around the cursor position is folded. // To be exact: All complete lines between the lines with the braces (without them itself). // // // Those cut-out lines are stored in PATHNAME.clx // // (Imagine those %< as a pair of scissors) // // Key-Assignments: Ctrl-Numpad- collapse (cut out) // Ctrl-Numpad+ expand (insert) // Ctrl-Numpad* expand all // // Please note: This is a beta version or to be specific: Heavily under construction!!! // It's not yet fully stress-tested. // So use at your own risk. // // // To do: // - more data security (perhaps like DB-transactions?) // - check or disable undo just before collapsing for data security // - setup File_Close_Macro for data security // // - more (error) handling and messages // // - check .clx file for emptiness // - counter for collapses // - eventually: some environment around a snippet in the .clx-file (for security) // - check/optimize/document register usage // - more docu // //-------------------------------------------------------------------- // do some preparations for the macro // check if the key assignments are alread there // if not: assign them // #103=Buf_Num Buf_Switch(Buf_Free(EXTRA)) Out_Ins() Key_List() Out_Ins(CLEAR) Search("| BE) { // normalize block #106=BB BB(BE) BE(#106) } } Goto_Pos(BB) if (At_EoL) { Line(1) } else { BoL } BB(CP) #101=Win_Vert-(#104-Cur_Line) // line position in window // count the indention #106=0 Search_Block("|!|W", Cur_Pos, EoL_Pos, NOERR) if (!Error_Match) { #106=Cur_Col - 1 } #105=Cur_Line ItoA(#105, 105, FILL+NOCR) Goto_Pos(BE) if (At_BoL) { Char(-Newline_Chars) } else { EoL } BE(CP) #105=Cur_Line-#105+1 // number of lines // Attention! More checks/security needed! Reg_Copy_Block(106, BB, BE) // without lonely (if any) CR/LF Reg_Set(103, PATHNAME) // the main text file #103=Buf_Num Reg_Set(104, @103) Reg_Set(104, ".clx", APPEND) // the file containing the "collapsed" (= cut-out) text parts File_Open(@104) #104=Buf_Num // search for already existing label repeat(ALL) { Search("%<--|@(105)", BEGIN+ERRBREAK) Reg_Set(105, "x", APPEND) } // => $105 contains a new valid label now // append the new cut-out text at End_Of_File EoF if (! At_BoL) { Ins_Newline } Ins_Text("%<--") Reg_Ins(105) Ins_Text("--") // Num_Ins(Reg_Size(106), FILL+NOCR) // first version with number of bytes inserted Num_Ins(#105, FILL+NOCR) // now with number of lines Ins_Text("--") Ins_Newline Reg_Ins(106) Ins_Newline File_Save(OK+NOMSG) // save and quit the .clx file Buf_Quit(OK) Buf_Switch(#103) Del_Block(BB,BE) // use the above indention here too: Ins_Char(32, COUNT, #106) // try to use an appropriate comment (e.g. //, regarding to File_Ext) Reg_Set(103, FILE_EXT) if (Reg_Compare(103, ".VDM")==0) { Ins_Text("// ") } if (Reg_Compare(103, ".C")==0) { Ins_Text("// ") } if (Reg_Compare(103, ".CPP")==0) { Ins_Text("// ") } // etc. Ins_Text("%<--") Reg_Ins(105) Ins_Text("-- -->%") Set_Visual_Line(#101) return //-------------------------------------------------------------------- :expand_all: // check if in .clx itself Reg_Set(104, FILE_EXT) if (Reg_Compare(103, ".clx")==0) { return } Reg_Set(103, PATHNAME) #103=Buf_Num Reg_Set(104, @103) Reg_Set(104, ".clx", APPEND) Save_Pos #100=Win_Vert BoF // for all labels repeat (ALL) { Search("%<--", ERRBREAK) Call("expand1") } Restore_Pos Set_Visual_Line(#100) return //-------------------------------------------------------------------- :expand: // check if in .clx itself Reg_Set(104, FILE_EXT) if (Reg_Compare(103, ".clx")==0) { return } Reg_Set(103, PATHNAME) #103=Buf_Num Reg_Set(104, @103) Reg_Set(104, ".clx", APPEND) // check if cursor is in a line with label #101=Cur_Pos BoL Search_Block("%<--", BoL_Pos, EoL_Pos, NOERR) if (Error_Match) { Goto_Pos(#101) return } :expand1: #101=Cur_Pos #105=Win_Vert // line position in window // get the relevant part of label Search_Block("--", Cur_Pos, EoL_Pos, ADVANCE+NOERR+COUNT, 2) if (EM) { Search_Block(">%", Cur_Pos, EoL_Pos, ADVANCE+NOERR) // o.k. ? if (EM) { EoL } } Reg_Copy_Block(105, #101, Cur_Pos) // now search for that label in the .clx file File_Open(@104) Search("|@(105)", BEGIN+NOERR) if (Error_Match) { // ERROR, shouldn't happen! Dialog_Input_1(104,"`Error`, `No text to insert found. Bug!?.`", WORKAREA+CENTER,0,0) Buf_Switch(#103) return } Search("--", ADVANCE+COUNT, 2) #106=Num_Eval(SUPPRESS+ADVANCE) // number of lines Match("--", ADVANCE) Del_Block(BoL_Pos, Cur_Pos) Del_Line(1) //Reg_Copy_Block(106, Cur_Pos, Cur_Pos+#106, DELETE) // first version with number of bytes to take Reg_Copy(106, #106, DELETE) // to do: more safety! //Del_Line(1) File_Save(OK+NOMSG) // save and quit the .clx file #104=File_Size Buf_Quit(OK) if (#104==0) { File_Delete("|@(104)", OK) if (File_Exist("|@(104).bak")) { // o.k. or retain for safety? File_Delete("|@(104).bak", OK) } } Buf_Switch(#103) BoL Del_Line(1) Reg_Ins(106, BEGIN) // insert former cut-out text here Set_Visual_Line(#105+1) Line(1, NOERR) return