/************************************************************************** /************************************************************************** File: 'tse_tip1.txt Tuesday - November 9, 1993 Started 5-13-93 for small bits of info and/or source code. TSE (The SemWare Editor, a.k.a. TESSIE) /************************************************************************** /************************************************************************** =========================================================================== Date: 05-11-93 From: EBERHART ADAM Unmarking text with the mouse button: --------------------------------------------------------------------------- I just tried this (changed mLeftBtn from tse.s): /************************************************************************** proc mLeftBtn() if not MouseMarking(_INCLUSIVE_) and not ProcessHotSpot() MainMenu() elseif not iscursorinblock() UnMarkBlock() endif end /************************************************************************** Thursday - May 13, 1993 /************************************************************************** TSE change to *.key to have CTRL-Y move cursor position to BegLine. Change DelLine() to DelLine() BegLine() then recompile. While having two commands on the same will currently work, it is not guaranteed to always be implemented. So instead of the double command define a procedure in 'tse.s' proc YankLine() DelLine() and then define the key: YankLine() BegLine() end /************************************************************************** =========================================================================== Date: 05-13-93 From: RAY ASBURY Subj: WordRight/Left TSE Macro --------------------------------------------------------------------------- If you've noticed that WordLeft() and WordRight() stop on the beginning and the end of lines, and don't like this behavior, here's a simple replacement for these commands which skips over the beginning and the ending of lines: CONSTANT kPREVIOUS_WORD = FALSE, kNEXT_WORD = TRUE INTEGER PROC mGotoWord1(INTEGER whichOne) IF (whichOne ==kNEXT_WORD) Return(WordRight()) ENDIF Return(WordLeft()) END mGoToWord1 INTEGER PROC mGotoWord2(INTEGER whichOne) WHILE ( (mGotoWord1(whichOne)) AND (NOT IsWord()) ) whichOne = whichOne ENDWHILE IF (IsWord()) Return(TRUE) ENDIF Return(FALSE) END mGotoWord2 PROC mGotoWord(INTEGER whichOne) PushPosition() IF (mGotoWord1(whichOne)) IF (NOT IsWord()) IF (NOT mGotoWord2(whichOne)) PopPosition() Return() ENDIF ENDIF ELSE PopPosition() Return() ENDIF KillPosition() END mGotoWord To use this, simply add this to your TSE.S file and replace direct calls of WordLeft() with mGotoWord(kPREVIOUS_WORD) and of WordRight() with mGotoWord(kNEXT_WORD). Currently, if a word is not found, the cursor won't move. If, however, you would prefer that it go to either the beginning of the file, or the end (depending on the direction you are searching), use this version of mGotoWord(): PROC mGotoWord(INTEGER whichOne) IF (mGotoWord1(whichOne)) IF (NOT IsWord()) mGotoWord2(whichOne) ENDIF ENDIF END mGotoWord I hope you find this useful, "Buddy" E. Ray Asbury, Jr. Team TSE /************************************************************************** =========================================================================== Date: 05-13-93 From: KYLE WATKINS Subj: TSRGEP problem that hit line# is shifted down one line Reference: Next item also has a solution for a TSRGREP problem --------------------------------------------------------------------------- -> markline() <---- CHANGE TO CHARACTER OR COLUMN -> GotoBufferId(oid) -> BegLine() -> if linenumbers -> InsertText(Format(linenumber:lndigits) + ' ³ -> -> endif -> copyblock() <---- Then the copy block will be on same line instead of below (or above) ->But what is happening is the text associated with the hit line# is ->shifted down one line. Hi David, If you change to a block other than LineBlock, then CopyBlock will use the same line. ---- Kyle /************************************************************************** =========================================================================== Date: 05-13-93 From: DAVID MARCUS Subj: TSGREP Solution --------------------------------------------------------------------------- I have determined the problem and solution causing your TSGREP hit list to be so erratic; it is the setting for your InsertLineBlocksAbove configuration option. You can either set it to ON or TRUE, or make these three small changes to TSGREP: 1. Add this line as the first line under the global INTEGER declarations [line ~82]: ILBA, // holds InsertLineAbove value 2. Add this line as the first line in proc MAIN() [line ~260]: ILBA = Set(InsertLineBlocksAbove, ON) 3. In proc end_processing(), add this line as the first line under /* Reset editor */ [line ~723]: Set(InsertLineBlocksAbove, ILBA) *** Please let me know if this does not work. *** /************************************************************************** =========================================================================== Date: 05-13-93 From: KYLE WATKINS Subj: Remove blank lines in a text file --------------------------------------------------------------------------- The following will delete all blank lines in a file, even if the line contains just tab and space characters. proc DelBlankLine() pushposition() //save your position begfile() //remove this if you want to start at the //current pos. and replace it with begline() while LFind("[\d009\d032]*$","X") //Find "Beginning of line followed //by 0 or more tabs or spaces //followed by EOL". Use of LFind //instead of Find so that the display //does not update with each find. message(currline()," of ",numlines()) //just for information in case //it's a large file delline() endwhile message("DONE!") //So you know it's done when //no blank lines are in file popposition() //return to your original position end /************************************************************************** =========================================================================== Date: 05-14-93 From: SAMMY MITCHELL --------------------------------------------------------------------------- > I am trying to use a command macro I had for QEdit that would allow > me to abandon a file and restart the edit with the last saved copy. I > seem to want a variable into which I can place the CURRENT FILE NAME, > but I don't see this. How about this: // quit the current file (even if changed) and reload it from disk proc ReloadCurrentFile() // version 1 string fn[65] = CurrFilename() // save the name AbandonFile() // quit the file EditFile(fn) // and reload it end Or, if you prefer: // quit the current file (allow saving first) and reload it from disk proc ReloadCurrentFile() // version 2, safer string fn[65] = CurrFilename() // save the name if isChanged() // if changed allow saving case YesNo("Save Changes?") when 0, 3 return() when 1 if not SaveFile() return () endif endcase endif AbandonFile() EditFile(fn) end And finally, a version that is more like QEdits "NewFile", which will allow you to optionally reload the current file, or just load another file after quitting the current file: // quit the current file (allow saving first) and load another proc NewFile() string fn[65] = CurrFilename() // save the name if isChanged() // if changed allow saving case YesNo("Save Changes?") when 0, 3 return() when 1 if not SaveFile() return () endif endcase endif AbandonFile() AddHistoryStr(fn, _EDIT_HISTORY_) EditFile() end /************************************************************************** =========================================================================== Date: 05-09-93 From: KYLE WATKINS Subj: MOUSE SELECTED TEXT --------------------------------------------------------------------------- -> editors, when you click again on the screen the highlighted text -> doesn't go away. This is very annoying. With TSE you must click and -> then drag some to get the previous selected text to disapear. With You can issue unmarkblock() to get rid of the marked block (our default ) instead of trying to remark a block to get rid of the first block. When you "click and drag" the mouse, you are actually using the markchar() command to mark a character block. If you would rather the marked block be unmarked each time you press the left mouse button whenever you are in an "editing portion" of the screen, you can make the following adjustments to the mLeftBtn() procedure that is near the bottom of the tse.s file (or within the ".s" file you used to configure the editor): proc mLeftBtn() if mousehotspot() == _mouse_marking_ // add this line unmarkblock() // add this line endif // add this line if not ProcessHotSpot() MainMenu() endif end This will unmark any block if you press the left mouse button and you are within the editing window. If you are outside the editing window, the block will remain marked. If you want to unmark the block no matter where the mouse cursor is, modify the mLeftBtn() procedure to begin with unmarkblock() instead of the three lines I show. When you use the mouse with QEdit by first loading qm.com, mouse movements are translated to the appropriate cursor commands depending on the direction of mouse movement and are placed in the keyboard buffer. That is why the movement of the mouse caused the cursor to move. One drawback to this is that the cursor will move whenever the mouse is moved, which means if you bump the mouse, your cursor moves. If you want to do this in TSE, it should be possible with a macro if you take all of the window borders into account. Kyle Watkins (SemWare Technical Support) /************************************************************************** =========================================================================== Date: 05-15-93 From: BOB CAMPBELL Subj: Re: TSE not finding macro --------------------------------------------------------------------------- > Here's how I got around this problem. In your > TSE.S file's WhenLoaded(), add the following > AddHistoryStr(Query(MacPath), _ExecMacro_History_) > AddHistoryStr("", _ExecMacro_History_) Thanks Ray. It took me a while to figure out how to use your routine but I've got it installed now and it's even better than what I was asking for! /************************************************************************** =========================================================================== Date: 05-17-93 From: KYLE WATKINS Subj: BLOCK TABBING --------------------------------------------------------------------------- Question: In Qedit, I can highlight a block of text, move it, and then if the indent happens to be further in that it was originally, I can place the cursor at the beginning of a line of text and hit tab, and the whole block is tabbed over. Hi John, If you are using the tse.s file, there is a macro called mShiftBlock(). This macro is used with the default , , and key assignments. Modify your tab keys to be: for use: iif(isCursorInBlock(),mShiftBlock(-Query(TabWidth)),TabLeft()) for use: iif(isCursorInBlock(),mShiftBlock(Query(TabWidth)),TabRight()) If your cursor is not in a marked block, you will get the normal tableft() and tabright(), otherwise the block will be shifted by the current tab width. Kyle Watkins (STS) /************************************************************************** =========================================================================== Date: 05-17-93 From: RAY ASBURY Subj: TSE macro help --------------------------------------------------------------------------- Spend some time just playing around with regular expressions - the power of them is incredible. Although they've been around a long time, I'd never used them until I started alpha testing TSE. I could hardly get along without them now. BTW - here's three searches that I use a lot and are extremely handy: Find("^$", "X") - finds blank lines Find("^.@", "X") - finds all lines Find("^.#", "X") - finds all non-blank lines I've put these into the find & replace histories so that I can simply Up() to them. If you want to do the same thing, just add something like the following to your TSE.S's WhenLoaded() macro: AddHistoryStr("^{.@}", _Find_History_) AddHistoryStr("^{.#}", _Find_History_) AddHistoryStr("", _Find_History_) ÚÄÄÄ<<< BOB CAMPBELL >>>ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ ³I also discovered (quite by accident) while working with the search function³ ³that the search strings are saved to a buffer for recall by using the ³ ³CursorUp and CursorDown keys. ³ ÀÄÄÄ>>> RAY ASBURY <<<ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ These are called "histories". A lot of the dialog prompt boxes within TSE have them. Check out pages 24-5 in the User's Guide. Did you know that you can mark text, and then use the Copy() command to paste the marked text into most dialog boxes? ÚÄÄÄ<<< BOB CAMPBELL >>>ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ ³I'm sure you know about this feature but I wanted to mention it and your³ ³search string above because it offered a valuable example for learning. ³ ÀÄÄÄ>>> RAY ASBURY <<<ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ My humility demands that I let you know it took a couple of hours to come up with that macro. Although putting the search string together wasn't bad, how to handle some of the other stuff wasn't easily apparent. Thanks for the compliments, but I suspect you'll be teaching me things before too long. "Buddy" E. Ray Asbury, Jr. Team TSE /************************************************************************** =========================================================================== Date: 05-18-93 fFrom: KYLE WATKINS Subj: Regular Expressions --------------------------------------------------------------------------- -> What does the stuff inside the quotes ("^[\d009\d032]*$") mean and is -> there a place I can find this information in the manual? Hi Paul, Pages 75-82 in the "User's Guide" explains the use of Regular expressions (the "X" for the Find options means to use regular eXpressions). The ^ means to anchor the search to the beginning of the line. The [\d009\d032] denotes the set of the tab character (ASCII decimal 9) and the space character (ASCII decimal 32). The * means zero or more occurences of the preceding character. In this case the preceding character is a "set" of characters (the tab and the space) that are valid candidates for satisfying the condition. The $ means the end of the line. Kyle Watkins (SemWare Technical Support) /************************************************************************** =========================================================================== Date: 05-18-93 From: KYLE WATKINS Subj: KILLFILE --------------------------------------------------------------------------- Try the following and see if it is what you want: proc mKillFile() //get currentfilename less ext and add .bak as ext. string filename[65]=SplitPath(CurrFilename(),_DRIVE_|_PATH_|_NAME_)+".bak" EraseDiskFile(filename) //erase the currentfile with .bak ext from disk killfile() //erase currentfile from disk abandonfile() //abandon the current file updatedisplay(_statusline_refresh_) //clears "erase disk file" message editfile("-a- *.*") // give a pickdir of *.* in the current dir end mKillFile() Kyle Watkins (STS) /************************************************************************** =========================================================================== Date: 05-18-93 From: RICHARD BLACKBURN Subj: TSE Macro To Run KBD Macr --------------------------------------------------------------------------- ÚÄ ³Richard, have you had a chance to develop a TSE macro to load and run ³keyboard macros from the command line yet? ÀÄ Yes, I wanted to test it for a while, before posting it :) You will need to add the following to your WhenLoaded() in your TSE.S file: string cmdline[128] = Query(DosCmdLine), temp[128] = cmdline, macrofile[62] = '' integer s1 = 0, s2 = 0 Upper(temp) s1 = Pos('-U', temp) if s1 == 1 or temp[s1 - 1] == ' ' macrofile = SubStr(cmdline, s1 + 2, sizeof(macrofile)) s2 = Pos(' ', macrofile) if s2 macrofile = SubStr(macrofile, 1, s2) endif LoadKeyMacro(macrofile) cmdline = iif(s1 == 1, '', SubStr(cmdline, 1, s1)) + iif(s2 == 0, '', SubStr(cmdline, s1 + 2 + s2, sizeof(cmdline))) Set(DosCmdLine, cmdline) endif Once you have added this, be sure to burn it in using SC.EXE. I picked -U[KbdMacroName] as the command line switch. You can change it to whatever you prefer by chnaging the Pos('-U', temp) to look for the character you want to use. Richard Blackburn (SemWare Technical Support) /************************************************************************** =========================================================================== Date: 05-18-93 From: ALAN DAWSON Subj: DRAGGING TEXT --------------------------------------------------------------------------- In the spirit of macros sharing: I'm not a mouse kinda guy, but dragging text is sure one of the neat things about rodents and GUIs. Here are a couple of keyboard-tied macros for TSE to let you drag text up and down a file until you reach the point you want to "drop" it. I don't have any doubt the macros can be improved, either. They're quick and dirty and work great for me. I have these tied to my Ctrl-ArrrowUp and Ctrl-ArrowDown keys. What they do is this: If a block is marked, drag it in the direction of the pressed key. If a block is NOT marked, mark the current line and drag that. Put the following keys in your TSE.KEY file, compile the macros and put them in the \tse\mac file, and burn a new copy of E.EXE ExecMacro ("linedown") ExecMacro ("lineup") ----------- lineup.s starts --------- proc Main () If IsBlockMarked () <1 MarkLine () Else MoveBlock () GotoBlockBegin () BegLine () UP () EndIf End ----------- linedown.s starts --------- proc Main () If IsBlockMarked () <1 BegLine () MarkChar () Down () MarkChar () Down () Else MoveBlock () GotoBlockEnd () BegLine () Down () EndIf End /************************************************************************** =========================================================================== Date: 05-21-93 From: ALAN KELLEY Subj: CUT with _NO_FILL_ --------------------------------------------------------------------------- I have a suggestion for an additional function you might consider if you ever update it. I use a Cut with _NO_FILL_ a lot when working on menus or columnar data (or whenever I don't want anything else to move from where it's at after a block cut). It's what I would call the compliment to the Paste(_OVERWRITE_) command. In fact I've changed my key def's around a bit (see below) so my cut_with_no_fill_macro could be assigned to to compliment . Paste() Cut() Copy() Cut(_APPEND_) Copy(_APPEND_) Paste(_OVERWRITE_) myCutNoFill() I'm not much of a programmer, but to give you an idea of what I'm talking about, here is the macro I came up with. It seems to work with any kind of block you throw at it. proc myCutNoFill() PushBlock() Copy() PopBlock() FillBlock(" ") GotoBlockBegin() UnMarkBlock() end /************************************************************************** =========================================================================== Date: 05-19-93 From: DAVID WALKER Subj: Intercepting key input --------------------------------------------------------------------------- ÕÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ͸ ³It would help to see the macro as it stands, but what I think you ³are looking for is this looping construct (it's fresh in my mind ³'cause SemWare just told me how ): ³ ³KeyDef Name() ³ ³ ³End ³ ³PROC you_are_working_on() ³ ³ Stuff you are working on.... ³ ³ Enable(Name) ³ Process() ³ Disable(Name) ³ ³ More stuff ³ ³END ÔÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ; You're right, Mel. That's exactly what I was looking for. Here's my own version, from the current incarnation of my "copy block from this window to the other window" macro: /* CpyBlk.S Macro to mark a block, then copy it to the next window (at the end). Assumes two windows open on the screen [next version should check for that]. */ keydef wMarkSet EndProcess() EndProcess() end integer proc wMark() // get keys until or pressed // return TRUE if was pressed, // FALSE if was pressed Message("Mark block to copy, then ") Enable(wMarkSet) Process() // accept everything until EndProcess() executed Disable(wMarkSet) return(Query(key) == ) // 'key' returns the last key pressed end proc wCopyBlock() MarkStream() // start marking, then switch to Process() if wMark() // if was pressed, Copy() // copy the marked block to the clipboard NextWindow() // Switch to the 'other' window Paste() // Paste the block from the clipboard UpdateDisplay() // Make sure the pasted block is visible Endfile() // Move to the end of the file NextWindow() // Back to where we started else UnMarkBlock() // if was pressed, never mind endif end wCopyBlock() /************************************************************************** =========================================================================== Date: 05-22-93 From: DAVID MARCUS Subj: mGetClipboardBlockType() --------------------------------------------------------------------------- /************************************************************************** GET_CLIPBOARD_BLOCK_TYPE Determines the type of block that was copied to the current clipboard. Returns same integer values as isBLockMarked() -- see TSE doc for details. D. Marcus -- 5-21-93 /************************************************************************** integer proc get_clipboard_block_type() integer tid, // temp buffer blocktype PushPosition() PushBlock() tid=CreateTempBuffer() Paste() blocktype = IsBlockMarked() AbandonFile(tid) PopBlock() PopPosition() return(blocktype) end /************************************************************************** ========================================================================== Date: 05-24-93 From: SAMMY MITCHELL Subj: TSE CONFIGURATIONS - switching between two configurations --------------------------------------------------------------------------- > I would really like to know how to use two different configurations in > TSE. I currently have TSE set with no wordwrap or autoindent, just what > I want when I'm writing batch files. But when I write mail, I like > those things on. Is there anyway I can have my standard setting on most > of the time, but when I'm editing mail use my other settings? If you have specific file extensions that can identify each of these conditions, then it is fairly easy to do what you ask. In the 'OnChangingFiles' macro in TSE.S, it contains a case statement based on the current extension. Say your mail stuff has an filename-extension of 'ml'. Changing the code to the following should give you what you want: from: language = FALSE cmode = FALSE case CurrExt() when ".s",".asm",".pas",".inc",".prg" language = TRUE when ".c",".h",".cpp",".hpp" language = TRUE cmode = TRUE endcase to: // assumes mail filename-extension is ".ml" Set(WordWrap, off) Set(AutoIndent, off) language = FALSE cmode = FALSE case CurrExt() when ".s",".asm",".pas",".inc",".prg" language = TRUE when ".c",".h",".cpp",".hpp" language = TRUE cmode = TRUE when ".ml" Set(WordWrap, on) Set(AutoIndent, on) endcase This will force WordWrap and AutoIndent off, everytime you change files, except if the file has an extension of '.ml', in which case these settings will be turned on. =========================================================================== Date: 05-25-93 From: MEL HULSE Subj: RepeatCommand deleting too much --------------------------------------------------------------------------- 1. If a string search fails, how do I get a repeated macro to abort. I use the repeat for 1000 times, but there are only 500 occurances in the file. It will keep deleting at the line where it fails, so I lose 500 too many lines. #INCLUDE this with a keybinding in TSE.S, compile ("sc -b \ui\tse") ...and use as the last command in your keyboard macro, run the macro then use RepeatCmd as in QEdit. PROC FindOut() If RepeatFind() Right() Else PurgeKeyMacro() EndIf END FindOut() If you want to use your keyboard macro again, be sure and save it as the above deletes the loaded copy in order to stop it. /************************************************************************** =========================================================================== Date: 05-25-93 From: MEL HULSE Subj: WhenLoaded Usage --------------------------------------------------------------------------- ÚÄo ³(Incidentally, why do you refer to them as WhenLoaded ³macros? They're not by chance tied into the WhenLoaded statement ³in TSE.S (and ALWAYS LOADED AND ACTIVE when the editor starts) are ³they?) ÀÄo That's it. Here's the relevant code: Proc WhenLoaded() integer cid = GetBufferId() /* ppp */ LoadMacro("c:\SE\macros\utility1") LoadMacro("c:\SE\macros\utility2") LoadMacro("c:\SE\macros\utility3") Set(MacPath, "c:\se\macros\") // Default Path SetGlobalStr("Ruler", "4") Set(MouseRepeatDelay, Val(GetEnvStr("MOUSERAT"))) // See below * pick_buffer = CreateTempBuffer() GotoBufferId(cid) Set(CurrVideoMode,_28_LINES_) Hook(_ON_CHANGING_FILES_, OnChangingFiles) Hook(_ON_FIRST_EDIT_, OnFirstEdit) End WhenLoaded /************************************************************************** =========================================================================== Date: 05-23-93 From: JACK HAZLEHURST Subj: DelToBOL with undelete --------------------------------------------------------------------------- By the way, the delete to BOL routines do it in such a way that you can't recover with Undelete. I am now using: // Delete characters to beginning of line proc mDelToBOL() PushBlock() // This does it in a way that can be UnMarkBlock() // recovered by "UnDelete". MarkChar() BegLine() MarkChar() DelBlock() PopBlock() end // proc DelToBOL with undelete /************************************************************************** =========================================================================== Date: 05-23-93 From: GEORGE DE BRUIN Subj: History Buffer suggested uses --------------------------------------------------------------------------- The "File(s) to edit:" prompt in TSE has a history that keeps track of the last 500 entries. If you have already loaded a file from the directory you want to go to, all you have to do is scroll through the history (using the up arrow or down arrow key) until you find that entry. Then, delete the file name, leaving the drive/path in tact (including the final backslash -- ie, 'c:\tse\ui\') and press enter. That will bring up the directory listing for you. ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ A variation on this trick would be to have a macro that is executed when you load the editor push a bunch of entries on the stack for you. This way, all you'd have to do is pick the right entry out of the history list. Here's a short example macro I would place in TSE.S: proc EditHist() AddHistoryStr("c:\hold\", _EDIT_HISTORY_) AddHistoryStr("c:\tse\src\", _EDIT_HISTORY_) AddHistoryStr("c:\tse\ui\", _EDIT_HISTORY_) AddHistoryStr("c:\c\src\", _EDIT_HISTORY_) AddHistoryStr("c:\c\doc\", _EDIT_HISTORY_) end DirHist Now, in your WhenLoaded() in TSE.S you would add a call to EditHist() like this: proc WhenLoaded() /* * Whatever else you have in your when loaded. * */ EditHist() end Of course, after editing TSE.S you'd need to exit TSE and re-burn in your configuration. (With 'sc -be.exe ui\tse.s') If you wanted to get real fancy, you could have EditHist() load a file of the paths you want in the history and insert them into the edit history. That way, you could just edit the file instead of having to change and re-burn in the macro all the time. (I won't take the time to develop this right now, but if you are interested, I will put it together for you.) /************************************************************************** =========================================================================== Date: 05-25-93 From: MEL HULSE Subj: Examples of WhenLoaded() --------------------------------------------------------------------------- That's it. Here's the relevant code: Proc WhenLoaded() integer cid = GetBufferId() /* ppp */ LoadMacro("c:\SE\macros\utility1") LoadMacro("c:\SE\macros\utility2") LoadMacro("c:\SE\macros\utility3") Set(MacPath, "c:\se\macros\") // Default Path SetGlobalStr("Ruler", "4") Set(MouseRepeatDelay, Val(GetEnvStr("MOUSERAT"))) // See below * pick_buffer = CreateTempBuffer() GotoBufferId(cid) Set(CurrVideoMode,_28_LINES_) Hook(_ON_CHANGING_FILES_, OnChangingFiles) Hook(_ON_FIRST_EDIT_, OnFirstEdit) End WhenLoaded /************************************************************************** =========================================================================== Date: 05-27-93 From: JAN NOLAN Subj: Combining SS.mac & SS_Block.mac --------------------------------------------------------------------------- SS.mac & SS_Block.mac can be easily combined into a single macro. Just add a new main routine that decides which to do if isCursorInBlock() == _LINE_ // Chks for block & block type ss_block() // ie. the old main() in ss_block else ss_doc() // ie. the old main() in ss.s /************************************************************************** =========================================================================== Date: 05-31-93 From: ALAN KELLEY Subj: myLoadFiles() --------------------------------------------------------------------------- Could you write a macro that calls EditFile, extracts the directory from the loaded file and issues a dos call to change to this directory: Hi Klaus, Thanks for the myLoadFile() macro. I did have to extend it to work across drives. This is what I came up with (though I think there must be an easier way): proc myEditFile() // string directory[40], drive[1] if EditFile() drive = SplitPath(CurrFileName(), _DRIVE_) directory = SplitPath(CurrFileName(), _PATH_) if drive == GetDrive() Dos ('CD '+directory+'.', _DONT_CLEAR_) else LogDrive(drive) Dos ('CD '+directory+'.', _DONT_CLEAR_) endif endif end Another trick I came up with to use along with this one is to pop up the directory listing for the directory of the current file with this: proc myPickFile() // string filename[40] filename = SplitPath(CurrFileName(), _DRIVE_ | _PATH_) + "*.*" if EditFile(filename) AddHistoryStr(filename, _EDIT_HISTORY_) endif end ÷÷ END of LoadFile() TSE macro Monday; May 31 at 0641 hrs ÷÷ /************************************************************************** =========================================================================== Date: 06-01-93 From: KYLE WATKINS Subj: TSE START-UP SWITCHES --------------------------------------------------------------------------- -> The same command with TSE gives a dupe of the first window, rather -> than a blank, which confuses me. Try changing to something like -> below: /************************************************************************** proc mhwindow() if hwindow() editfile() endif end mhwindow() /************************************************************************** ÷÷ END TSE startup switches Wednesday; June 2 ÷÷ /************************************************************************** =========================================================================== Date: 06-02-93 From: SAMMY MITCHELL Subj: TSE this and that --------------------------------------------------------------------------- AC> * Date and time are stamped together -- should be two separate AC> commands. This is actually just a macro: proc mDateTimeStamp() InsertText(GetDateStr(), _INSERT_) InsertText(" ", _INSERT_) InsertText(GetTimeStr(), _INSERT_) end So, for instance, if you wanted to insert just the date: InsertText(GetDateStr(), _INSERT_) // END of some date inserts /************************************************************************** /************************************************************************** =========================================================================== Date: 05-29-93 From: BARRY HARRIDGE Subj: mCompile() not within TSE not indicating error --------------------------------------------------------------------------- I foolishly tried Ctrl-f9 Compile when SC.EXE was neither in my directory nor on my path. The status line gave the message "unknown command SC" but then a little menu popped up saying "Compile successful" and inviting me to Load or Execute! I looked at your proc mCompile(), then unerased my $errors$.tmp and found it was zero bytes as expected. I believe that the trouble lies in proc mCompile() where it has AbandonFile() if NumLines() == 0 .. else .. endif because the NumLines() now refers to the current *.S file, not the error file. I fixed it by moving AbandonFile() to after the "if" , and after the "else". /************************************************************************** /************************************************************************** =========================================================================== Date: 06-04-93 From: MEL HULSE Subj: WhenLoaded() hints --------------------------------------------------------------------------- ?) Make up files of macros (each with all there PROCs) and their bound keystrokes. I call these files UTILITY1.S, UTILITY2.S... Put the keybindings at the bottom so you can copy them easily (see below.) Each file needs to compile to less than 16k. In the TSE.S WhenLoaded() PROC load these macro files as follows: Proc WhenLoaded() integer cid = GetBufferId() LoadMacro("c:\TSE\mac\utility1") LoadMacro("c:\TSE\mac\utility2") LoadMacro("c:\TSE\mac\utility3") . . . . . . . . . . 1) Go into TSE.KEY and copy the keybindings from the other files in a commented area. That way, when you need a new keybinding, you can "Find" in TSE.KEY to see if what you want is used. //END WhenLoaded() hints /************************************************************************** /************************************************************************** =========================================================================== Date: 06-06-93 From: TOM WHEELER Subj: Macro to reverse all lines in a marked block. --------------------------------------------------------------------------- DN> I am looking for a macro which will reverse the order of all lines in a DN> marked block, which may not necessarily be in alphabetical order.. It's simple. x = number of lines in block. while (x) gotoblockbegin() deleteline() gotoblockend() down() undelete() endwhile /************************************************************************** END of: Reversing the order of lines marked in a block.Wednesday - June 9, 1993 /************************************************************************** /************************************************************************** /************************************************************************** =========================================================================== Date: 06-09-93 From: MEL HULSE Subj: Format left margin --------------------------------------------------------------------------- ÚÄ´ TOM WHEELER on Monday the 7th of June 1993 ³HS> Does anyone have a simple way I must be overlooking to start all ³HS> text in a file from column 2 (or 3, or whatever)? ÀÄÄÄÄ> ÚÄo TSE mReturn2(), ³...which does Return(), Right(), Right(). If you want to be able ³to modify the indentation level use a global variable and ³RepeatCommand(). Damn, just checked the book, and it says ³RepeatCommand() asks the user. ÀÄo If you want to do it this way, an undocumented feature takes care of this. ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ ³ Implement within the TSE.S environment.³ ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ Integer Ndent // global variable Somewhere in WhenLoaded(): NDent = 2 PROC SetNdent() String sNdent[2] = Str(Ndent) If Ask("Left Margin...", sNdent) Ndent = val(sNdent) EndIf END PROC DoNdent() CReturn() Right(Ndent) // Note cursor movements can take an integer End DoNdent() // END of TSE procedure to Format left margin /************************************************************************** END TSE Format left margin with SetNDent() & DoNdent() 06/10/93 /************************************************************************** /************************************************************************** Thursday - June 10, 1993 Changed ClipboardMenu() in 'tak.s' to add turn WordWrap ON/OFF. changes marked with //tak /************************************************************************** Menu ClipboardMenu() history "Cu&t" , Cut() "C&ut Append" , Cut(_APPEND_) "&Copy" , Copy() "Cop&y Append" , Copy(_APPEND_) "" , , Divide "&Paste" , Paste() "Paste &Over" , Paste(_OVERWRITE_) "" , , Divide "&Named ClipBoards ", NamedClipBoardMenu(), DontClose //tak additions below "" , , Divide "&WordWrap ON" , Set(WordWrap,ON) "WordWrap &OFF" , Set(WordWrap,OFF) //tak additions END end // ClipBoardMenu() /************************************************************************** END changes to 'tak.s' to add selection of WordWrap ON/OFF to ClipBoardMenu() 6-10-93 /************************************************************************** /************************************************************************** =========================================================================== Date: 06-09-93 From: RAY OCONNOR --------------------------------------------------------------------------- //tak tickler: Make a menu selection for Help() and the selection will be context selectable. e.g. Block operations, file operations, make one option the ability to view the '*.hlp' file Online documentation is something I have become quite dependent upon. Use it all the time for C++. The online docs don't replace the manuals but, they are a great supplement. proc Help() EditFile("TSE_HELP.ME") mCompressView(1) end Help Help() /************************************************************************** Tickler for making F1 help() a menu with selectable help files by context /************************************************************************** //************************************************************************* /************************ Start Comment Area ***************************** =========================================================================== Date: 06-13-93 From: MEL HULSE Subj: TSE - adding to block to TAK Commenter --------------------------------------------------------------------------- ³ ³e.g. Paragraph after running Commenter v2.0 ³ ³REM The SemWare Editor (or TSE, as affectionately named by our beta ³REM testers) is licensed, commercial software. Please help us stay in ³REM business by respecting our copyright and keeping this version ³ private. ÀÄÄÄÄ> MEL HULSE Oh! That should be easy. The key is being sure the text to be REM'd is marked. 1) Save the right margin to a variable and change it to the value you want minus the space for REM. 2) While the text is blocked, do a WrapPara() from the block begining. You don't need my macro. 3) GotoBlockBegin() 4) Do this: *************************************************************************/ //tak******************* END of Comment Area ****************************** While IsCursorInBlock() InsertText("REM ", _INSERT_). Down() EndWhile 5) UnMark the block and restore the right margin. That'll put the REM in front of each line of the text. That do what you want? //tak********************************************************************** //END Adding to block in TAK Commenter Monday - June 14, 1993 //tak********************************************************************** =========================================================================== Date: 06-14-93 From: DAVID MARCUS Subj: Removing Double Blank Lines --------------------------------------------------------------------------- This macro deletes all blank lines that are adjacent to another blank line or at top or bottom of file. Useful for cleaning up text files or screen captures. proc deblank() integer old = NumLines() PushPosition() BegFile() while CurrChar() < 0 // remove blanks from beginning DelLine() endwhile repeat // remove from body of file if CurrChar() < 0 Down() while ( CurrChar() < 0 ) AND ( CurrLine() < NumLines () ) DelLine() endwhile endif until NOT Down() while CurrChar() < 0 // remove from end of file DelLine() Up() endwhile PopPosition() UpdateDisplay() Message( Str( old - NumLines() ) + " lines deleted") end //tak********************************************************************** //TSE macro to Remove double blank lines. Tuesday - June 15, 1993 //tak********************************************************************** //************************************************************************* =========================================================================== Date: 06-17-93 From: RICHARD HENDRICKS Subj: '}' & '{' --------------------------------------------------------------------------- JH>I am having trouble with TSE with the '}' and '{' keys. They seem to JH>invoke some special formatting stuff and jump to wierd places. Is JH>there some way to deactivate this and have '{' and '}' be just like JH>any other letter? John Ham In your TSE.S file, you probably have some lines something like the following... // Global variables - assumes globals initialized to 0. // Line 76 or so integer cmode, // used to invoke C-mode language, // used to invoke language package // .... proc OnChangingFiles() string fn[65] = CurrFilename() integer mk, cid = GetBufferId() // ..... language = FALSE cmode = FALSE case CurrExt() when ".s",".asm",".pas",".inc",".prg" language = TRUE when ".c",".h",".cpp",".hpp" language = TRUE cmode = TRUE endcase end Depending on the settings for 'language' and 'cmode' the '{' and '}' will be handled specially. //************************************************************************* Handling of { and } ----- 'language' and 'cmode' need to be set //************************************************************************* =========================================================================== Date: 06-19-93 From: MEL HULSE Subj: Cheap and Dirty WHILE loop --------------------------------------------------------------------------- PROC foo() Integer i = 10 While i = 0 [command to be repeated] i = i - 1 EndWhile END =========================================================================== Date: 06-22-93 From: RICHARD HENDRICKS Subj: Convert:Grphic Box 2 Text --------------------------------------------------------------------------- Sometimes I need to convert all the Extended ASCII graphics characters to more printable or e-mailable characters. Here is a macro that I wrote that does that. ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ» ÌÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ͹ For example -- the file contains boxes like: º º º º ÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍͼ +----------------------+ run GRP2TXT and you will now have: +----------------------+ | | | | +----------------------+ Have fun.. Richard // Saturday June 19, 1993 at 14:56:34 EST // grp2txt.S 03/27/1992 12/09/1992 // by Richard Hendricks // Suggests by STEVE WATKINS, SemWare & RICHARD BLACKBURN, SemWare proc Main() pushposition() begfile() replace('[´µ¶·¸¹»¼½¾¿ÀÁÂÃÅÆÇÈÉÊËÌÎÏÐÑÒÓÔÕÖ×ØÙÚÛ]','+','qxnq') // replace('[´-¹»-ÃÅ-ÌÎ-Ú]','+','gxnq') --- shorter but less // readable form of line above begfile() replace('[º³°±²ÝÞ]', '|', 'gxnq') begfile() replace('[ÄÍÜß]', '-', 'gxnq') popposition() end main // end-of-message //************************************************************************* Convert boxes to text characters //************************************************************************* =========================================================================== Date: 06-19-93 From: TOM WHEELER Subj: Comment macro --------------------------------------------------------------------------- Here's one for formatting comments in C++ or SAL code. It either creates a "comment header" ("// "), or makes sure the comment starts at the correct column. Then it puts the cursor just past the header for text insertion/editing. I hardcoded the column at 41. A neat expansion would be the ability to reformat the comments in a block. I hereby donate this code to the public domain. Use it, abuse it, or misuse it as you see fit, unfit, or misfit. /************************************************************************* mComment() 6-19-93 Tom Wheeler Macro to Create or edit/format a C++ style comment on the cursor line Algorithm: If there is no comment header ("// ") on the line then it creates one either at column 41 or at the first tabstop past end of line, if the line is longer than 41 characters Otherwise, try to make sure the comment starts at column 41 Go right 3 characters *************************************************************************/ proc mComment() integer save_insertmode = Query (Insert) integer ComCol = 41 // hardcoded - so who cares? Set (Insert, 1) BegLine() PushBlock() MarkLine() MarkLine() if (not lFind ("// ", "l")) EndLine() if (CurrCol() < ComCol) GotoColumn (ComCol) else GotoColumn (CurrCol() + DistanceToTab (1)) endif InsertText ("// ") else if (CurrCol() < ComCol) while (CurrCol() <> ComCol) InsertText (" ") endwhile elseif (CurrCol() > ComCol) while (CurrCol() <> ComCol and mLeftChar() == 32) BackSpace() endwhile if (mLeftChar() <> 32) InsertText (" ") // Note - this is a physical // tab (ASCII 9), NOT SPACES endif endif Right (3) endif UnmarkBlock() PopBlock() Set (Insert, save_insertmode) end //************************************************************************* Inserts comments '//' at column 41 //************************************************************************* 06/24/93 If you want a macro to open HWindow() and you want it to start from the initial command the put UpdateDisplay() before the HWindow() command in the macro. //************************************************************************* //************************************************************************* =========================================================================== Date: 06-26-93 From: VERNON LEONARD Subj: Vernon's Commenter macro --------------------------------------------------------------------------- I haven't seen your marco to do the comments, it may be close to the one I did (below). I also added a few lines to remove the the comment lines since I was usally trying to find where the problem was in the code. //************************************************************************* proc mComment() integer type = 0 string word[12] = "" type = isCursorInBlock() // see if the cursor is in the block if type GotoBlockBegin() // we are so goto the begining of block Begline() // make sure we are in 1st column endif PushPosition() // Save where we are at just in case word = GetText(CurrCol(),2) // get the first word on the line PopPosition() // now go back there if word == "//" // we are in comments block while type // start loop DelChar() // delete the comments DelChar() DelChar() // and the space Down() // got down a line type = isCursorInBlock() // are we still in the block endwhile // end loop else // no comments while type // begin loop for comments BegLine() // make sure we are at 1st column InsertText("// ") // insert the comments Down() // down a line type = isCursorInBlock() // are we still in the block endwhile // end the while loop endif UnMarkBlock() // unmark the block end mComment // that's all folks //************************************************************************* =========================================================================== Date: 06-26-93 From: MEL HULSE Subj: Better Movement Macros --------------------------------------------------------------------------- ÚÄ´ RAY ASBURY on Friday the 25th ³In the case of GotoColumn() and GotoLine(), I wanted a combined ³command, similar to the "-n" command line option of TSE (by the ³way - another tester help some with the replacement macro for ³these, but I can't for the life of me remember who it was ). ÀÄÄÄÄ> ALL Do you mean this one : - - - - - - - - - - - - - - - /* Goto Line and/or column. Bind to a key. Use. To a line only - Answer prompt with the line number. To a column only - Answer prompt with a comma followed by the column number. To a line and column - Answer prompt with the line number, a comma and the column number. Ray Asbury, David Marcus, and Mel Hulse March 28, 1993 */ PROC GoCol(STRING s) GotoColumn(val (SubStr(s,Pos(',', s)+1 ,3)) ) END PROC linecolumn() STRING s[10] = '' Integer linecol_hist = 250 if Ask('Goto [line][,column]:', s, linecol_hist) If s == "" message("No Entry...") elseif s[1] == "," GoCol(s) elseif NOT Pos(',', s) GotoLine(Val(s)) else GotoLine(val (SubStr(s, 1, Pos(',', s) -1)) ) GoCol(s) endif endif END =========================================================================== =========================================================================== Date: 06-28-93 From: KYLE WATKINS Subj: Sizing Windows --------------------------------------------------------------------------- You can use PushKey() with the appropriate cursor keys to resize a window. When you use PushKey() to push keystrokes on the stack, it is on a LIFO (Last In First Out) basis. PushKey() is described on page 151 of the Advanced User's Guide. The following example procedure will open a Horizontal window and then reduce the height of the new window by 4 lines. proc mReduceWindow() if hwindow() pushkey() pushkey() pushkey() pushkey() pushkey() pushkey() resizewindow() endif end When Resizewindow() is called, the pushkey() selects the top of the window, the 4 pushkey() moves the bar down for positions, and the pushkey() causes the window changes to be accepted. If a new horizontal window cannot be opened, the resizewindow() is bypassed. =========================================================================== Date: 06-29-93 From: KYLE WATKINS Subj: Regular Expressions --------------------------------------------------------------------------- You can use "regular expressions" with the Find() command to find the occurrence of "-" at the end of a line. See page 75-82 of the "User's Guide" for information about "regular expressions". For instance: Find("-$","X") will find any "-" that is the last character on a line. The "$" specifies the end of line, and the "X" specifies to use "regular expressions". You can have: while Find("-$","X") delchar() joinline() wordright() //assumes that you remain on the same line. //you may want to adjust macro to take into //account that this may carry you to next line //and also adjust for a blank line following. splitline() endwhile I am not sure how you are defining the page..... if your page has a FormFeed character present in the file, then you can account for this by checking to see if the Formfeed character follows finding the "-" at the end of line. //************************************************************************* //************************************************************************* =========================================================================== Date: 06-29-93 From: KYLE WATKINS Subj: More Regular Expressions --------------------------------------------------------------------------- -> 'any occurrence of a period followed by a nonwhitespace' Find("\.[~\d009~\d032]","X+") -> 'all occurrences of a numeral preceding a period' Find("[0-9]\.","X+") -> 'find period whitespace lowercase-alphacharacter ". (a-z)" ' Find("\.[\d009\d032][a-z]","X+") //************************************************************************* //************************************************************************* =========================================================================== Date: 07-07-93 From: RAY ASBURY Subj: PROJECTS Suggestion --------------------------------------------------------------------------- After seeing a message you sent to George telling him that you're about to release a new verison of PROJECTS, I wanted to suggest something. I would very much like to be able to specify whether to return to the "current directory" as saved in the project file, or to return to the "actual" current directory when TSE was started. Maybe even a user prompt "Return To Original Directory" "Stay In Project's Home Directory" "Abort Exit" Just a thought. <1« Hrs Later> Heck, I went ahead and did it myself! Here are the changes that I made (ALL TO PROJECTS.S): ADD THE FOLLOWING PRETTY MUCH ANYWHERE: PROC mGetStartupDirectory() DOS("CD > C:\TEMP\@@ERA@@~", _DONT_CLEAR_|_DONT_PROMPT_) END mGetStartupDirectory PROC mRestoreStartupDirectory() EditFile("C:\TEMP\@@ERA@@~") LogDrive(Chr(CurrChar())) MarkStream() EndLine() Left() MarkStream() DOS ("chdir " + GetMarkedText(), _DONT_CLEAR_|_DONT_PROMPT_) END mRestoreStartupDirectory MENU menuExitDirectory() Title = "Exit To Startup Directory?" History "&Yes" "&No" END menuExitDirectory IMMEDIATELY BEFORE THE SAVEALLANDEXIT() CALL IN mSaveFilesWithStatus(), ADD THE FOLLOWING: again: menuExitDirectory() CASE (MenuOption()) WHEN 1 mRestoreStartupDirectory() WHEN 2 UpdateDisplay() OTHERWISE goto again ENDCASE SOMEWHERE IN WhenLoaded(), ADD THE FOLLOWING: mGetStartupDirectory() //************************************************************************* TSE select directory up exit Thursday - July 8, 1993 //************************************************************************* //************************************************************************* =========================================================================== Sunday - July 11, 1993 --------------------------------------------------------------------------- RA> using Shift, pressing Alt-Q, P would only work if the Cap Locks is OFF. RA> Key binds are case sensitive ONLY on the second key and ONLY when using RA> two-key 's, such as

