// // ClipCatch.vdm Christian Ziemski 29.09.2003 // 17.04.2004 // 02.01.2006 // // Observe and get the Windows Clipboard in an endless loop: // // When the ClipBoard is no longer empty, the text from there is inserted // into the current buffer at cursor position and the ClipBoard is emptied. // // You can stop the loop with Ctrl-C. // // So you can collect text snippets from here and there in a single place. // // It is possible to have a routine/macro for reformatting the inserted parts. // See below for options (#56 and following). // // If enabled via dialog (recommended) the macro saves the collected text // after a configurable number of pastes. // //------------------------------------------------------------------------- // // This macro requires VEDIT 6.12 due to the enhanced Clip_Copy_Block(). // //------------------------------------------------------------------------- // // #49 undo config value // #50 parent's locked-in macro (0=none) // #51 Win_Num // #52 original buffer // #53 temp buffer // #54 flag: s.th. inserted? // #55 VM ?? // --- // #56 flag for inserting NewLine(s) // #57 flags for reformating pastes; see below (checkboxes) // ... // #65 interval for auto save after n pastes // #66 counter for pastes // --- // // @54 locked-in macro // @55 commands from external macro (default: CLIPCATCHX.VDM (X=extension)) // --- // @56 name of the external extension macro // @57 quoting character(s) // @58 auto save interval // --- // //------------------------------------------------------------------------- // // to do: // save temp. buffer to temp file (for big sizes)? Now handled with auto save feature // error handling when T-Reg full // check Undo handling (currently: Undo is disabled during macro run) // add commandline to dialog ? // call a macro at end ? // another default macro extension name ? // // check sometimes "hanging" Alt-key when taskswitching via kbd (not related to this macro only) // check/fix returning to command mode or parent macro! (should be fixed by vpw.exe 6.15) // //------------------------------------------------------------------------- Num_Push(49,66) // save used registers Reg_Push(54,58) // default settings; can be changed in the Dialog_Input_1 when running #56 = 2 // 1 = insert exactly like copied into the ClipBoard // 2 = let every paste begin at Begin_Of_Line // 3 = insert an empty line before each paste // 4 = insert an empty line and a line with current timestamp // before each paste #57 = 0 // 1 = call the subroutine USRFORMAT below after every paste #58 = 0 // 1 = call the external macro named in DI1() // (default: "CLIPCATCHX.VDM") after every paste #59 = 0 // 1 = remove empty lines from every pasted block, // but put an empty line after a block // (forces surrounding empty lines like #56=3) #60 = 0 // 1 = replace all whitespace in the pasted block with one space #61 = 0 // 1 = insert quote-character(s) (default: "> ") in front of // every pasted line // (forces at least newlines like #56=2 but honors #56>2) Reg_Set(56, "CLIPCATCHX.VDM") // external macro for formatting Reg_Set(57, "> ") // quoting characters Reg_Set(58, "5") // auto save interval //-------------------------------------------------------------------------- Reg_Empty(103) // control the focus in DI1() Reg_Set(104, ".i") // repeat (ALL) { #103 = Dialog_Input_1(56, "`CLIPCATCH`, `This macro watches the ClipBoard and retrieves all text from there, pasting it into the current buffer.`, `Every paste is done`, `.g() simply at cursor position`, `() beginning at a new line`, `() preceeded with an empty line`, `() preceeded with an empty line and a time stamp`, `with optional formatting by`, `.g[] calling subroutine USRFORMAT`, `[] calling external macro named:`, `|@(103)?? `, `.g[] removing empty lines and building a paragraph`, `[] compressing whitespace to single space`, `[] quoting all lines with the character(s):`, `?? `, `The buffer is saved to disk every n pastes (0=disable):`, `?? `, `|@(104)[&Ok]`,`[&Cancel]`",SET+APP+CENTER,0,0) if (#103 != 1) { Reg_Pop(54,58) // restore text registers Num_Pop(49,66) // restore numerical registers return } if (#58 == 1) { // check existence of choosen file if (Reg_Size(56) > 0) { Reg_Load(55, "|@(56)", NOERR+EXTRA) if (! Error_Flag) { // if file found: leave loop break } } Reg_Set(103, ".i") // on error: set focus to input box Reg_Empty(104) // continue // and repeat loop } break } #65=Num_Eval_Reg(58, SUPPRESS) // to do: some error checking if (#65 > 0) { if (! Is_Open_Write) { #103=Dialog_Input_1(56, "`CLIPCATCH`, `The buffer has not assigned filename yet.`, `Please save it in the following dialog.`, `[&Ok]`,`[&Cancel]`",SET+APP+CENTER,0,0) if (#103 != 1) { Reg_Pop(54,58) // restore text registers Num_Pop(49,66) // restore numerical registers return } Set_Altered_Flag(1) File_Save(NOMSG) } } Reg_Empty(103) Reg_Empty(104) #49 = Config(U_E_UNDO, 0) // disable undo, but save original value #55 = VM() // to do: ? #54 = 0 // clear flag for: s.th. inserted // set Locked-in macro. It will be executed on ending the loop with Ctrl-C #50 = Reg_Lock_Macro // save original locked-in macro config Reg_Set(54, " Reg_Lock_Macro(CLEAR) // disable locked-in macro Reg_Pop(54,58) // restore text registers if ((#56 > 2) && (#54 == 1)) { // end paste with an empty divider line if (! At_EoL) { // (but only if s.th. was inserted) Ins_Newline() } Ins_Newline() } Config(U_E_UNDO, #49) // restore undo Block_Begin(CLEAR) #103 = #50 // store values temporary in case the old locked in macro jumps in ... #104 = #55 Num_Pop(49,66) // restore numerical registers if (#103 != 0) { // there has been an original locked-in macro Visual_Macro(CLEAR) Reg_Lock_Macro(#103) // set original locked-in macro again } else { Visual_Macro(#104) // to do: how to return to cmd prompt if started from there??? // online help error: Break_Out(EXTRA) does a Visual_Macro(SET+NOMSG) // but SET+NOMSG is converted to a NOMSG(8) in fact } Return ") Visual_Macro(CLEAR) Reg_Lock_Macro(54) #51 = Win_Num // save original values #52 = Buf_Num #53 = Buf_Free(EXTRA) // working buffer for text from clipboard #66 = 0 // increase paste counter if (#59) { #56 = Max(2, #56) } // in this case: force at least Newline if (#60) { #56 = Max(3, #56) } // in this case: force at least empty line Repeat (ALL) { Win_Switch(STATLINE) // The message must be inside the loop Win_Color(79) // otherwise an overlapping window would Win_EoL // delete the message. Message(" Catching contents of the ClipBoard and inserting it here. Quit with ") Win_Switch(#51) // back to original window Buf_Switch(#53) // switch to temp buffer Buf_Empty(OK) Clip_Ins() // insert clipboard here if (File_Size() > 0) { // if there was s.th. in the clipboard //------------------------------------------------ #66++ // increase paste counter if (#57) { // call the subroutine USRFORMAT below BoF Call("USRFORMAT") } if (#58) { // call the commands found in external macro (if any) // Note: // The called macro MUST NOT change T-Reg 54-58, Num_Reg 49-67! // (Or if it has to: It should save the values and restore them at end.) // It operates on the temp. buffer containing the current paste. BoF Call(55) } if (#59) { // remove empty lines from every pasted block BoF Replace_Block("|<|X", "", 0, File_Size, BEGIN+ALL+NOERR) EoF if (! At_BoL) { // but put an empty line after a paste Ins_Newline(1) } } if (#60) { // replace all whitespace in the pasted block with one space BoF Replace("|W", " ", BEGIN+ALL+NOERR) } if (#61) { // insert quote-character(s) in front of every pasted line BoF while(! At_EoF) { BoL Reg_Ins(57) // insert quote character(s) Line(1, NOERR+ERRBREAK) } } //------------------------------------------------ Buf_Switch(#52) // back to original buffer if (#56 > 1) { // special treatments if (! At_BoL) { Ins_Newline() // let every paste begin at Begin_Of_Line } if (#56 == 3) { // begin every paste with an empty divider line Ins_Newline() } if (#56 == 4) { // insert timestamp Ins_Newline() Out_Ins() Message("# ") Date(LOCAL+NOMSG+NOCR) Message(" ") Time(NOMSG) Out_Ins(CLEAR) } } #54 = 1 // set flag for "s.th. inserted" #103 = Cur_Pos // remember begin of insertion Reg_Ins(#53+BUFFER) // insert (reformatted) clipboard and advance cursor past insert Block_Begin(#103) // mark inserted block for optical reference Block_End(Cur_Pos) Clip_Copy_Block(0,0) // empty clipboard for next loop Update if (#65 && (#66 >= #65)) { File_Save(OK+NOMSG) #66=0 } } Buf_Switch(#53) // temp. buffer Buf_Quit(OK) // close temp. buffer Buf_Switch(#52) // back to original buffer Sleep(3) } return // just in case ... //====================================================== // // This subroutine can be filled with life by the user. // It operates on the temp. buffer containing the current paste. // Note: // This macro MUST NOT change T-Reg 54-58, Num_Reg 49-66! // (Or if it has to: It can save the values and restore them at end.) // :USRFORMAT: // example: // All whitespace is replaced by an underscore // BoF Replace("|W", "_", BEGIN+ALL+NOERR) return