** Reply to message from Harry Binswangeron Wed, 02 Jul 2008 21:23:25 -0700 For the brave of heart, attached, UnDo.ZIP with all the requisite files. The underlying thinking behind this UnDo|ReDo program: You can't reliably capture keystrokes in memory, and you can't reverse the logic of commands in XPL (SORT command etc). Even if you could do all this, you'd be OOM (Out-Of- Memory) in 3 seconds flat. In short, it can't be a "smart" Undo a la Word, which un-does individual keystrokes. The only reliable method is file backups. So here are my two schemes: 1) Timed, and 2) Keystroke-Generated, backups. The user can choose either method. Theoretically, you could use both methods concurrently, but I do not advise it. Windows NT+ ONLY for the Timed method (that means NT4, 2000, XP, Server, or Vista); 9x can be used with the Keystroke- Generated method. Installation ============ The Title of XyWrite's window *must* (MUST!) begin with the seven letters "XYWRITE" -- case-INsensitive!! So XyWrite=xywrite=XYWRITE=XYWrite etc. Adjust your XyWrite window's Properties accordingly. Required external programs: UnDo.exe - locate in Editor's directory KillNB.exe - locate in Editor's dir kmd.exe - locate in DOS Path (e.g. .\system32) or Editor's dir. If you don't already have kmd.exe, download it from XyWWWeb: http://users.datarealm.com/xywwweb/dwnload.cgi?download=WIN95CMD.ZIP UnDo.exe does all the work (KillNB just kills UnDo.exe if you want to stop making Timed backups -- no other purpose). UnDo requires a dedicated subdirectory of Editor's dir, \UD (e.g. C:\XY4\UD), which contains the backups. Frame UNDO.INT makes this subdirectory automatically if it does not yet exist -- you do NOT need to make it. You'll require PLENTY of unused disk space for backups! Backups bear the "8" part of the 8.3 filename in your current window, plus EXTensions numbered 001-999, e.g. if the document is named "MYFILE.TXT" then the first backup will be named "MYFILE.001". NOTE: A potential flaw here is if you are editing files named e.g. MYFILE.A and MYFILE.B, then no distinction between them will be made in the backups (they'll all be called MYFILE.001, MYFILE.002, etc, and they will overwrite each other, and get all bumbled up). So... ummm... just don't DO that -- caveat user! [UNTITLED] windows are handled as e.g. "UNTITLE5.001" for the first backup of the [UNTITLED] document in Window #5. If the current file hasn't changed since the last backup, then no backup is made. Add a new stanza "[UnDo]" to XyWWWeb.REG, per different instructions for each method, below. Install 6 new frames in XyWWWeb.U2 (CoPy from file UNDO.FRM into U2, then LOADHELP : 1) undo.int,rud - UNDO.INT provides INiTialization. You MUST run UNDO.INT in STARTUP.INT: edit STARTUP and enter a separate line in STARTUP as follows, *after* XyWWWeb.U2 is LOADed: ... JM 2.undo.intQ2 ;*; ... UNDO.INT creates subdir .\UD if it doesn't already exist, or erases any existing files in .\UD RUD restarts UnDo under the Timed method after UnDo is turned off with KUD, described below (KUD="Kill UnDo", RUD="Restart UnDo"). 2) $T - creates Timed UnDo backups. This is constructed as a XyWrite function, for ease of use in the KBDfile -- just two characters, "$T". 3) $K - ditto, except $K creates Keystroke-Triggered UnDo backups. 4) undo,redo - Write the appropriate backup over the current file, then RECAll it. When you want to UnDo or ReDo, you just issue one of those commands+ on the CMline (or could put on a key), and it "happens". Make some changes to a document, then try it! 5) cud[/nv] - Clear the UnDo backups for the current file. /NV optionally clears *all* files in .\UD, creating an empty directory. 6) kud - Kill UnDo.exe with the Timed method (stop UnDo.exe from running). Description of the "Timed" method: ================================= Principles: You assign frame $T to a keystroke in KBD file. Theoretically, it can be any keystroke, but I would pick a simple one, with only one or two or (best!) NO standard toggling keys like Alt or Ctrl or Shift (do NOT use NumLock or CapsLock!) -- for example, I have been using LeftAlt+LeftShift+U, and also ScrollLock. ScrollLock works best for me. UnDo.exe knows what keystroke or keystroke combo you've picked, and IF (only if) XyWrite is the current foreground process then UnDo pokes that keystroke into XyWrite's keyboard buffer every X seconds (the user should NOT manually use this keystroke!). Poking the keystroke into the keyboard buffer EXECUTES it! You determine the value of X seconds: 10, 20, 30, 60, whatever. You also determine how many levels of backup you want to maintain (Tip: Do NOT use the full 998 maximum, because UnDo will be RENaming ALL your backups EVERY time you make a new one! use a reasonable number, like 20 or 100 or 300). UnDo.exe gets these three pieces of information from three REG Variables (respectively, UnDoKeys, UnDoFreq, UnDoDepth) when you initialize UnDo (via frame UNDO.INT): UNDO.INT passes an argument to UnDo.exe like "A4A055 10 100", which means: A4A055 are the hex XXh scan codes for LeftAlt(A4)+LeftShift(A0)+U(55), in my example. A table of scan codes, SCANCODE.TBL, is included in UnDo.ZIP. Don't get confused: scancodes are NOT the same as XyWrite key numbers in the KBDfile! You MUST consult SCANCODE.TBL to get the correct scancodes for the keystroke you've selected! 10 = make a backup every 10 seconds 100 = maintain 100 levels of backup New Stanza in REG ("Timed" method): --------------- [UnDo] UnDoKeys=91 <==ScanCode of key used to trigger backups, e.g. 91=ScrollLock UnDoFreq=10 <==check document status every X seconds, e.g. 10 seconds UnDoDepth=100 <==number of backups to maintain, e.g. 100 ; --------------- You can *test* that you've written the correct scancodes in REG Variable "UnDoKeys" by starting UnDo.exe and then running IDKEY . Every X seconds IDKEY should jump to your $T key. Hit an ordinary alpha key A-Z to move IDKEY off the $T key, then watch IDKEY pop back to $T again X seconds later... When picking a key, you need to consider several things. Keystrokes are additive. Real and poked keystrokes are not distinguished by the system. If you are manually holding down the Shift key, and UnDo pokes a ScrollLock, what XyWrite sees is Shift-ScrollLock. That's fine, because you can map $T to Shift-ScrollLock too in your KBD file -- in fact, you can and *should* map $T to key #70 (the ScrollLock key) in each Table of your KBD file. But what if $T is mapped to Alt-Shift-U in KBDfile? If you're manually holding down the Shift key, and UnDo pokes Alt-Shift-U, the system sees Alt-U (because two shifts cancel the shift). UnDo tries to determine what keys you are holding down, but the fact is that XyWrite is a lot faster than the Windows operating system, and it isn't foolproof. ScrollLock (key #70 in the KBD file) works particularly well for me, because it is basically a useless key (i.e., the ToggleScrollLock function TS mapped to key #70 by the factory is an odorous function that I never use), and ScrollLock isn't affected by the various shifting keys. Simply tell UnDo (via REG Variable "UndoKeys") to use the unshifted key (scancode 91); if you've mapped $T to key #70 in each Table of your KBD file then any manually-additive shifting keys will also generate $T. This way, UnDo never interferes with your keystrokes. (The only downside is if your keyboard has a ScrollLock light: it will turn on and off every X seconds.) If the current file hasn't changed since the last backup, then no backup is made. UnDo.exe _checks_ every X seconds, but if the file hasn't changed, then nothing happens. The Timed method will probably screw up in Vista if UAC (User Access Control) is enabled; on my machine UAC is disabled, and everything works. UAC users will need to run Xy with "elevated privileges" (UAC is a total PITA, in my opinion...) The Timed method is similar to Xy's native AOT method, which however keeps only ONE(!) level of backup, and operates only on whole minutes: 1, 5, 50 (you can't specify, e.g., "d aot=.5" for every 30 seconds). Pretty sad. Description of the "Keystroke-Generated" method: =============================================== This is an UNtimed procedure (no poking into keyboard buffer). The user decides what constitutes an "undo-able" action, and codes KBDfile appropriately, inserting function $K (_not_ $T) before keystrokes that do "big things" -- copy, paste, delete block, copy block, move block, maybe, etc etc. The user decides what actions rise to the level of an UnDo. UnDo.exe monitors subdir .\UD for file changes. New Stanza in REG ("Keystroke-Generated" method): --------------- [UnDo] UnDoKeys=K <==MUST be the single letter "k" UnDoFreq= <==you may leave this empty - it is ignored UnDoDepth=50 <==number of backups to maintain, e.g. 50 ; --------------- The "Keystroke-Generated" method is very simple to implement, and works like a charm. Let me know what you think... [End] ----------------------------- Robert Holmgren holmgren@xxxxxxxx ----------------------------- Attachment: UnDo.ZIP
Description: Binary data