// PROJSAVE.VDM - Write VEDIT's current status out to files. // Implements {FILE, Project, Project close}. // // Originally by: Thomas C. Burt, Greenview Data, Inc. // 22-Feb-2005 // 14-Apr-2006 Christian Ziemski: don't save hard coded paths into .PRJ // added NOERR to Chdir // 15-Apr-2006 Pauli Lindgren: do not insert comment, no MRU // 13-Jan-2009 Pauli Lindgren: fix BROWSE option // // Requires: VEDIT 6.15 or later (due to syntax of Replace()). // // From VEDIT: Select {File, Project, Project close}. // // Description: Creates files "projname.prj" and "projname.dat" in the // user's project directory, typically "C:\VEDIT\PROJECTS". // // PROJNAME.PRJ holds the commands to restore the named edit-session. // PROJNAME.DAT holds the user cut & paste text registers 0-9, // system text registers 107-116, 119 and 123-126 (the // tools and user menus and current keyboard and // window layouts), unnamed edit buffers and buffer- // dependent configuration values. // // The session settings will be restored if internal value PROJ_RESTORE is set. // However, the project will always be "opened" and files loaded, as usual. // ////////////////////////////////////////////////////////////////////////////// // // Text Register Usage // // 0 Scratch: hold buffer dependent configuration parameters // 1 Scratch: hold name of current edit file // 2 (End of command characters: ) // 120 List of pathnames belonging to the current project. // Each pathname is zero-byte terminated. // 121 Pathname of currently open project (projpathname.prj). // 122 Register this macro runs in // // Numeric Register Usage (0 - 29 are saved and restored) // // 0 Local scratch variable // 1 " " " // 2 " " " // 3 Status of active window when macro starts // 4 ID of active window when macro starts // 5 ID of T-Reg current macro is executing in // 6 ID of buffer for creating restoration cmds - "PROJNAME.PRJ" // 7 ID of active edit buffer at start of this macro // 8 Current zoom status for editing windows // 10 ID of current buffer/register (working index) // 11 Flag when saving buffer dependent configuration variables // 12 Flag returned by SaveEnv() for ProjSaveAs() and ProjSave(): // 7 for ProjSaveAs() and ProjSave() to prevent emptying "kept" // unnamed edit buffers; 0 for ProjSave(0) to allow the emptying // 30 Current edit position // 50 Current length of edit-session-saving file - "PROJNAME.DAT" // 51 Length of text register being saved // 130 Flag from Save_Env() ProjSave/As() running; (temp at start; put into #12) // 131 Active buffer ID at startup (temporary at start; put into #7) // 132 ID of work buffer (temporary at start; put into #6) // 133 ID of current window (temporary at start; put into #4) // //**************************************************************************** // if ( Macro_Num == 122 ) { // (Don't want message when RUNSHELL'ng) Message("Saving project...",STATLINE) } #130 = Save_Env(5) // Inform VEDIT that a project's state is to be saved // Save flag that ProjSave/As() may be running #131 = Buf_Num // ID of active edit buffer at inception #132 = Buf_Free(EXTRA) // ID of edit-session restoration work buffer #133 = Win_Num // // Enable following line as debugging aid // // if (WSTAT($)<0){WR($,4,BOTTOM)};WS($);Update() ? // // Handle unnamed buffers. // Num_Push(0,9) Reg_Push(1,2) #9 = Buf_Total for (#0=0;#0<#9;#0++) { #1 = Buf_Next if (!Is_Open_Write && File_Size > 0 ) { Update() #2 = DI1(1,"`Closing Project`, `One or more buffers contain text but do not have a filename. You can save this buffer into the project, or also save it with a filename. Or you can abandon this buffer.`, `.cSave ?`, `\[Keep] Save buffer as-is in the project.`, `\[Save as...] Save buffer in a file, and save in the project.`, `\[Abandon] Discard the buffer contents, permanently.`, `[&Keep]`, `[&Save as ...]`, `[&Abandon]`",APP+CENTER,0,0) // // Treat as Keep. // So, for #2 == 0 || #2 == 1, nothing to do, here. // if (#2 == 2) { #3 = Get_Filename(2,"*.*") if (#3>3) { File_Save_As(@(2),NOMSG) } } if (#2 == 3 ) { Buf_Quit(OK+DELETE) } } Buf_Switch(#1,ATTACH) } Reg_Pop(1,2) Num_Pop(0,9) // // Delete any non-Command-mode reserved windows. // if (Win_Reserved_Bottom && Win_Reserved_Bottom_ID != '$'+128) { Win_Delete(Win_Reserved_Bottom_ID) } if (Win_Reserved_Top && Win_Reserved_Top_ID != '$'+128) { Win_Delete(Win_Reserved_Top_ID) } if (Win_Total==0) { Screen_Init() } // Need at least one window ////////////////////////////////////////////////////////////////// // // // Save to .PRJ File // // // ////////////////////////////////////////////////////////////////// // // Create the .PRJ file in a temporary work buffer. // if (#132<0) { // If all temporary buffers are in use #132 = XBUF1 // Use Extra_Buffer_1 Buf_Switch(#132) // Switch to it Buf_Quit(OK) // And empty/close it } Buf_Switch(#132,EXTRA) // Create work buffer as normal edit buffer // // Setup T-Reg[121] with the project pathname. // RS(121,Proj_Current) // i.e., projdriv:\projpath\proj.PRJ if (RSize(121)==0) { break_out(EXTRA) } File_Open_Write(@(121),SUPPRESS+FORCE+OVERWRITE) Begin_Of_File() // Erase any former macro commands Del_Char(ALL) // Better safe than sorry // // Save current project. // Reg_Push(0,0) Reg_Set(0,Proj_Current) if (Reg_Size(0)>0) { // // Proj_Add("filename"), for all project filenames. // #122 = #132 + 1 if (#122 > XBUF4) { #122=XBUF1 } BS(#122,EXTRA+NOEVENT) Reg_Ins(120,BEGIN) while (Search("|0",NOERR)) { Del_Char(1) rcb(0,BOB_Pos,Cur_Pos,DELETE) bs(#132) IT('Proj_Add("') Reg_Ins(0) IT('")') IN() bs(#122,EXTRA+NOEVENT) } Buf_Quit(OK) Buf_Switch(#132) Reg_Empty(0) } Reg_Pop(0,0) // // Open conditional restore clause. // Ins_Text("if (PROJ_RESTORE==0) { return }") IN() Ins_Text("if (PROJ_RESTORE>=2) ") Ins_Char(0x7B) // Opening brace IN() // // First, save some numeric variables, as in edit-session-restore. // Format is: #r = value // Out_Ins() // Capture console output in work buff Num_Display(0,9) // List all non-zero numregs from #0 - #9 // (98,99 must not be saved because of // complications for "locked-in" macros, // such as WildFile). Num_Display(107,116) // List all non-zero numregs from #107 - #116 // Must not include 118 used in STARTUP.VDM Num_Display(119,119) // Include #119 used in HTML.KEY Out_Ins(CLEAR) // Restore console output // // Now define some variables for our own use. // #3 = Win_Status(#133) // #3 = status of active window at startup #4 = #133 // #4 = Original window ID #5 = Macro_Num // #5 = currently executing T-Reg #6 = #132 // #6 = Edit-session restoration work buffer #7 = #131 // #7 = ID of active edit buffer at statup #8 = Is_Zoomed // #8 = Current zoom status for editing windows #11 = 0 // #11 will be set when saving buffer dependent values #12 = #130 // Bit 1 set when ProjSaveAs() or ProjSave(!0) is running if (#7 > Num_Edit_Bufs) { #7 = 1 } // Buffer-save loop doesn't (yet) // work with reserved buffers // // Save entire set of configuration parameters. // Buf_Switch(#6) // Switch to work buffer Out_Ins() // Divert console output into work buffer Config_Display(EXTRA+SHORT+SUPPRESS+GLOBAL) // Save complete "Config(...)" commands // Skip full description // Don't save hardware dependent parms // Save global buffer-dependent values Out_Ins(CLEAR) // Restore console output // IT("Config( E_INS_MODE,") // Add current insert/overstrike mode NI(Config(E_INS_MODE),LEFT|NOCR) IT(")") IN() // // Balance Match_Paren with closing brace. // Save_Pos() if (Search("Match|[_]Paren",REVERSE+NOERR)) { EOL() Ins_Text(" // Balance extra opening brace: ") Ins_Char(0x7D) } Restore_Pos() ////////////////////////////////////////////////////////////////// // // // Save to .DAT File // // // ////////////////////////////////////////////////////////////////// // // Save text registers et al. into project's ".dat" file. // First replace ".prj" with ".dat" in T-Reg[121]. // Save_Pos() Goto_Pos(BOB_Pos) Reg_Ins(121) // projdrive:\projpath\projname.PRJ Save_Pos() Replace("prj","dat",reverse) Restore_Pos() Reg_Copy_Block(121,BOB_Pos,Cur_Pos,DELETE) Restore_Pos() // // Create .DAT file, starting with T-Reg[0]. // File_Delete(@(121),OK+NOERR) // Ensure upcoming Reg_Save() doesn't // generate a prompt but does create a // new file, regardless of any existing // file or the size of T-Reg[0] Reg_Save(0,@(121),NOCONFIRM) // Create .dat file and save T-Reg[0] into it; // OK if empty #10 = 0 // Text Register[0] #50 = 0 // Current length of PROJNAM.DAT #51 = Reg_Size(#10) Call("RLP") // Reg_Load_Part(0,PROJNAM.dat,0,#51) // // Append remaining "cut & paste" T-Regs[1-9]. // for (#10 = 1; #10 < 10; #10++) { // Save cut & paste registers if ((#51=Reg_Size(#10)) > 0) { Reg_Save(#10,@(121),APPEND) // Append current text register contents to .DAT file Call("RLP") // Generate reload instruction in .PRJ file: // Reg_Load_Part(r,"fname",ofs,len) // 'r' = #10 // 'ofs' = #50 // 'len' = #51 // then update ofs += len } } ////////////////////////////////////////////////////////////////////////// // // // Note: T-Regs[97-106] are never to be saved due to possible later // // complications when a "locked-in" macro is improperly // // terminated such as for a syntax error, internal error, the // // user closing Vedit while WildFile is running, etc. // // // ////////////////////////////////////////////////////////////////////////// // // Save necessary system registers but don't save // this macro, keyboard or window structures (yet) or // T-Regs[117,118,120-122]. // Note: STARTUP.VDM runs in 122 // for (#10 = 107; #10 < 126; #10++) { if ((#10<>#5) && #10<>117 && #10<>118 && ((#10 < 120) || (#10 > 122))) { if ((#51=Reg_Size(#10)) > 0) { Reg_Save(#10,@(121),APPEND) Call("RLP") } } } ////////////////////////////////////////////////////////////////// // // // Finish saving to .PRJ file // // Save edited files (after confirmed prompt). // // Save unnamed edit buffer into .DAT file. // // // ////////////////////////////////////////////////////////////////// // // Free up Text Registers[0-3]. // Set up T-Reg[2] with end-of-command chars: closing parenthesis, newline. // Reg_Push(0,3) // Free up text registers 0 - 3 (Balance next paren... Reg_Set(2,") ") // Reg[2] = end of command chars // // Save # screen lines if DOS; only restore if DOS. // if (OS_Type == 2) { // If DOS ... IT("if(OS_Type==2 && Screen_Lines!=") NI(Screen_Lines,LEFT+NOCR) IT(") {Screen_Size(") // Screen_Size(Screen_Lines) NI(Screen_Lines,LEFT+NOCR) IT(")}") IN() } // // Close conditional restore clause. // Ins_Char(0x7D) // Closing brace IN() // // Save edit buffers. // Num_Push(20,29) // Free up 10 numeric registers Buf_Switch(#10=#7) // Get starting buffer # do { #30 = Cur_Pos Reg_Empty(1) for (#1=0; #1<10; #1++) { // for Text Markers[m], m = #1 = 0,9 #2 = 20 + #1 // Compute index #@2 = marker(#1) // Save markers in #20[m] } RCB(0,0,0,EXTRA) // T-Reg[0] = buffer dependent values #31 = Block_Begin #32 = Block_End #33 = Column_Begin #34 = Column_End #35 = Block_Mode #36 = #37 = 0 // Assume not editing disk sectors if (OS_Type == 2) { // If DOS... #36 = Is_Disk_Open // check for disk editing if (#36) { #37 = Disk_Open_Mode } // and get the disk-open mode } if (Is_Open_Write && #36==0) { Out_Reg(1) Name_Write(EXTRA+NOMSG+NOCR) Out_Reg(CLEAR) #37 = Browse_Mode Buf_Switch(#6) IT(`if (File_Exist(*"`) // )) Reg_Ins(1) IT(`"*,NOERR`) IC(0x29) // Closing paren IC(0x29) // Closing paren IC(0x7B) // Opening brace IN() } else { #51 = Reg_Size(#10+BUFFER) } Buf_Switch(#6) IT("Buf_Switch(") // Buf_Switch(r)) NI(#10,LEFT|NOCR) Reg_Ins(2) // Closing paren, newline // // DOS version only - If disk open // if (#36) { IT("Disk_Open('") // Disk_Open('d',mode)) IC('A'+#36-1) IT("',") NI(#37,LEFT|NOCR) Reg_Ins(2) // Closing paren, newline // // else if output "fn" // } else { if (Reg_Size(1)>0) { IT(/File_Open(*"/) // File_Open("fn")) Reg_Ins(1) // IT(/"*,MRU/) IT(/"*/) // PL: No MRU and fixed BROWSE option (comma instead of pipe) if (#37&0xC2) { IT(",BROWSE") } // If user wanted browse-only Reg_Ins(2) // Closing paren, newline if (#37&01) { IT("Browse_Mode(SET)") // If {EDIT, Browse} IN() } // // else save into .DAT file. // } else { #10 += BUFFER if ((#51=Reg_Size(#10)) > 0) { Reg_Save(#10,@(121),APPEND) Call("RLP") // Reg_Load_Part(r,"file",ofs,len) } #10 -= BUFFER }} Reg_Save(0,@(121),APPEND) // Save buffer dependent parameters Num_Push(10,10) #10 = 0 #51 = Reg_Size(0) #11 = 1 Call("RLP") // Reg_Load_Part(0,"fn",ofs,len,LOCAL) #11 = 0 Num_Pop(10,10) for (#1=0; #1<10; #1++) { // for i=0,9 #2 = 20 + #1 // #20[i] = Saved filemarkers if (#@2 >= 0) { // If filemarker[i] is defined IT("Set_Marker(") // Set_Marker[i,markpos]) NI(#1,LEFT|NOCR) IT(",") NI(#@2,LEFT|NOCR) Reg_Ins(2) // Closing paren, newline } } IT("Block_Begin(") // Block_Begin(#31)) NI(#31,LEFT|NOCR) Reg_Ins(2) // Closing paren, newline IT("Block_End(") // Block_End(#32)) NI(#32,LEFT|NOCR) Reg_Ins(2) IT("Column_Begin(") // Column_Begin(#33)) NI(#33,LEFT|NOCR) Reg_Ins(2) IT("Column_End(") // Column_End(#34)) NI(#34,LEFT|NOCR) Reg_Ins(2) IT("Block_Mode(") // Block_Mode(x)) NI(#35,LEFT|NOCR) Reg_Ins(2) IT("Goto_Pos(") // Goto_Pos(edit pos)) NI(#30,LEFT|NOCR) Reg_Ins(2) if (Reg_Size(1)>0){ IC(0x7D) IN() } Buf_Switch(#10) // Goto buffer just processed #10=Buf_Next() // // Empty unnamed buffers to avoid "Save-As" dialog later; but not for // ProjSave/As(), because the .DAT file is not reloaded... // ProjSave(0) overrides this to prevent subsequent redundant "SaveAs" dialog on close. // if (!Is_Open_Write && File_Size > 0 && !(#12&2)) { Buf_Empty(OK) } Buf_Switch(#10) // Goto next edited buffer } while (#10<>#7) // Until circled all the way around // // Open conditional restore clause. // BS(#6) Ins_Text("if (PROJ_RESTORE>=2) ") Ins_Char(0x7B) // Opening brace IN() // // Save current search/replace strings and search options. // if (SRD > 0) { Out_Ins() IT("SR_Set(") //) SRD(EXTRA) if (SRD > 1) { IT(",SET") } Reg_Ins(2) Out_Ins(CLEAR) #10 = Search_Options IT("Search_Options(") //) NI(#10,LEFT+NOCR) Reg_Ins(2) } // // Save current working directory. // BS(#6) // Redundant switch to work buffer IT("Chdir('") // Beginning of Chdir(cwd)) Out_Ins() // Capture console output in work buff Name_Dir(NOMSG|NOCR) // Capture current working dir name Out_Ins(CLEAR) // Restore console output IT("', NOERR") // CZ: NOERR added for USB stick usage Reg_Ins(2) // // Save window structures into .DAT file. // Only restore if same type (Win32, Win16, DOS) and version #. // #10 = 126 // ID of window structures #51 = Reg_Size(#10) Reg_Save(#10,@(121),APPEND) IT("if(OS_Type==") NI(OS_Type,LEFT+NOCR) IT(" && Is_Win32==") NI(Is_Win32,LEFT+NOCR) IT(" && Win_Struct_Size==") NI(Win_Struct_Size,LEFT+NOCR) IT(" && Version_Num==") NI(Version_Num,LEFT+NOCR) IT(") {") IN() Call("RLP") // Reg_Load_Part(126,...) IT("} else { Screen_Init(ATTACH) }") IN() // // Close conditional restore clause. // Ins_Char(0x7D) // Closing brace IN() // // If (main) buffer 1 currently closed, need to close it during restore. // if (Buf_Status(1)==-1) { IT("Buf_Switch(1) Buf_Close(NOMSG)") //Close buffer 1 IN() } // // Ensure start-up in original active buffer. // IT("Buf_Switch(") //) NI(#7,LEFT|NOCR) Reg_Ins(2) if (#3>0) { // Switch to original window and IT("Win_Switch(") //) attach it if it viewed an edit NI(#4,LEFT+NOCR) // buffer. (Handles case of multiple IT(",ATTACH") // windows into one edit buffer) Reg_Ins(2) } else { IT("Win_Switch(") //) NI(Buf_Org_Window(#7),LEFT+NOCR) IT(",ATTACH") Reg_Ins(2) } // // Open conditional restore clause. // Ins_Text("if (PROJ_RESTORE>=2) ") Ins_Char(0x7B) // Opening brace IN() // // Cause screen to be redrawn. // IT("Screen_Reset()") IN() // // Rezoom window, if needed. // if (#8<>0) { IT("Update()") // Screen doesn't update otherwise IN() IT("Win_Zoom()") // Zoom the window IN() } // // Close conditional restore clause. // Ins_Char(0x7D) // Closing brace IN() // // Cleanup for restoration macro. // IT("Return(1,DELETE)") // Discard Project restoring macro IN() //CZ insert ----------------------------------------- // Replace any hardcoded // - project directory with variable PROJECTS // - Vedit home directory (e.g. C:\VEDIT\) with variable HOME Replace("$(PROJECTS)\\","|(PROJECTS)\\", REGEXP+BEGIN+ALL+NOERR) Replace("$(HOME)\\","|(HOME)\\", REGEXP+BEGIN+ALL+NOERR) //CZ end -- ----------------------------------------- File_Close(NOMSG+SUPPRESS) // Close PROJNAM.PRJ Buf_Quit(OK) // Release extra buffer // // Cleanup for this macro. // Num_Pop(20,29) Reg_Pop(0,3) Save_Env(CLEAR) // Inform VEDIT to finish saving edit-session Buf_Switch(#7) // Switch back to original active buffer Return() // //**************************************************************************** // // RLP - Generate command 'Reg_Load_Part(r,"PROJNAME.dat",ofs,len,NOERR[+LOCAL])' // in work buffer, where 'r' = #10, 'ofs' = #50, 'len' = #51; // then update ofs+=len. // (#11 sets "LOCAL" when saving buffer dependent configuration values.) // :RLP: IT("Reg_Load_Part(") //) NI(#10,LEFT|NOCR) IT(`,"`) Reg_Ins(121) IT(`",`) NI(#50,LEFT|NOCR) IT(",") NI(#51,LEFT|NOCR) iT(",NOERR") if (#11) { IT("+LOCAL") } //( IT(")") IN() #50 += #51 Return()