& . I don't believe RA> the single keys, or the first key of a two-key bind, are case sensitive. Finally it's cleared up!! The below works: --------------------------------------------------- proc Test1() Message ("Test 1") end proc Test2() Message ("Test 2") end test1() test2() //************************************************************************* Sunday - July 11, 1993 //************************************************************************* =========================================================================== Date: 07-12-93 From: GEORGE DE BRUIN Subj: TSE - Query(Type of block) --------------------------------------------------------------------------- --> Is there any way to detect the block type? Both the "isBlockInCurrFile" and "isCursorInBlock" procs will return the block type. I used them in BoxIt! to check for the presence of a block, and the type of block (example follows): if isBlockInCurrFile() <> _COLUMN_ // Is there a column block in current message("No Column Block In File.") // buffer? If not, then return. return() endif if isCursorInBlock() <> _COLUMN_ // Is the cursor in the block? message("Cursor Not In Block.") // If not, then return. return() endif The first "if" does what you want it to. //************************************************************************* Detecting Block Type Wednesday - July 14, 1993 //************************************************************************* =========================================================================== Date: 07-13-93 From: KYLE WATKINS Subj: Endless loops...(BREAK, ON) --------------------------------------------------------------------------- -> Is there a way to interrupt a macro when its trapped in an endless loop? Page 189 of the Advanced User's Guide contains a description of the Break editor variable. You can set this ON at the beginning of your macro ,saving the current state of the Break variable before setting it ON so that you can restore it to the state it was in before running your macro. e.g. proc something() integer breakset=set(break,on) ..... ..... your routine .... .... set(break,breakset) end You can now use to stop the running macro. //************************************************************************* Using BREAK to stop an runaway TSE macro Wednesday - July 14, 1993 //************************************************************************* =========================================================================== Date: 07-11-93 From: RAY ASBURY Subj: TSE hooks --------------------------------------------------------------------------- There is also a very round about way of doing this via the Hook() command, but I'm not even going to think I could explain it fully. The idea is to Hook() a macro in TSE.S just before calling an external macro. Then, anytime you wanted to execute a macro in TSE.S, just cause the Hook()'d condition to occur. For example, in TSE.S, CONSTANT INCREMENTAL_SEARCH_MACRO = 1, CURRENT_EXT_MACRO = 2 // etc. PROC mCallExtMacro() Hook(_ON_CHANGING_FILES_, mCallTSEDotSMacro) ExecMacro("ExtMacro") Hook(_ON_CHANGING_FILES_, YourUsualHookedMacro) END PROC mCallTSEDotSMacro() CASE GetGlobalInt("gTseDotSMacroToRun") WHEN INCREMENTAL_SEARCH_MACRO mIncrementalSearch() WHEN CURRENT_EXT_MACRO mCurrExt() ENDCASE END Then, your external macro could simply do something like CONSTANT INCREMENTAL_SEARCH_MACRO = 1, CURRENT_EXT_MACRO = 2 // etc. SetGlobalInt("gTseDotSMacroToRun", INCREMENTAL_SEARCH_MACRO) EditFile(CurrFileName()) Ta-da!! You just called a TSE.S macro from inside an external macro! I know, it's not very clean, but it does work. //************************************************************************* Utilizing hooks Wednesday - July 14, 1993 //************************************************************************* =========================================================================== Date: 07-15-93 From: DAVID MARCUS Subj: NameClip Fix --------------------------------------------------------------------------- The following is a fix to a bug in NameClip that was causing the UnMarkAfterCopy switch to not work. The changes are in the proc named Clipboard, which begins at about line 310 in nameclip.s. 1. Find these lines: UMAP = set(UnMarkAfterPaste,FALSE) if UMAP PushBlock() endif Change to: if operation == PASTE_APPEND or operation == PASTE_OVERWRITE UMAP = set(UnMarkAfterPaste,FALSE) if UMAP PushBlock() endif endif 2. Find these lines: if UMAP PopBlock() endif set(UnMarkAfterPaste,UMAP) Change them to: if operation == PASTE_APPEND or operation == PASTE_OVERWRITE if UMAP PopBlock() endif set(UnMarkAfterPaste,UMAP) endif This will be incorporated into the next version of NameClip, but I wanted to send them now to avoid any frutration. As far as I know they only affect UnMarkAfterCopy. //************************************************************************* TSE 'nameclip.s' fix to umark block after copy 07/16/93 //************************************************************************* =========================================================================== Date: 07-15-93 From: DAVID MARCUS Subj: NameClip() Same Fix as above??? --------------------------------------------------------------------------- I've found the reason that the UnMarkAfterCopy after failing ... it was a poor implementation of my UnMarkAfterPaste switch. You can fix it yourself by changing the following in your code. Both of these examples are in the proc Clipboard(), which begins at line 1826 in the file you sent me. 1. Go to line 1892 and add this line _after_ it: endif 2. Go to line 1888 and add these two lines _after_ it: if operation == PASTE_APPEND or operation == PASTE_OVERWRITE The result is: if operation == PASTE_APPEND or operation == PASTE_OVERWRITE if UMAP PopBlock() endif set(UnMarkAfterPaste,UMAP) 3. Go to line 1847 and add this line _after_ it: endif 4. Go to line 1843 and add these two lines _after_ it: btw, Line 1558 was still missing the terminating / Let me know if anything else comes up. I'll be getting this fix to the copy on the BBS soonish. =d= if operation == PASTE_APPEND or operation == PASTE_OVERWRITE The result is: if operation == PASTE_APPEND or operation == PASTE_OVERWRITE UMAP = set(UnMarkAfterPaste,FALSE) // This allows us our choice if UMAP // of beg/end block after paste PushBlock() endif endif //************************************************************************* TSE unmark block after copy. Could be the same as previous. 07/16/93 //************************************************************************* =========================================================================== Date: 07-24-93 From: SAMMY MITCHELL Subj: FIND PASTED STRING --------------------------------------------------------------------------- I'll do my best to try to explain the concepts behind what is going on (and maybe even why!). First, lets look at the goals. Do you want to a> mark the string, cut it, and then run the macro (3 steps) or b> mark the string, and run the macro (2 steps) In designing TSE, we felt like b> was what users wanted to do most of the time, so we proceeded accordingly. QEdit, because of its simple-minded scripting capability, enticed users to do a> (even though b> could have been done in QEdit, it wasn't quite a straight forward, and as reliable). In TSE, you can _interactively_ copy a marked string into a prompt via the CopyBlock command (you could _not_ do this in QEdit - you _had_ to first copy/cut it to the Clipboard), or a string in the Clipboard via the Paste command. In macros, things are a little different. In TSE, built-in commands/functions take either integer or string input. And TSE has macro-oriented commands to extract strings (and string blocks) from the currently edited file. These commands are GetText, and GetMarkedText. For example, in a macro, to find the next occurrence of the currently marked string: lFind(GetMarkedText(), "") And TSE commands return either a string or an integer. For example, the Paste command, pastes the Clipboard contents at the current position, whether it be a file or a prompt. However, the Paste command returns an integer, indicating whether the operation was successful or not. I hope this helps explain some of the concepts! Now on to your specific problem, "How to get a string out of the Clipboard, for use in a macro". /********************************************************************** Macro to get a string from the Clipboard. The current contents of the Clipboard are unchanged. Returns only the first line of the text in the Clipboard. Notes: We could use PushPosition/PopPosition in lieu of GotoBufferId; however, this could produce side-effects (the 'hook' functions), so just to be save, we use the latter. **********************************************************************/ string proc ClipBoard2String() integer id = GetBufferId() // save where we're at string s[80] GotoBufferId(GetClipBoardId()) // switch to clipboard s = GetText(1, sizeof(s)) GotoBufferId(id) // and return to previous file return (s) // return string to caller end proc DelSaved() lFind(ClipBoard2String(), "") DelLine() end DelSaved() Of course, you might want to add just a little error checking to your DelSaved routine, to keep from inadvertently deleting lines, in case you forget to place something in the ClipBoard in the first place, or no further occurrences of the string are found. proc DelSaved() string s[80] = ClipBoard2String() if Length(s) <> 0 if lFind(s, "") DelLine() else Message(s, " not found...") endif else Warn("Clipboard empty") endif end And now, after all that, here is something I've been using to do things with strings - find and delete them, copy or cut them to the Clipboard. I hope you can make use of it too! To use it, assign mFindAndDo() to a key (or place it under the Search menu like I did - I've replaced the 'Count' function with it, since it can also 'count' occurrences of a string). Now, either place your string in the Clipboard, or just mark it. Execute FindAndDo, and you'll have the option of counting, deleting, copying/cutting all lines that contain the requested string. You'll get a find prompt; just either type the string in, or press CopyBlock or Paste to get a saved one. Anyway, hope this is of interest: /*********************************************************************** Find and do. Applies one of several options to a found string. ***********************************************************************/ constant dofCOUNT = 1, dofDELLINE = 2, dofCUTAPPEND = 3, dofCOPYAPPEND = 4 menu FindAndDoMenu() History Title = "After Find do" "Cou&nt" "&Delete Line" "C&ut Append" "&Copy Append" end proc mFindAndDo() integer choice, curr_id, count, n, old_sound string find_st[65] = '', find_option_st[12] = '' curr_id = GetBufferId() choice = FindAndDoMenu() case choice when 0 return () when dofCUTAPPEND, dofCOPYAPPEND // cut/copy to buffer GotoBufferId(GetClipBoardId()) EmptyBuffer() GotoBufferId(curr_id) endcase count = 0 PushPosition() if Ask("Search for:", find_st, _FIND_HISTORY_) and Ask("Options [BGLIWX] (Back Global Local Ignore-case Words reg-eXp):", find_option_st, _FIND_OPTIONS_HISTORY_) and lFind(find_st, find_option_st) old_sound = Set(sound, off) repeat count = count + 1 n = NumLines() case choice when dofDELLINE DelLine() when dofCUTAPPEND, dofCOPYAPPEND PushBlock() MarkLine() MarkLine() if choice == dofCUTAPPEND Cut(_APPEND_) else Copy(_APPEND_) endif PopBlock() endcase if NumLines() < n BegLine() PrevChar() endif until not lRepeatFind() Set(sound, old_sound) endif PopPosition() Message(count, " occurrences found") end //************************************************************************* TSE find pasted string explanation by Sammy Mitchel 07/25/93 //************************************************************************* =========================================================================== Date: 07-24-93 From: SAMMY MITCHELL --------------------------------------------------------------------------- Did you know you can have the statusline on the bottom and the help line on the top? But anyway, as for the 'toggle help/statusline on/off': // Toggles between statusline/helpline on bottom of screen if Query(ShowStatusLine) Set(StatuslineAtTop, ON) Set(ShowStatusLine, OFF) Set(ShowHelpLine, ON) else Set(StatusLineAtTop, OFF) Set(ShowStatusLine, ON) Set(ShowHelpLine, OFF) endif UpdateDisplay() //************************************************************************* Toggling statusline/helpline ON-OFF 07/25/93 //************************************************************************* =========================================================================== Date: 07-25-93 From: DAVID MARCUS Subj: rePos(), reSubStr(), rePlaceChars() --------------------------------------------------------------------------- One of the occasional frustrations in TSElife for me has been that I cannot use regular expressions in the Pos() and SubString() commands. Being that my wife is out of town for a fortnight, we now can use these. I've developed three macros that I am uploading in subsequent messages: rePos() : Returns the start position of 'needle' within 'haystack,' using regular expression search and any additional specified search s and replace options. reSubStr() : Returns the string matching regular expression 'needle' from within string 'haystack', using options specified (if any). rePlaceChars() : Returns a string calculated by taking string 'haystack' and replacing string 'needle' with string 'thread', using regular expression search and any specified options. This 12-line proc can also be used to: * delete needle from haystack * trim all spaces from the beginning or end of a string * insert one string into another at a specified position. * do multiple replaces within the string (argument specifies how many, or all) * do multiple deletes within the string (argument specifies how many, or all) Please let me know any problems with these, or ways that they can be enhanced to make them more useful for you! =========================================================================== Subj: rePos() --------------------------------------------------------------------------- /************************************************************************** rePos() : Returns the start position of 'needle' within 'haystack,' using regular expression search and any additional specified search and replace options. Examples: n = rePos(last_name, full_name, 'i') if rePos('M[r]?s.', full_name, '^i') sex = 'F' endif (last_name and full_name are two strings in your proc.) Returns 0 (FALSE) if not found. *************************************************************************/ integer proc rePos(STRING needle, STRING haystack, STRING options) integer bid = CreateTempBuffer(), location = 0 AddLine(haystack) if lfind(needle, options + 'x') location = CurrPos() endif AbandonFile(bid) Return(location) end --- =========================================================================== Subj: reSubString() --------------------------------------------------------------------------- /******************************************************************** reSubStr() : Returns the string matching regular expression 'needle' from within string 'haystack', using any additional search/replace options specified (if any). Returns '' (empty string) if not found. Example: title = rePos('[DM][r]?[s]?\.', full_name, '^') Returns Dr. Mr. Mrs. Ms. Title is equal to any of these if they are at the beginning of full_name. **************************************************************************/ string proc reSubStr(STRING needle, STRING haystack, STRING options) integer bid = CreateTempBuffer() string s[255] = '' PushBlock() UnMarkBlock() AddLine(haystack) if lfind(needle, options + 'x') MarkChar() BegLine() if lfind(needle + '\c', options + 'x') MarkChar() s = GetMarkedText() else s = '' endif endif AbandonFile(bid) PopBlock() Return(s) end --- =========================================================================== Subj: rePlaceChars() --------------------------------------------------------------------------- /************************************************************************** rePlaceChars() NOTE: 12 lines--80 bytes compiled--possibly the most useful and versatile single proc I've ever written. Returns a string calculated by taking string 'haystack' and replacing string 'needle' with string 'thread' using regular expression search and any specified options. Returns haystack (unchanged) if no find occurs. Example: full_name = rePlaceChars( first_name, // find this full_name, // in this initial, // replace with this 'wi') // using these opts Use of ^ and $ in options allows this to be used to delete a string [of spaces or text] from the start or end. To trim all spaces from the end of a string, for instance: old_str = rePlaceChars( ' #', // 1 or more spaces old_str, '', // replaced with ;; '^' ) // beginning To trim them from the end of the string replace '^' with '$', above. To trim them from both the beginning and the end: old_str = rePlaceChars( '{^ #}|{ #$}', // see your manual old_str, '', '2' ) // must allow 2 replaces You can use rePlaceChars to insert a string into the middle of another at aspecified position. For instance: old_str = rePlaceChars( Format( '' : 5 :'.' ), // 5 = insert pos old_str, // string input '\0' + ins_str, '' // no special opts ) To place it 5 chars before the END of old_str, change '' to '$'. Finally, you can use a number as part of option string to have that nunber of occurrences of needle replaced by thread (if it occurs > 1 time). Use 0 to mean 'replace all occurrences'. old_str = rePlaceChars( ' ', // space old_str, // string input '' // no replace '12' // number of times ) This deletes the first 12 spaces anywhere in the string. **************************************************************************/ string proc rePlaceChars(STRING needle, STRING haystack, STRING thread, STRING options) integer bid = CreateTempBuffer() string s[255] = '' AddLine(haystack) lreplace(needle, thread, options + 'xn1') s = GetText(1,CurrLineLen()) AbandonFile(bid) Return(s) end --- //************************************************************************* rePos(), reSubStr(), rePlaceChars() 07/26/93 //************************************************************************* =========================================================================== Date: 07-20-93 From: BOB CAMPBELL Subj: Deleting Blank Lines macro DelBlank() --------------------------------------------------------------------------- /************************************************************************** Written by Bob Campbell 5/8/93 DelBlank.mac deletes all blank lines saving only one blank between paragraphs. Printer FormFeeds will be converted to an extra blank line. Usage: ExecMacro("DelBlank") **************************************************************************/ integer Proc mIsParaEnd() integer CurLine, NextLine CurLine = CurrLineLen() Down() NextLine = CurrLineLen() Up() If Curline >= 1 and NextLine == 0 Return (TRUE) // And return success Endif Return (FALSE) // And return false end proc mDelBlanks() if CurrLineLen() >= 1 if mIsParaEnd() Down(2) else Down() Endif else DelLine() Endif end proc Main() string x[1], y[1], z[2] x=" " // Form feed y=" " // Replacement for form feed characters z="gn" // Start search at file beginning, do not confirm BegFile() while Down() up() mDelBlanks() endwhile Replace(x,y,z) // Replace form feeds with spaces end //************************************************************************* DelBlank() 07/26/93 //************************************************************************* =========================================================================== Date: 07-23-93 From: IAN CAMPBELL Subj: mListOpenFiles changes --------------------------------------------------------------------------- PreScript: 08/08/93: TAK a complete macro with even more changes is available as 'a:\listopen.s' on TSE[2] Here's a little macro change for TSE.S that you might be interested in incorporating into your copy of the editor. Did you ever notice that when you bring up TSE's buffer list (default keystroke = ) that it just displays all of the files in the same order that they exist in the ring, with the current file on the top of the list? This makes finding things a bit TEDIOUS, particularly when you have a lot of files open, since files tend to MOVE AROUND as new ones are brought to the "top of the list". Now, there is no way to change the order of the files within the ring, but it is fairly simple to sort the files just before displaying them in the picklist. The beauty of this approach is that all files within a group will ALWAYS be displayed identically, with the same files in the same position each time. This makes finding a file in a large group MUCH simpler. Heres how to do it: In your "TSE.S" file locate the macro mListOpenFiles(). Add a new string definition "string fnOrg[65] = CurrFilename()" just below the "string fn[65]" definition. Find the following two lines in the macro (somewhere near the bottom of the macro): GotoBufferID(filelist) BegFile() Replace these two lines with the following lines: GotoBufferID(filelist) // go to the buffer with the filenames PushBlock() // save old marking information that might exist UnMarkBlock() // turn off any old marking if it exists BegFile() // start at the beginning of the file Right() // skip the * field for the column mark MarkColumn() // start marking a column EndFile() // go the the end of the file GotoColumn(79) // get entire drive/pathname in column mark MarkColumn() // mark the end of the column Sort() // sort the lines based on the columns marked PopBlock() // put back any old marking that might exist lFind(fnOrg, "B") // cursor to original file (search backwards) GotoBufferID(start_file) // back to the original file for a screen update UpdateDisplay() // update the screen now GotoBufferID(filelist) // back to the file list with all the filenames Voila! An alphabetically sorted picklist, with the current file hilited! If you're working with a lot of open files, and you frequently switch between them to using mListOpenFiles(), then you will probably LOVE this change! //************************************************************************* // Changes to mListOpenFiles() to sort the open files buffer 07/26/93 // PostScript: 08/08/93: TAK a complete macro with even more changes is // available as 'a:\listopen.s' on TSE[2] //************************************************************************* =========================================================================== Date: 07-27-93 From: DAVID MARCUS Subj: reLength --------------------------------------------------------------------------- Here are two more commands to let you use regular expression syntax more widely. These are based on and require the reSubStr() command I uploaded in a message yesterday. Enjoy. =d= /************************************************************************** reLength(): Returns the length of 'needle' within 'haystack,' using regular expression search and any additional specified search and replace options. Examples: n = reLength(last_name, full_name, 'i') where last_name and full_name are two strings in your proc. Returns 0 (FALSE) if not found. Copyright: (c) 1993 David Marcus **************************************************************************/ integer proc reLength(STRING needle, STRING haystack, STRING options) return(Length(reSubStr(needle, haystack, options))) end /******************************************************************** reGetText(): Returns the string matching regular expression 'needle' from within the current line, using any additional search/replace options specified (if any). Example: title = '[DM][r]?[s]?\.' reGetText(title, // search for 30, // starting at 4, // for up to 4 chars '^') // must be at begining // i.e., col 30 Returns Dr. Mr. Mrs. Ms. D. M. Drs. (Title is equal to any of these if they begin at position 30. 4 is the max length I think might be found.) Returns '' (empty string) if not found. Copyright: (c) 1993 David Marcus **********************************************************************/ string proc reGetText(STRING needle, INTEGER start_point, INTEGER str_length, STRING options) return(reSubStr(needle, GetText(start_point,str_length), options)) end //************************************************************************* reLength() 07/27/93 //************************************************************************* =========================================================================== Date: 07-28-93 From: RICHARD HENDRICKS Subj: Line Drawing with MOUSE --------------------------------------------------------------------------- // DRAW.S 11/20/1992 01/28/1993 // by Richard Hendricks // Press a key or click the mouse to stop drawing proc Main() integer x, xl, y, yl integer vert, horiz LineTypeMenu() // select the desired line type GoToMouseCursor() // get mouse and text cursor together MouseStatus() // make current and last values the same MouseStatus() xl = query( MouseX ) yl = query( MouseY ) repeat if WaitForMouseEvent( _Mouse_Move_ ) MouseStatus() x = query( MouseX ) // xl = query( LastMouseX ) // removed in .65 y = query( MouseY ) // yl = query( LastMouseY ) // removed in .65 if y <> yl vert = abs(y - yl) if y < yl repeat vert = vert - 1 LineDraw(_up_) until not vert else repeat vert = vert - 1 LineDraw(_down_) until not vert endif endif if x <> xl horiz = abs(x - xl) if x < xl repeat horiz = horiz - 1 LineDraw(_left_) until not horiz else repeat horiz = horiz - 1 LineDraw(_right_) until not horiz endif endif GoToMouseCursor() // get mouse and text cursor together xl = x // query( LastMouseX ) -- 01/28/1993 yl = y // query( LastMouseY ) -- 01/28/1993 endif until keypressed() end Main //************************************************************************* //END of TSE macro DRAW.S to line draw with the MOUSE 07/28/93 //************************************************************************* =========================================================================== Date: 07-30-93 From: RAY ASBURY Subj: Alternate keyboards in TS --------------------------------------------------------------------------- Hi Dave, ÚÄÄÄ<<< DAVE BACHMANN >>>ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ ³Am I trying to do something that can't be done? Do I have to burn-in³ ³2 separate versions of TSE and rename one? Any suggestions will be ³ ³gratefully accepted. ³ ÀÄÄÄ>>> ALL <<<ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ It can be done and it won't require two versions. Keep you 'normal' setup as it is. Then, create a macro file similar to the following: HELP EmulateHelp // JUST AN EXAMPLE "This is my emulator" END EmulateHelp // IF ANY OF THE KEYS IN EmulateKeys (BELOW) HAVE MACROS ASSIGNED TO THEM, PUT THEM HERE. KEYDEF EmulateKeys // PUT YOUR KEY ASSIGNMENTS HERE, SUCH AS Help(EmulateHelp) END EmulateKeys PROC Main() Enable(EmulateKeys, _EXCLUSIVE_) // THIS "TURNS ON" THE KEYS IN // EmulateHelp, AND "TURNS OFF" // ALL OTHER ASSIGNABLE KEYS END Main Save this file (such as emulate.s) and compile it with "SC EMULATE". (Be sure to put it in the same directory as E.EXE or in the directory you have MacPath set to). Now, just use a command similar to "E /Eemulate", and viola, you now have a different version of TSE!! "Buddy" E. Ray Asbury, Jr. Team TSE //************************************************************************* EmulateKeys suggestions for multiple key assignments 07/31/93 //************************************************************************* =========================================================================== Date: 08-04-93 From: RICHARD BLACKBURN Subj: mouse programming source --------------------------------------------------------------------------- What are you wanting to do with the mouse? Here is an example of making the HelpLine mousable: You can add mouse support to the HelpLine with macros. The following macro will add mouse support for the default HelpLine in TSE. You should be able to modify this to work with your HelpLine. /*********************************************************************** This procedure when tied to the will work like the default TSE, with the exception that if you click on the help line, it will process the command in the associated location. ***********************************************************************/ proc LeftBtn() if NOT ProcessHotSpot() end //************************************************************************* =========================================================================== Date: 08-04-93 From: BOB CAMPBELL Subj: Obscure forgotten Macros --------------------------------------------------------------------------- If you're like me you have macros assigned to keys that you have forgotten. I've got lots of these handy little macros that are so seldom used that I've found the only way to recall them is from a Menu. But that circumvents the quick intuitive response of TSE. For example I've got a macro that deletes to the beginning of the line. This is a dangerous type of macro to have assigned to a key in the first place ,especially if you forget what that key does, but since I may find a use for it I keep it available. Trouble is it's too cumbersome to run through the menus if I what to use it repeatedly. So here's my solution. mRepeatMenuOption replays the last menu option with the push of one key. Simply use it once and then recall it overe and over with this hotkey. proc mRepeatMenuOption() pushkey() // pushes the menu option when mainmenu() is called pushkey() MainMenu() end mRepeatMenuOption() Now I can keep all my obscure functions available with descriptions by menu and still be able to repeat the command quickly. When I first began adding features to my TSE I would simply add them to my source file and assign a key, but the EXE file finally got too big to compile and I ran out of keys. Using this method allows me to run most of my macro externally, thereby keeping the .EXE program size down to a reasonable size. The use of the MainMenu() is only an example You might be better off making a separate menu. Menu ForgottenProcedures() ... end //************************************************************************* mRepeatMenuOption macro 08/07/93 //************************************************************************* =========================================================================== Date: 08-09-93 From: RICHARD BLACKBURN Subj: Save Changes / Lose Changes prompt change --------------------------------------------------------------------------- Thanks for the suggestion of changing the QuitFile() menu prompt. We had a lot of people that had requested the prompt changed to "Save Changes". You could use a macro to change the prompt to "Lose Changes". integer proc mPQuit() if NumFiles() == 0 return (AbandonEditor()) endif if isChanged() case YesNo( "Lose changes?" ) when 0, 3 // Escape or Cancel return (FALSE) when 2 // No return (SaveAndQuitFile()) endcase // Let "Yes" case fall through endif return(iif(NumFiles() == 1, AbandonEditor(), AbandonFile())) end //************************************************************************* Change QuitFile() prompt from Save Changes to Lose Changes 08/10/93 //************************************************************************* =========================================================================== Date: 08-08-93 From: MAYNARD HOGG Subj: Obscure Forgotten Macros --------------------------------------------------------------------------- BC>I've got a macro that deletes to the beginning of the line. This is a >dangerous type of macro to have assigned to a key in the first place Not if you make the macro undoable as the ^Q-Del combination has been since WordStar 4! proc DelToBol() //reversible! //M. Hogg 06/09/93 if CurrChar() < 0 // are we past end of line? BegLine() DelToEOL() // let the editor do it for us else PushBlock() MarkChar() BegLine() MarkChar() DelBlock() PopBlock() endif end //************************************************************************* DelToBOL with the ability to undo 08/13/93 //************************************************************************* =========================================================================== Date: 08-12-93 From: MEL HULSE Subj: Indent a block in TSE --------------------------------------------------------------------------- The Tab key and shift tab keys shift a block right and left for me. I use the following macros in TSE.S: PROC TabBlockLeft() Iif(isCursorInBlock(), mShiftBlock(-(Query(TabWidth))), TabLeft()) END PROC TabBlockRight() Iif(isCursorInBlock(), mShiftBlock(Query(TabWidth)), TabRight()) END proc TabBlockLeft() proc TabBlockRight() TabBlockLeft() TabBlockRight() //************************************************************************* Procedures to use TAB for shifting marked blocks 08/14/93 //************************************************************************* =========================================================================== Date: 08-15-93 From: DAVID MARCUS Subj: Video Cursor Position --------------------------------------------------------------------------- After having a bit of difficulty with how set my video cursor when I want video output to be at the current text cursor position, I have come up with this formulation, which may be of help to others: integer X11, Y11 X11 = CurrCol() + Query(WindowX1) -1 Y11 = CurrRow() + Query(WindowY1) -1 ... do stuff ... GotoXY(X11, Y11) This works regardless of numberof windows, whether display is boxed or zoomed, and statusline position. p.s. - Semware: WhereX() and WhereY() ought to have WindowX1 and WindowY1 as 'See Also' references. //************************************************************************* Video cursor 08/16/93 //************************************************************************* =========================================================================== Date: 08-18-93 From: SAMMY MITCHELL Subj: BLOCK INDENTATION IN TSE --------------------------------------------------------------------------- JK> I also think QEDIT handled this better than TSE. If the cursor was in a JK> block and you used the tab key, the whole block moved. You didn't have JK> to fuss around with . Wouldn't it be better to make TSE work JK> the same way? I have to disagree. I _much_ prefer the new way. But, implementing the QEdit style is simple: (Note that this routine requires the mShiftBlock procedure and associated constants from the TSE.S file. You can place it in TSE.S just after the mShiftBlock procedure, or at the beginning of your TSE.KEY file.) proc QEditTab(integer direction) if Query(Insert) and isCursorInBlock() mShiftBlock(Query(TabWidth) * direction) else if direction == SHIFTRIGHT TabRight() else TabLeft() endif endif end QEditTab(SHIFTRIGHT) QEditTab(SHIFTLEFT) //************************************************************************* //Block indentation change from default to use ShiftTAB 08/19/93 //************************************************************************* =========================================================================== Date: 08-18-93 From: GEORGE DE BRUIN Subj: Feeding keystrokes --------------------------------------------------------------------------- From ³ FRED BRUCKER ÚÄÄÄÄÄÁÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ ³If CopyBlock() isn't bound to a key, then how else could it be ³executed in a dialog box? I'm lost here. ÀÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ To ³ GEORGE DE BRUIN Whoops. I think I wasn't too clear on this... Let's try again: CopyBlock() // When compiled is seen by TSE as a // native command CopyBlock(_DEFAULT_)// When compiled is seen by TSE as a // macro Since is seen as a native command by TSE it works in the prompt windows. However, since is seen as a macro (not a native command) in TSE it does not function in the prompt boxes. Does that make things any clearer? ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ ³Another dialog box problem: In QEdit I could "feed" keystrokes to ³the dialog box with the likes of this: ³ ³ MacroBegin EditFile DelLine Return 'g' ³ ³This would bring up the file list at the first file starting with ³"g". How can I do this in TSE? ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ You would use the PushKey() function to "stack" the keystrokes in the sequence you want, then call the command. Something like this: proc OpnSrcMnu() Pushkey() PushKey() // Pull up Search Menu end Note that the keystrokes must be pushed on the stack in backwards order (ie, it is a true stack). ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ ³I'm having trouble loading and executing a macro from the command ³line. I have this command line: tse file1 file2 -k -emsgmac.mac. ³ ³Here's the macro: ³ ³proc WhenLoaded() ³ Set(Wordwrap,ON) ³ HWindow() ³end ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ Change it so that it is not a WhenLoaded(). Place it in a Main(), like this: proc main() Set(WordWrap, ON) HWindow() end Now it should work. OPENING TSE WITH TWO HORIZONTAL WINDOWS IS DISCUSSED IN THE NEXT NOT SEE 'Opening TSE with two windows' on 8-20-93. //************************************************************************* //Feeding keystrokes and much, much more 08/19/93 //************************************************************************* =========================================================================== Date: 08-20-93 From: FRED BRUCKER Subj: Opening TSE with two windows --------------------------------------------------------------------------- Well, either I've mis-communicated my split-window-on-startup problem or all of you wizards are asleep at the switch. After getting familiar with UpdateDisplay() from our earlier discussions, I tried this as my startup macro in my mail reader: proc WhenLoaded() UpdateDisplay() Set(Wordwrap,ON) HWindow() NextWindow() end Works like the proverbial charm! I even like the appearance of the boxed windows in this situation. This macro splits the screen on startup with the original message in the upper window and the reply (usually empty, unless a re-reply) in the lower. The two filenames and the macro are supplied on the command line. It switches the active window to the upper so I'm ready to get a quote. //************************************************************************* Open TSE with two horizontal windows 08/20/93 //************************************************************************* =========================================================================== Date: 08-21-93 From: KYLE WATKINS Subj: VARIABLE TABULATOR INPUT --------------------------------------------------------------------------- The following macro will allow you to toggle the variable tab stop at the cursor location. /*** START HERE ***/ integer t_unit, t_bit, vartabset string vtab[32], s_unit[1] proc ToggleTab() if vartabset s_unit=chr(asc(s_unit)&(~(1 shl t_bit))) vartabset=FALSE else s_unit=chr(asc(s_unit)|(1 shl t_bit)) vartabset=TRUE endif vtab=substr(vtab,1,t_unit-1)+s_unit+substr(vtab,t_unit+1,32) set(vartabs,vtab) end string proc querytab() if currcol() <256 t_unit=(currcol()/8)+1 //Get vartab string element t_bit=(currcol() mod 8) //Get bit of vartab string element vtab=query(vartabs) s_unit=vtab[t_unit] if (asc(s_unit)&(1 shl t_bit)) vartabset=TRUE return("_SET_ ") else vartabset=FALSE return("CLEAR ") endif endif return("INVALID") end menu tabmenu() Title="Variable Tab Toggle" Command=ToggleTab() "Variable Tab is" [querytab()+" at column "+str(currcol()):22] ,,DONTCLOSE end tabmenu() //Example key assignment //************************************************************************* //Toggle the TAB stop variable 08/22/93 //************************************************************************* =========================================================================== Date: 08-24-93 From: GEORGE DE BRUIN Subj: KillMax Variable --------------------------------------------------------------------------- Whoops. An oversight in the manual... Right now you can set KillMax in the TSE.CFG file. Right now it can only be set for 0 or non-zero (ie, it will go back to the default value). Just add a line that says: KillMax = 0 to the TSE.CFG file (make sure it is between the Config / EndConfig lines. This will set it so that no kills are added to the buffer. If you want to change the value so it is just different (say to 10), add the following to the WhenLoaded() proc in TSE.S: set(KillMax, 10) //************************************************************************* //KillMax Variable 08/25/93 //************************************************************************* =========================================================================== Date: 08-31-93 From: PAUL LENZ Subj: Three (3) MARGIN SETING MACROS --------------------------------------------------------------------------- Here are 3 macros which set margins quickly and easyly. They work like WordStar's ctrl-o-r, ctrl-o-l, and ctrl-o-g. Paul Lenz /************************************************************************* MARGIN.S contains: SetLeftMargin() sets left margin SetRightMargin() sets right margin MarginFromLine() sets left and right margins dependig of cursor line 31.8.1993 by Paul Lenz Friesenstrasse 22 30161 Hannover Germany *************************************************************************/ proc SetLeftMargin() string lm[3] = "" if Ask("Left Margin or ESC for current position",lm) if val(lm) > 0 Set(LeftMargin,val(lm)) endif else Set(LeftMargin,CurrPos()) endif end proc SetRightMargin() string rm[3] = "" if Ask("Right Margin or ESC for current position",rm) if val(rm) > 0 Set(RightMargin,val(rm)) endif else Set(RightMargin,CurrPos()) endif end proc MarginFromLine() Set(RightMargin,PosLastNonWhite()) Set(LeftMargin,PosFirstNonWhite()) Message(str(PosFirstNonWhite())+" <---Margins---> "+str(PosLastNonWhite end --- //************************************************************************* Subj: Three (3) MARGIN SETING MACROS 09/02/93 //************************************************************************* //************************************************************************* /************************ Start Comment Area ***************************** =========================================================================== Date: 09-01-93 From: MEL HULSE Subj: RT MARGIN Toggle MACRO --------------------------------------------------------------------------- WHAT IT DOES: It toggles between 64 and 72 characters for the right margin and displays the RT Margin setting in the upper right hand corner. ****************** RIGHT MARGIN MACRO ************************ Macro to toggle RT Margin between 72 and 64 characters Creation date: 04/15/93 H. Garth McKay (with a little bit of help! from Mel Hulse) Source File: RTMGN.S Assigned Macro Key ************************************************************** *************************************************************************/ //tak******************* END of Comment Area ****************************** proc Main() Integer Timer = 18 // 27 is about 1 1/2 seconds IF Query(RightMargin) == 72 Set(RightMargin,64) Else IF Query(RightMargin) == 64 Set(RightMargin,72) endif endif Message(" Rt Margin... ", (Query(RightMargin))) Delay(Timer) // Added UpdateDisplay(_STATUS_LINE_REFRESH_) // Added End //************************************************************************* // Right Margin Toggle 09/02/93 //************************************************************************* =========================================================================== Date: 09-05-93 From: DAVID MARCUS Subj: mouse keys and TSE.KEY --------------------------------------------------------------------------- Define these constants ..... constant LeftRightBtn = | , LeftCenterBtn = | , RightCenterBtn= | , LeftRightCenterBtn = | | And then you can use them for key definitions: < CenterBtn> < LeftBtn> < RightBtn> < LeftCenterBtn> < LeftRightBtn> < LeftRightCenterBtn> < RightCenterBtn> p.s. - I will not swear that 100% of these combinations work. //************************************************************************* Mouse button combinations 09/06/93 //************************************************************************* =========================================================================== Date: 09-07-93 From: SAMMY MITCHELL Subj: MYSTERY CODE - DelExtraBlankLines() w/detailed explanation --------------------------------------------------------------------------- // Remove all occurrences of more than one consecutive blank line, starting // at the current line proc DelExtraBlankLines() loop // Loop, until an empty line (PosFirstNonWhite() == 0) is found, or until the // end of file is reached (Down() == FALSE, which is also 'not Down()'). repeat until PosFirstNonWhite() == 0 or not Down() // We are either at the eof, or on a blank line. Determine which if not Down() // if Down() == FALSE, we're at eof, so stop break endif // We are not at eof, so the line we were on must be blank. Now delete // additional blanks lines. PosFirstNonWhite() == 0 signifies a blank line. // PosFirstNonWhite() <> 0 means we have a non-empty line. A shortcut way // of writing PosFirstNonWhite() <> 0 is 'if PosFirstNonWhite()'. // DelLine will return FALSE if there are no more lines to Delete, as might // happen if we reach eof. repeat until PosFirstNonWhite() or not DelLine() endloop end //************************************************************************* Subj: MYSTERY CODE - DelExtraBlankLines() w/detailed explanation 09/08/93 //************************************************************************* =========================================================================== Date: 09-07-93 From: RICHARD BLACKBURN Subj: Switche examples within a macro --------------------------------------------------------------------------- > Will it work with EditFile(-b file.xyz) in a macro? Yes, that will work! The "-n" goto line/column will also work in a macro. e.g. EditFile(-n## file.xyz) //************************************************************************* 09/08/93 //************************************************************************* =========================================================================== Date: 09-07-93 From: RICHARD BLACKBURN Subj: HELPLINE --------------------------------------------------------------------------- > How can I turn the HelpLine on and off from within a macro? > Can I have different HelpLine text for different macros? > Can I change the HelpLine text for different parts of the same macro? Ans. Yes, Yes, Yes To turn the HelpLine on/off in a macro: Set(ShowHelpLine, On/Off) To change the HelpLine when you load a macro, just assign the HelpLine in your macro like a key assignment. To have different help lines while a macro is running, you can put the different HelpLines in a KeyDef and enable them when you want the HelpLine to change. =========================================================================== Date: 09-09-93 From: FRED BRUCKER Subj: Binary edit mode --------------------------------------------------------------------------- >> If I remember correctly you had some trouble getting TSE to split a window using HWindow() in a main() or whenloaded(). << Thanks for your suggestion using Pushkey(). I also got it to work using UpdateDisplay() in the Whenloaded(): proc WhenLoaded() UpdateDisplay() HWindow() end //************************************************************************* Opening TSE with a Horizontal Windows 09/09/93 //************************************************************************* =========================================================================== Date: 09-09-93 From: DAVID MARCUS Subj: WordWrap with spaces macr --------------------------------------------------------------------------- Here is a first try at a paragraph wrapping macro that preserves [and forces!] two spaces at the end of each sentence except when the sentence ends a line. forward proc endpara() forward proc begpara() proc wrap_with_spaces() PushBlock() PushPosition() WrapPara() PopPosition() PushPosition() MarkChar() EndPara() MarkChar() PopPosition() while lfind("[\.\!\?][\d034'\)]@ \c", 'xln1') if CurrChar() > 0 and CurrChar() <> 32 InsertText(' ', _INSERT_) endif PushPosition() BegLine() WrapPara() PopPosition() PushPosition() MarkChar() EndPara() MarkChar() PopPosition() endwhile Down() BegLine() PopBlock() end proc EndPara() Down() if CurrLineLen() == 0 BegPara() endif repeat until ( Down() AND CurrLineLen() == 0 ) OR ( CurrLine() == NumLines() ) if CurrLine() <> NumLines() Up() endif EndLine() end proc BegPara() if CurrLineLen() == 0 repeat until ( Down() AND CurrLineLen() <> 0 ) OR ( CurrLine() == NumLines() ) else repeat until ( Up() AND CurrLineLen() == 0 ) OR ( CurrLine() == 1 ) if currline() <> 1 Down() endif endif GotoPos(PosFirstNonWhite()) end //************************************************************************* WordWrap with two spaces after a comma 09/10/93 //************************************************************************* =========================================================================== Date: 09-15-93 From: RAY ASBURY Subj: Ruler --------------------------------------------------------------------------- Here's a simple one that a fellow tester made available quite a while back that I like very well. Although it is not sticky (as to it's location), it has served me quite well: PROC mRuler() // originally written by Peter Birch, but released to PD INTEGER i = 1, j = Query(WindowCols), k = CurrXOffset() + 1, nRow = CurrRow() + Query(Windowy1) IF (CurrRow() == Query(WindowRows)) nRow = nRow - 2 ENDIF VGotoXY(Query(Windowx1), nRow) WHILE (i <= j) IF (k MOD 10 == 0) Write(SubStr(Format(k:4:'0'), 3, 1)) ELSEIF (k MOD 5 == 0) Write("Å") ELSE Write("Â") ENDIF i = i + 1 k = k + 1 ENDWHILE VGotoXY(Query(Windowx1), nRow) PutAttr(Color(Bright White ON Red), j) END mRuler //************************************************************************* RULER 09/16/93 //************************************************************************* =========================================================================== From: IAN CAMPBELL Date: 09-17-93 Subj: Switch between Last 2 Buffers --------------------------------------------------------------------------- Hi ALL, One of the strengths of the TSE editor is its ability to load a seemingly endless number of files. It doesn't seem to matter what you throw at this editor, it just takes it in stride. However, a problem develops when there are a lot of files loaded -- it becomes difficult to find them all! Now, I've been using the "Buffer List" (Alt-0) command to bring up the open files menu, and to switch between them, (and I've even modified the buffer list code so that things are sorted alphabetically and I can consistently find all of the files). But when one file starts with, say, an "A", and another starts with a "W", and there are thirty or so files open, it can take a while to move from one end of the buffer list to the other. This becomes especially tiresome when you are moving bits and pieces from one file to another, and must continually switch back and forth between the two of them. So I cooked up a little macro to allow toggling between just the last two files that you have looked at. It doesn't matter how many files are open, just touch one key and you're instantly in the previous file. Touch it again and you're back where you were! Here's the macro: --------------------------------------------------------------------- integer PreviousID = 0, CurrentID = 0 proc mTrackFileChanges() if PreviousID == 0 PreviousID = GetBufferID() CurrentID = GetBufferID() elseif GetBufferID() <> CurrentID PreviousID = CurrentID CurrentID = GetBufferID() endif end mTrackFileChanges proc mToggleBuffers() if PreviousID GotoBufferID(PreviousID) EditFile(Currfilename()) endif end mToggleBuffers --------------------------------------------------------------------------- Add the line: Hook(_ON_CHANGING_FILES_, mTrackFileChanges) to the Whenloaded() macro in TSE.S, and add the above two macros into TSE.S just above the WhenLoaded() macro. Finally, bind the mToggleBuffers() macro to a suitable key. You might want to choose a single key if you can find one. I used the key on the lower right corner of the keyboard. I found that I always used the left key for my editing, so this key was available. And it is VERY convenient . Anyway, my key mapping went as follows: mToggleBuffers() I find that I REALLY LIKE this macro. Let me know what you think! //************************************************************************* Switch between last two files(buffers) 09/18/93 //************************************************************************* =========================================================================== Date: 09-19-93 From: DAVID MAYEROVITCH Subj: RECURSIVE CALLS IN SAL --------------------------------------------------------------------------- integer proc Content ( string book ) integer real = true integer unreal = false if Great(book) == true return ( real ) else return ( unreal ) endif end Content //************************************************************************* Recursive Calls 09/20/93 //************************************************************************* =========================================================================== Date: 09-27-93 From: RICHARD BLACKBURN Subj: Macro Repeat --------------------------------------------------------------------------- .....what code do I need to add to the macro to make it loop 162 times? I assume you are referring to a TSE macro, so you could have loop with a variable you decrement, for example: proc test() integer i = 162 while i <> 0 i = i - 1 // Do whatever you want in the loop endwhile end //************************************************************************* Example of a simple 'WHILE' 09/28/93 //************************************************************************* =========================================================================== Date: 09-28-93 From: RICHARD BLACKBURN Subj: KEY ASSIGNMENTS --------------------------------------------------------------------------- > The default TSE.KEY file has RepeatCmd() assigned to . > How come pressing either or executes > the RepeatCmd()? I'm sure the answer to the previous question will > clear up what is happening with my four key assignments below: > > Message("") > Message("") > Message("") > Message("") > > I placed them at the end of TSE.KEY. > When I compile I get duplicate key warnings for the last two. > > Warning 056 (280,1) duplicate key defined... ignored > Warning 056 (281,1) duplicate key defined... ignored > > Those four assignments are the only ones using . For ctrl two keys are relaxed for the 2nd key. The following keys are the same: Since the 2nd key is relaxed the only shift state TSE will see for the 2nd key is if you use Alt. //************************************************************************* Relaxed Key Assignments 09/28/93 //************************************************************************* =========================================================================== Date: 09-30-93 From: JACK HAZLEHURST Subj: Another STATUS line --------------------------------------------------------------------------- CM>Is there anyway I can add to the status line how many lines CM>the current file contains? I have a bunch of things I like to know about my settings in TSE. What I did was to assign a key to a macro that builds a string containing all the little tidbits I want to know about and displays it on the message line. The next keystroke, of course, wipes it out and brings back the status line, but I can see what I need this way. There are so many things I want to be able to check that I'm considering adding a second line of stuff (assigned, of course, to another key combination). // // Additional status line // proc mStatusLine2() Message( "ColMod=", OnOffStr(column_mode), " FulJst=", OnOffStr( Justify ), " TbsOut=", OnOffStr( TabsOut ), " ExpTbs=", OnOffStr( Query( ExpandTabs ) ), " WrdEnd=", iif( WESwitch, "END", "BEG" ), " LngCfg=", MenuStr(StdCfgMenu,CfgID) ) end "OnOffStr" is a macro you'll find in TSE.S. The other variables are peculiar (ve-e-ery peculiar) to my customization of TSE, but I'm sure you get the idea. //************************************************************************* Another STATUS line 09/30/93 //************************************************************************* =========================================================================== Date: 09-29-93 From: GEORGE DE BRUIN Subj: Temporarily changing margin --------------------------------------------------------------------------- If you just want to change the setting for the right margin while the mWrapPara() command is being executed, you could write a short macro: proc mWrap() integer rm = Set(RightMargin, 55) // Set new right margin, save old // value mWrapPara() // Wrap the paragraph Set(RightMargin, rm) // Set the right margin back to // the old value end This temporarily sets the margin would keep the right margin set the way it normally is, but allow you to have it at a different setting for wrapping. This macro would need to be inserted in your TSE.S file. The best place for the macro would be right above the lines: //************************************************************************* Temporarily Change Margin 09/30/93 //************************************************************************* =========================================================================== Date: 09-29-93 From: SAMMY MITCHELL Subj: NOT logic --------------------------------------------------------------------------- > I do have a question about this segment of the macro though: > > if NOT Down() > break > endif > > I understand the "NOT" logic, the "break," and why it's necessary > to prevent things from getting locked up on the last line of the > file; however, does the "Not Down()" test actually execute the > "Down()" function? It would appear so, or else I can't see what > advances the process a line at a time. > > It seems confusing and incorrect to me that an _IF_ should > execute the cited function. Is this documented somewhere? > One would never expect ordinary compares such as "If X == 3" to > result in X being set to the value of 3. Consistency should > dictate that "If function()" or "If NOT funtion()" should behave > the same way, shouldn't it? The if logic above could be rewritten as: integer ok ok = Down() // assign result to ok if ok == FALSE // test value of ok break endif The "if not Down()" form is just a convenient short-cut. Perhaps you're confusing the assignment operator '=' with the test for equality operator '==' ? 'a = b' can be read as "assign the value of b to a", while 'if a == b' can be read "if the value of a is the same as the value of b, do what follows". Does this make more sense now? If not, let me know. Can you think of something we could say in the manual to help make this point more clear? By the way, this is the way many other programming languages work, including C, Pascal and Visual Basic. //************************************************************************* NOT logic 09/30/93 //************************************************************************* =========================================================================== Date: 10-05-93 From: RAY ASBURY Subj: Menus and time delay --------------------------------------------------------------------------- ÚÄÄÄ<<< STEVE KRAUS >>>ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ ³Another good idea! I have assigned to "View" functions. ³ ³Views Found text (CompressView), while Views the Old screen, and³ ³ views text found in all files loaded. ³ ³ ³ ³I do wish for WordStar-style menus that would work like the HelpLines do. ³ ³If I press down the first key of a two-key and wait for some specified time,³ ³it would be nice to pop up a menu. ³ ³ ³ ÀÄÄÄ>>> RAY ASBURY <<<ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ You could do a WordStar-style menu. At least, one similar to what you describe here. Basically, here what you would need: proc OptionOneMacro() Message("this is OptionOneMacro()") end OptionOneMacro proc OptionTwoMacro() Message("this is OptionTwoMacro()") end OptionTwoMacro menu mMenu() "Menu Option &One", OptionOneMacro(), CloseAllBefore "Menu Option &Two", OptionTwoMacro(), CloseAllBefore end mMenu proc mShellMenu() INTEGER hrs, min, sec, hun, start, keyPress, wait = 5 // 5 second wait GetTime(hrs, min, sec, hun) start = ((((hrs * 60) + min) * 60) + sec) * 60 REPEAT IF (KeyPressed()) keyPress = GetKey() CASE keyPress WHEN OptionOneMacro() WHEN OptionTwoMacro() WHEN Return ENDCASE ENDIF GetTime(hrs, min, sec, hun) UNTIL ( (start + wait) > (((((hrs * 60) + min) * 60) + sec) * 60) ) mMenu() end mShellMenu I just put this together without testing, so I may have made a mistake or two. Hope this helps get you started. //************************************************************************* Menus and time delay 10/06/93 //************************************************************************* =========================================================================== Date: 10-05-93 From: RICHARD BLACKBURN Subj: Mouse functions --------------------------------------------------------------------------- If you do not mind losing one of your mouse keys, you can assign TrackMouseCursor() and it will scroll the screen while you are holding the key. Syntax: TrackMouseCursor() Returns: Nothing. Notes: While MouseKeyHeld() is TRUE, this function continuously moves the text cursor to the mouse cursor. If the mouse is moved outside the current window, the window is scrolled. Any block within the current file is extended to the new cursor. Internally this function uses MouseStatus(), which updates MouseX, MouseY, and MouseKey. See Also: Mousestatus(), MouseKeyHeld() //************************************************************************* Mouse functions 10/06/93 //************************************************************************* //************************************************************************* /************************ Start Comment Area ***************************** //tak********************************************************************** =========================================================================== Date: 10-05-93 From: RAY ASBURY Subj: A statusline clock --------------------------------------------------------------------------- With a 486/33 my cursor looked as if was having an epileptic seisure it was blinking so fast!! I added a check of the last posted time against the current time and only update the clock if it's changed. That eliminated the flicker. I also added code to use the same colors as the statusline uses. Here's you macro with my mods: *************************************************************************/ //tak******************* END of Comment Area ****************************** PROC mClock() INTEGER nowTime, saveAttr IF (Query(EditState) & _STATE_EDIT_MAIN_LOOP_) GetTime(gHrs, gHun, gMin, gSec) // global variables in my TSE.S nowTime = (gHrs * 60) + gMin IF (nowTime <> gLastPostedTime) // must be a global variable gLastPostedTime = nowTime Set(Cursor,Off) GotoXY(Query(ScreenCols) - 8, 1) // position for time saveAttr = Set(Attr, Query(StatusLineAttr)) PutStr(' '+GetTimeStr()+' ') // write the time Set(Attr, saveAttr) Set(Cursor,On) UpdateDisplay() ENDIF ENDIF END mClock Except for the time disappearing for about a 1/2 second when UpdateDisplay() is called, it now works great. Thanks for sharing your macro. //************************************************************************* Status Line Clock 10/06/93 //************************************************************************* =========================================================================== Date: 10-07-93 From: DAVID MARCUS Subj: TINY BUG IN TSGREP --------------------------------------------------------------------------- Find these two lines and delete the second line: [line numbers approximate] 1247 while lFind(sstring, options) 1248 AND CurrLine() <> NumLines() // stops processing if EOF Find these lines: 1342 else 1343 Down() // AND down 1344 BegLine() // to beginning of next line 1345 endif 1346 check_for_abort() 1347 endwhile and change to: 1342 else 1343 if NOT Down() goto end_of_file endif 1344 BegLine() // to beginning of next line 1345 endif 1346 check_for_abort() 1347 endwhile end_of_file: //************************************************************************* Tiny bug fix in TSEGREP5 10/07/93 //************************************************************************* //************************************************************************* /************************ Start Comment Area ***************************** =========================================================================== Date: 10-10-93 From: LOUIS VONDERSCHEER Subj: Displaying compile errors --------------------------------------------------------------------------- *************************************************************************/ //tak******************* END of Comment Area ****************************** Integer Proc JumpToError(String Type) String Colm[3], Line[4], ErrMsg[78] If GotoBufferId(Errors) If LFind(Type,'w+') ErrMsg = GetText(PosFirstNonWhite(),PosLastNonWhite()) Message('['+ErrMsg+']') Line = GetText(Pos('(',ErrMsg)+1,(Pos(',',ErrMsg)-Pos('(',ErrMsg))-1) Colm = GetText(Pos(',',ErrMsg)+1,(Pos(')',ErrMsg)-Pos(',',ErrMsg))-1) GotoBufferId(source) GotoLine(Val(Line,10)) GotoColumn(Val(Colm,10)) ScrollToRow(Query(WindowRows)/2) Else BegFile() GotoBufferId(source) If Flag Return(False) Else GotoBufferId(source) Beep(1) Message('No '+Type+'s found...') Return(false) EndIf EndIf Else Message('Error Buffer not found...') halt EndIf Return(true) End JumpToError //---------- Proc ShowErrors() string temp[10] = '' if not gotobufferid(source) Source = GetBufferId() endif If GotoBufferId(Errors) if lList('Errors',80,Query(ScreenRows),0) BegLine() EndWord() temp=GetText(1,CurrPos()) if Pos('Error',temp) or Pos('Warning',Temp) or Pos('Note',Temp) Up() // move up a line so jump to err find it JumpToError(temp) EndIf EndIf GotoBufferId(Source) Return() Else GotoBufferId(Source) Return() EndIf End ShowErrors . . . JumpToError('Error') // find next error JumpToError('Warning') // find next warning ShowErrors() //************************************************************************* /************************ Start Comment Area ***************************** These are some excerpts from my sCompile macro. I use message() to put the error on the status line rather then open another window. To see the entire error output I press . At that point I can pick the specific error/warning/note to jump to. I like it this way but milage may vary... *************************************************************************/ //tak******************* END of Comment Area ****************************** =========================================================================== Date: 10-04-93 From: RICHARD BLACKBURN Subj: Inserting LetterHaed --------------------------------------------------------------------------- You could do your letterhead by setting it up as a DATA structure in your TSE.S file, for example (NOTE, I shortened it for the message): DATA LetterHead " ð ð ð ð ð ð TAKnet Infromation Exchange ..." " Fort Wayne, Indiana ..." "ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ ..." "<::::] <::::] <::::] <::::] <::::] <::: ..." "ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄ ..." " ³====³ ..." " CALL: (219) 745-3635 ³ ³ ..." "..." END Then you can assign the the following to a key to insert your letter head into the file: InsertData(LetterHead) // Insert the LetterHead DATA into the file. Once you have done this, be sure to use SC.EXE to update E.EXE with the changes. //************************************************************************* Adding Letterhead by using DATA 10/14/93 //************************************************************************* =========================================================================== Date: 10-14-93 From: JONATHAN DE BOYNE POLLARD Subj: Regular expressions [General] --------------------------------------------------------------------------- Having never used TSE, but having use regular expressions in other programs for a long time, you will probably find most of these supported everywhere. . Any character * Zero or more repetitions ? Zero or one repetitions + One or more repetitions [] Encloses a character set () Encloses a subexpression | Separates alternatives \ Quote literal next char ^ Match beginning of line $ Match end of line Some programs don't supply | and (). Other programs add \< Match the start of a word \> Match the end of a word \( Start a substring \) End a substring In the replace part of search and replace, most regexps that support \( and \) should also support \1 to \9 for substring insertion. How does this lot match against TSE ? ³ Is there any ³ standardization, or do language and system developers define them as ³ they please? ³ ³ I have a vague impression that the idea of regexps comes out of the C ³ and Unix world. The second is the answer to the first. They are used extensively in UNIX tools such as ex (vi by another name), ed, sed, and grep, although I doubt that they originated with UNIX. The "standard" regular expressions are usually those documented in the UNIX V8 regexp(3) manual, although the \< and \> metasequences are part of ex(1). There is a widely distributed regular expression C library written by Henry Spencer of the University of Toronto based upon the regexp(3) stuff. //************************************************************************* General discussion of regular expressions 10/15/93 //************************************************************************* =========================================================================== Date: 10-15-93 From: DAVID MAYEROVITCH Subj: More on Regular expressions --------------------------------------------------------------------------- JD> How does this lot match against TSE ? JD> . Any character * Zero or more repetitions JD> ? Zero or one repetitions + One or more repetitions JD> [] Encloses a character set () Encloses a subexpression JD> | Separates alternatives \ Quote literal next char JD> ^ Match beginning of line $ Match end of line TSE includes all of the above, with {} instead of (), and also has ~ for a complement class (you may have omitted this from your list). JD> Some programs don't supply | and (). Other programs add JD> \< Match the start of a word \> Match the end of a word JD> \( Start a substring \) End a substring TSE lacks the preceding four. JD> In the replace part of search and replace, most regexps that support JD> \( and \) should also support \1 to \9 for substring insertion. TSE does this too. TSE also includes @, which is similar to * but matches with maximum closure where * matches with minimum closure, and it includes #, which stands in a similar relation to +. JD> ³ Is there any JD> ³ standardization, or do language and system developers define them as JD> ³ they please? JD> The "standard" regular expressions are usually those documented in the JD> UNIX V8 regexp(3) manual, although the \< and \> metasequences are //************************************************************************* More on regular expressions 10/16/93 //************************************************************************* =========================================================================== Date: 10-15-93 From: ANDREAS MARTINI Subj: PEARL OF WISDOM --------------------------------------------------------------------------- Hello to Sammy Mitchell the man who invented home MacroBegin FirstNonWhite jTrue done: Begline done: also known as IF not BegLine() GotoPos(PosFirstNonWhite()) Endif From this great man, to whom I am not worth to clean his shoes, I took his wisdom and changed the lines in the unchangeable TSE.KEY file to // if Remove Trailing Whitespace is set to OFF If not EndLine() GotoPos(PosLastNonWhite()) Right() EndIf //************************************************************************* 10/16/93 //************************************************************************* =========================================================================== Date: 10-15-93 From: MEL HULSE Subj: Cursor commands that accept an Integer --------------------------------------------------------------------------- Here's the cursor commands I know of that work with an integer parameter: Backspace() DelChar() DelLeftWord() DelLine() DelRightWord() Down() DupLine() Left() NextFile() PageDown() PageDown() PageUp() PrevChar() PrevFile() Right() RollDown() RollLeft() RollRight() RollUp() ScrollDown() ScrollLeft() ScrollRight() ScrollUp() SplitLine() TabLeft() TabRight() Up() WordLeft() WordRight() Unfortunatly, CRETURN() doesn't work with an integer parameter. //************************************************************************* Command that accept Integer value 10/16/93 //************************************************************************* ========================================================================== Date: 10-15-93 From: David Daniel Anderson Subj: mAbandonAll() --------------------------------------------------------------------------- proc mAbandonAll() while NextFile() <> 0 AbandonFile() endwhile AbandonFile() end //************************************************************************* mAbandonAll() 10/16/93 //************************************************************************* =========================================================================== Date: 10-16-93 From: DAVID DANIEL ANDERSON Subj: Old TSE Macros Reload file from disk --------------------------------------------------------------------------- It allows the user to get the most recent "saved to disk" version of the current file. It prompts for confirmation, and defaults to "y" if only enter is pressed. This could be changed to "n" to make it safer (see the second line). proc mRefreshFile() string rfr[1]="y" string ThisFile[80] = CurrFileName() Ask("Do You Want to Get the Saved Copy of This File?", rfr) if rfr == "y" ChangeCurrFileName("#tsetemp") EditFile(ThisFile) PrevFile() AbandonFile() EditFile(ThisFile) endif end It could be enhanced to save the current position in the file and restore that position when the saved version is reloaded, should you desire. I don't care to do it, though. //************************************************************************* Reload file from disk 10/16/93 //************************************************************************* =========================================================================== Date: 10-20-93 From: SAMMY MITCHELL Subj: FIND & REMOVE BLANK LINES --------------------------------------------------------------------------- Here it is (msg 708) and probably in a file too: // Remove all occurrences of more than one consecutive blank line, // starting at the current line proc DelExtraBlankLines() loop repeat until PosFirstNonWhite() == 0 or not Down() if not Down() break endif repeat until PosFirstNonWhite() or not DelLine() endloop end DelExtraBlankLines() //************************************************************************* DelExtraBlankLines() again? 10/20/93 //************************************************************************* =========================================================================== Date: 10-18-93 From: BOB KOWITT Subj: Reload from disk --------------------------------------------------------------------------- // Abandons file on screen and reloads same file proc Reload() string fn[65] = CurrFilename() AbandonFile() EditFile(fn) end //************************************************************************* 10/20/93 //************************************************************************* =========================================================================== Date: 10-20-93 From: RICHARD BLACKBURN Subj: Synchronized Windows --------------------------------------------------------------------------- SEE SYNCHRONIZED FIX!!! - later in this file > What is the possibility of getting Synchronized Windows for at least > two of the windows. It would help. The following macro will scroll all windows together. You need to assign ScrollWindows() to a key. When you want to lock the windows together press the key you have assigned to ScrollWindows(). When you want to stop scrolling the windows press : constant cLEFT = 1, cRIGHT = 2, cUP = 3, cDOWN = 4, cPAGEUP = 5, cPAGEDOWN = 6, cBEGLINE = 7, cBEGFILE = 8, cENDLINE = 9, cENDFILE = 10 proc mScrollWindows(integer direction) integer winid = WindowId(), num = 1 while num < 10 if GotoWindow(num) case direction when cLEFT Left() when cRIGHT Right() when cUP Up() when cDOWN Down() when cPAGEUP PageUp() when cPAGEDOWN PageDown() when cBEGLINE BegLine() when cBEGFILE BegFile() when cENDLINE EndLine() when cENDFILE EndFile() endcase endif num = num + 1 endwhile GotoWindow(winid) end keydef ScrollKeys mScrollWindows(cLEFT) mScrollWindows(cRIGHT) mScrollWindows(cUP) mScrollWindows(cDOWN) mScrollWindows(cPAGEUP) mScrollWindows(cPAGEDOWN) mScrollWindows(cBEGLINE) mScrollWindows(cBEGFILE) mScrollWindows(cENDLINE) mScrollWindows(cENDFILE) EndProcess() end proc ScrollWindows() Enable(ScrollKeys) Process() Disable(ScrollKeys) end //************************************************************************* Syncronize Window Scrolling 10/20/93 //************************************************************************* =========================================================================== Date: 10-23-93 From: SAMMY MITCHELL Subj: Find & remove *ALL* blank lines --------------------------------------------------------------------------- If you want to delete _all_ blank lines, how about: proc DeleteAllBlankLines() PushPosition() // save our place loop if PosFirstNonWhite() == 0 if not DelLine() break // if eof endif elseif not Down() // if eof break endif endloop PopPosition() end DeleteAllBlankLines() //************************************************************************* Subj: Find & remove *ALL* blank lines 10/24/93 //************************************************************************* ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ ³SYNCHRONIZED FIX!!! from macro above³ ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ =========================================================================== Date: 10-25-93 From: RICHARD BLACKBURN Subj: Synchronized Windows Macro FIX!! --------------------------------------------------------------------------- DD> Richard, when I implemented your macro, I noticed that with 2 windows DD> opened vertically, if the cursor is in window 1 when I invoke the DD> macro, only window 2 scrolls, windows 1 is locked. If I'm in window DD> 2, then both windows scroll together. Is this the way it's supposed DD> to work? This is with v1.00z. Thanks. The following macro should fix the problem: constant cLEFT = 1, cRIGHT = 2, cUP = 3, cDOWN = 4, cPAGEUP = 5, cPAGEDOWN = 6, cBEGLINE = 7, cBEGFILE = 8, cENDLINE = 9, cENDFILE = 10 proc Scroll(integer direction) case direction when cLEFT Left() when cRIGHT Right() when cUP Up() when cDOWN Down() when cPAGEUP PageUp() when cPAGEDOWN PageDown() when cBEGLINE BegLine() when cBEGFILE BegFile() when cENDLINE EndLine() when cENDFILE EndFile() endcase end proc mScrollWindows(integer direction) integer winid = WindowId(), num = 1 while num < 10 if GotoWindow(num) Scroll(direction) endif num = num + 1 endwhile GotoWindow(winid) if winid == 1 Scroll(direction) endif end keydef ScrollKeys mScrollWindows(cLEFT) mScrollWindows(cRIGHT) mScrollWindows(cUP) mScrollWindows(cDOWN) mScrollWindows(cPAGEUP) mScrollWindows(cPAGEDOWN) mScrollWindows(cBEGLINE) mScrollWindows(cBEGFILE) mScrollWindows(cENDLINE) mScrollWindows(cENDFILE) EndProcess() end proc ScrollWindows() Enable(ScrollKeys) Process() Disable(ScrollKeys) end ScrollWindows() //************************************************************************* Lock scrolling Windows FIX!!! 10/26/93 //************************************************************************* =========================================================================== Date: 10-25-93 From: DAVID MARCUS Subj: Making New CmdLine Opts --------------------------------------------------------------------------- ALSO see next message for CmdLine() use with NameClip() I am uploading to the library here a pair of helper macros that faciliate (make easy!) the creation of custom command line options. They allow you to test to see if any option [1 or more letters preceded by a '-'] was used on the TSE commandline and what argument, if any, followed the option. They also allow you to retrieve the filespecs used on the command line. Included are two command line options: * -p to print those files included on the command line. * -N to goto line,col rather than just going to line. For instance tse -p c:\autoexec.bat c:\config.sys prints both these files, first querying to print all (2) files. If you say yes, it does. If you say no, it queries on an individual basis for printing each file. In any case, the editor ends after printing. And: tse *.s -n5,10 goes to line 5, column 10 of the first file loaded. The file name is CmdLine3.ZIP. ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ ³ALSO see next message for CmdLine() use with NameClip()³ ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ //************************************************************************* CmdLine3 Macro 10/26/93 //************************************************************************* =========================================================================== Date: 10-26-93 From: DAVID MARCUS Subj: Load Named Clipboards Cmd --------------------------------------------------------------------------- SEE CmdLine() in previous message ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ ³ PLUG: Using the CmdLine helper macros, the TSE command ³ ³ line option described here took less than 15 minutes to ³ ³ conceive, implement, and test. ³ ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ For NameClip() users only ... a command line option to load a stored clipboard file at startup. You can use my CmdLine helper macros to create a command line option to automatically load a file of saved clipboards. Note: To do this, you must have included NameClip as part of your TSE configuration [that is, using a #INCLUDE rather than loading it as an external macro]. To do this.... 1. Find the GET_CLIPS_FROM_FILE() proc in NameClip.S and find these lines: if Ask('File name for clipboards?', saveclipfilename) Ä¿ AND Length(saveclipfilename) ³ else ³ msg = 'bad file name' ÃÄÄÄ¿ pop_message('', Query(MsgAttr), 19) ³ ³ goto ending ³ ³ endif ÄÙ ³ ³ 2. Wrap these lines in an add'l if...else...endif: ³  if Length(GetGlobalStr(global_saveclipfilename)) ³ saveclipfilename = GetGlobalStr(global_saveclipfilename) ³ else ³ if Ask('File name for clipboards?', saveclipfilename) //*Ä¿ ³ AND Length(saveclipfilename) //* ³ ³ else //* ³ ³ msg = 'bad file name' //* ÃÙ pop_message('', Query(MsgAttr), 19) //* ³ goto ending //* ³ endif //*ÄÙ endif //* these lines don't change, they are just wrapped //* in the extra "if...endif" 3. Add this to your WhenLoaded() in your TSE config file: /* Load clipboard file */ if CmdLineOptionUsed('cb') AND Length(GetGlobalStr('CmdLineArgForcb')) SetGlobalStr( 'global_saveclipfilename', GetGlobalStr('CmdLineArgForcb') ) get_clips_from_file() endif 4. Recompile TSE. You can now start TSE like this: e filespecs -cbCLIP_FILE_NAME where CLIP_FILE_NAME is the name of the file you have previously specified when storing clipboards to a file using the named clipboard Other Functions menu. Command line helper macros are in file CmdLine3.ZIP, in Conference 4, when released by sysops. //************************************************************************* CmdLine3() and NameClip() 10/27/93 //************************************************************************* =========================================================================== Date: 10-26-93 From: MEL HULSE Subj: TSE REGULAR EXPRESSIONS --------------------------------------------------------------------------- Here's a post from Internet that should prove helpful. Here are some quick and dirties from my files. Also attached is a brief description of each regexp character. expr = "^\@major head" expr = "{^\@major head}|{^\@med head}" expr = "<\$\!\.{NOT }?INCLUDE" expr = "^{\@maj}|{\@med}|{\@min}|{\@command name}" expr = "^{forward }?{public }?{{integer }|{string }}?{proc }|{menu }" expr = "\<\$[IAS]" expr = "{else }|{elseif }|{while }|{repeat }|{loop }|{for }|{switch} |{case }|{ expr = "{unix}|{vms}|{vax}|{aos}|{non-}|{dos}|{windows}|{motif}|{iq[wx]}" expr = "^{forward }?{public }?{{integer }|{string }}?{proc }|{menu }" expr = "{<\$M}|{<\$R\[}" Symbol Regular Expression Search Behavior ...... .................................................................... . Matches any single character (except end-of-line). ^ Beginning of line/block $ End of line/block \n In a REPLACE pattern: references a tagged component pattern from th search pattern, where "n" is a single-digit number from 0 through 9. | "Or" operator: matches the preceding or the following pattern. ? Optionally matches the preceding pattern. [ ] Identifies a Class of characters against which to match a single character. [ - ] Indicates a range of characters (based on ASCII sequence) when used BETWEEN characters in a Class. [~ ] Identifies a complement Class of characters to match against a single character, when "~" is used as the first character within the Class * Matches 0 or more occurrences of the preceding pattern, with minimum closure. + Matches 1 or more occurrences of the preceding pattern, with minimum closure. @ Matches 0 or more occurrences of the preceding pattern, with maximum closure. (See "Minimum/Maximum Closure" below). # Matches 1 or more occurrences of the preceding pattern, with maximum closure. (See "Minimum/Maximum Closure" below). { } Serve as Tags to identify a pattern group or component pattern withi the search pattern. Tagged patterns can be nested. \ Serves as an Escape operator. This symbol is used to override a Regular Expression operator so the operator symbol is treated as a literal character. It is also used with certain other characters to indicate additional Regular Expression options; and is used within a Replace pattern to reference a Tagged component (see the explanation of "{ }" (Tags) above). \a Matches the alert (beep) character (^G or ASCII 7). \b Matches the backspace character (^H or ASCII 8). \f Matches the formfeed character (^L or ASCII 12). \n Matches the newline (line feed) character (^J or ASCII 10). ** \r Matches the return character (^M or ASCII 13). ** \t Matches the tab character (^Ior ASCII 9). \v Matches the vertical tab character (^K or ASCII 11). \c Designates the placement of the cursor within the located string whe used with the Find command. \xnn Matches the character equivalent to the indicated hexadecimal value, \dnnn Matches the character equivalent to the indicated decimal value, \onnn Matches the character equivalent to the indicated octal value, where //************************************************************************* Information on 'regular expressions' 10/28/93 //************************************************************************* File: 'tse_tip1.txt Tuesday - November 9, 1993 Snippets of information from messages on various networks From May 1993 thru October 1993 END