The Macro Lesson

This macro will swap two parameters in a function. For example, 損aram 1,param2?becomes 損aram2,param1?

There may be more than 2 parameters in the function, but the cursor is assumed to be on the first parameter of the two that will be swapped. The parameters are assumed to be separated by commas. Will properly handle nested parameters, as well as having commas or parens in quoted text.




macro SwapParms

{
  push_undo;                   // Create a single undo sequence

  int tt = truncate_spaces;    // We have to turn truncate_spaces off
  truncate_spaces = false;     // or the end result may not look right

  int tr = refresh;            // Turn off refresh for speed
  refresh = false;
                               // Find the start of the parameter
  if(!find_text("[,(]", 2, _RegExp | _Backward ))
  {
    make_message("Cursor is not on a valid parameter.");
    beep;
    goto exit;
  }

  right;
  find_text("[^ \xFF\t]", 0, _RegExp );

  str_block_begin;              // Start marking a block
  call find_next_parm;          // Find the next parameter

  rm("cut /M=1/B=99");          // Cut first parameter to scratch buffer 99

  if(cur_char == ",")           // Delete the comma separator
  {
    del_char;
  }
                                // Mark all the blank space up to
  str_block_begin;              // the next parameter and copy it
                                // to buffer 98.  This ensures
                                // that when we put parameters
  find_text("[^ \xFF\t]", 0, _RegExp);  // back together, it will look
  rm("cut /M=1/B=98");          // the same as when we started

  call find_next_parm;          // Locate the next parameter

  left;                         // Skip backwards through blank space
  find_text("[^ \t\xFF]", 0, _RegExp | _Backward );
  right;

  text(",");                   // Put in the comma
  rm("paste /B=98/O=1/A=1");    // Paste in the separating space
  rm("paste /B=99/O=1");       // Paste in the parameter

  make_message("Parameters swapped.");

exit:

  rm("cut /B=98/E=1");          // Clear our scratch buffers
  rm("cut /B=99/E=1");
  pop_undo;                     // End the undo sequence

  truncate_spaces = tt;         // Restore truncate_spaces
  refresh = tr;                 // Restore refresh
  return();


// This subroutine locates the end of the current parameter
find_next_parm:
  while( find_text("[,()'\"]",0,_RegExp))
  {
    switch ( cur_char )
    {
      // Skip over single quoted text
      case "'" :
        right;
        find_text("'",1,0);
        right;
        break;

      // Skip over double quoted text
      case '"' :
        right;
        while(find_text("[\\\"]", 1, _RegExp ))
        {
          // Handle literal quote
          if(cur_char == "\\")
          {
            right; right;
          }
          else
          {
            break;
          }
        }
        right;
        break;

      // Skip nested parenthesis
      case "(" :
        rm("Match");
        right;
        break;

      // Found the end of the parm
      case ")":
      case "," :
        ret;
        break;
    }
  }
  ret;

}  //  SwapParms