* Align all lines in a line block on the specified character or string. * * To run: Execute the command def f2 'macro align.kex' * * Select a line block and enter the command "align ". * * All lines in the block that contain the specified string * are aligned on that string. Any line that doesn't contain * the specified string is shifted to the right so far that * none of its text is in the column(s) containing the * alignment string in the lines above and below it. * * Why: This macro was created in response to my need to choose * a set of unique "access keys" for Visual Basic controls. * Here's how it's used: * * 1. In a Visual Basic .FRM file (saved as text, of course), * select just the "Caption" lines, using a command such * as "ALL WORD/Caption". * 2. Draw a line block that includes all the captions whose * access keys might conflict with one another. * 3. Invoke ALIGN.KEX with the command "ALIGN &". * 4. Leaving the cursor where ALIGN placed it, sort the * line block using the SORTBOX.KEX macro (which normally * would be assigned to Ctrl-S). * 5. Examine the resulting box block for duplicates. * 6. When done, undo the changes or discard the file. * * Requires: KEDIT 5.0 or Kedit for Windows * * Version: User macro (Jan 1998 - Frank Huber) 'extract/Alt/Block/Line' If \Arg() Then Do 'emsg {ALIGN} A string argument is required.' Exit 1 End If \Block() | Block.1 \== 'LINE' Then Do 'emsg {ALIGN} No line block marked in this file.' Exit 1 End * Note where we are, and make sure the block is addressable. 'sos save' 'preserve' 'sos current' 'extract/Alt/Block/Line' 'sos current blockstart' If RC = 2 Then Do 'restore' 'sos restore' Exit 1 End * Prepare for the two loops. 'set autosave off' 'set stream off' target = Delimit(Arg(1)) length = Length(Arg(1)) cmax = 0 * Determine the maximum shift amount. Do Until \InBlock() 'shift right 1' 'nomsg clocate :1' 'nomsg clocate' target If RC = 0 Then cmax = Max(cmax, Column.1()) 'cursor down' If Shadow() Then 'cursor down' End If cmax = 0 Then Do 'emsg {ALIGN} "'Arg(1)'" not found in the line block.' Exit End * Shift all lines containing the specified string by that amount. 'sos blockstart' Do Until \InBlock() 'nomsg clocate :1' 'nomsg clocate' target If RC \= 0 Then 'shift right' cmax + length Else Do 'shift left 1' amt = cmax - Column.1() If amt > 0 Then 'shift right' amt End 'cursor down' If Shadow() Then 'cursor down' End * Reset the state so the operator would see no movement and only one alteration. ':'Line.1 'set alt' Alt.1+1 Alt.2+1 'restore' 'sos restore' * But then (try to) put the cursor on the last line in the block * and at the beginning of the alignment string. ':'Block.4; 'nomsg cursor file' Block.4 cmax-1