Slick-C Macros

These are my custom Slick-C macro commands that I use when coding. Hopefully it’s useful to someone.

#include "slick.sh"
#include "tagsdb.sh"
 
/** 
 * Reflow paragraph based on the current margin settings, with 
 * the option to specify left indent level.
 * 
 * @param indent indent level
 */
_command void kohei_reflow_paragraph(_str indent='') name_info(COMMAND_ARG',')
{
   _str extName = 'fundamental';
 
   if (!ext_inherits_from(extName)) {
      message("this command only works for fundamental mode.");
      return;
   }
 
   // Launch input dialog when no argument is given.
   if (indent == '') {
      int res = textBoxDialog("Indent Level", 0, 0, "", "", 
                              "reflow_paragraph_left_indent", "indent level:0");
      if (res == COMMAND_CANCELLED_RC) {
         // Dialog cancelled.  Abort.
         message("command cancelled");
         return;
      }
      indent = _param1;
   }
 
   // The indent must be a number.
   if (!isnumber(indent)) {
      message("'"indent"' is not a number.");
      return;
   }
   int indentLevel = (int)indent;
 
   // Set current extention options.
   VSEXTSETUPOPTIONS oldSetup;
   int setup_status = _ExtGetSetup(extName, oldSetup);
   if (setup_status) {
      // Failed to get the setup.
      return;
   }
 
   _str leftMargin, rightMargin, newparaMargin;
   parse oldSetup.margins with leftMargin' 'rightMargin' 'newparaMargin;
   if (!isnumber(leftMargin) || !isnumber(rightMargin) || !isnumber(newparaMargin)) {
      message("corrupt margin settings");
      return;
   }
 
   int leftMarginN    = (int)leftMargin;
   int newparaMarginN = (int)newparaMargin;
 
   int indentUnit = newparaMarginN - leftMarginN;
   if (indentUnit < 0) {
      indentUnit *= -1;
   } else if (indentUnit == 0) {
      // default indent unit length is 2.
      indentUnit = 2;
   }
 
   leftMarginN    += indentUnit * indentLevel;
   newparaMarginN += indentUnit * indentLevel;
 
   // Set new margin settings.
   VSEXTSETUPOPTIONS newSetup = oldSetup;
   newSetup.margins = leftMarginN :+ ' ' :+ rightMargin :+ ' ' :+ newparaMarginN;
   _ExtSetSetup(extName, newSetup);
   _update_buffers(extName);
 
   reflow_paragraph();
 
   // Restore the old setup.
   _ExtSetSetup(extName, oldSetup);
   _update_buffers(extName);
}
 
/**
 * Set active the specified project by its name, without the 
 * .vpj extension.  So, to activate 'foo.vpj', this command 
 * expects 'foo' as the input.  If there are multiple projects 
 * with the same name, it activates the first project it finds. 
 * 
 * @param name name of the project to activate
 */
_command void set_active_project(_str name='') name_info(COMMAND_ARG',')
{
   if (name == '') {
      int res = textBoxDialog("Project Name", 0, 0, "", "", "set_active_project", "project name");
      if (res == COMMAND_CANCELLED_RC) {
         // Dialog cancelled.  Abort.
         message("command cancelled");
         return;
      }
      name = _param1;
      if (name == '') {
         // Name is still empty.  Abort.
         message("specified project name is empty");
         return;
      }
   }
 
   int status = 0;
   int handle = _xmlcfg_open(_workspace_filename, status);
   if (status < 0) {
      return;
   }
 
   _str projFiles[];
   _WorkspaceGet_ProjectFiles(handle, projFiles);
   int i, n = projFiles._length();
   for (i = 0; i < n; ++i) {
      _str projName = stranslate(projFiles[i], '', "?*/", "r");
      projName = stranslate(projName, '', "\\.vpj$", "r");
      if (name == projName) {
         // Matching project name found.  Set this project active.
         workspace_set_active(projFiles[i]);
         return;
      }
   }
 
   message("no project named '"name"' found");
}
 
 
/** 
 * Look up a symbol using go-oo's LXR.
 * 
 * @param symbol_name Symbol name to look up.  Leave it blank to 
 *                    just go to LXR's main page.
 */
_command void ooo_lxr(_str symbol_name='') name_info(COMMAND_ARG',')
{
   _str baseurl = 'http://lxr.go-oo.org/';
   if (symbol_name == '') {
      goto_url(baseurl, true);
   } else {
      goto_url(baseurl'ident?i='symbol_name, true);
   }
}
 
/** 
 * Look up UNO API using the on-line IDL reference.  The namespaces must be 
 * separated by '.', and the com.sun.star namespace needs to be omitted. 
 * 
 * @param api_name
 */
_command void ooo_api(_str api_name='') name_info(COMMAND_ARG',')
{
   _str baseurl = 'http://api.openoffice.org/docs/common/ref/com/sun/star';
   if (api_name == '') {
      goto_url(baseurl'/module-ix.html', true);
   } else {
      _str relurl = stranslate(api_name, '/', '.');
      goto_url(baseurl'/'relurl'.html', true);
   }
}
 
/**
 * Insert an fprintf statement that contains the current class and method 
 * names, and set the cursor to the right position ready for typing a comment 
 * in.
 */
_command void c_insert_class_method_debug_statement() name_info(',')
{
   _str cur_class = current_class(0);
   _str cur_proc = current_proc(0);
   if (cur_class != '') {
      // inside class context.
      cur_class = stranslate(cur_class, '', '^[a-zA-Z\/]@\/', 'r');
      _insert_text('fprintf(stdout, "'cur_class'::'cur_proc': ');
   } else {
      // stand-alone function.
      _insert_text('fprintf(stdout, "'cur_proc': ');
   }
 
   typeless p;
   _save_pos2(p);
   _insert_text('\n");fflush(stdout);');
   _restore_pos2(p);
}
 
/** 
 * Activate the Code Annotation tool window.  There was no similar command in
 * the official product as of 12.0.2.
 */
_command void activate_code_annotations()  name_info(','VSARG2_EDITORCTL)
{
   return activate_toolbar("_tbannotations_browser_form","_type_list");
}
 
/** 
 * The parent command to some special cursor movements that fit my need.  I
 * have this command bound to Ctrl+Shift+']'.
 */
_command void kohei_move_cursor_special() name_info(',')
{
   if (_in_string()) {
      move_past_literal();
   } else {
      goto_begin_scope();
   }
}
 
/** 
 * When the cursor is somewhere on a function prototype, move the cursor to
 * the first character position after the opening brace.
 */
_command void goto_begin_scope() name_info(',')
{
   _UpdateContext(true, false, VS_UPDATEFLAG_context);
 
   int cxtid = tag_current_context();
 
   if (!cxtid) {
      // No usable context.  Bail out.
      return;
   }
 
   struct VS_TAG_BROWSE_INFO cm;
   tag_get_context_info(cxtid, cm);
   long cur_pos = _QROffset();
   long scope_begin = cm.scope_seekpos;
   if (cm.type_name :== 'func' && scope_begin > cur_pos) {
      _GoToROffset(cm.scope_seekpos);
   }
}
 
/** 
 * When the cursor is within a literal, move the cursor past that literal.
 */
_command void move_past_literal() name_info(',')
{
   if (_in_string()) {
      int status = _clex_find(STRING_CLEXFLAG, "N");
   }
}

Comments are closed.