kohei_write_enum_switch
This macro inserts an entire switch statement block for an arbitrary enum type. It includes case blocks for all members of the specified enum type.
#include "slick.sh" #include "tagsdb.sh" _command void kohei_write_enum_switch(_str enum_name = '') name_info(COMMAND_ARG',') { if (!ext_inherits_from('c')) { message("not in c mode"); _beep(); return; } if (enum_name == '') { int res = textBoxDialog("Provide tag name", 0, 0, "", "", "kohei_write_enum_switch", "tag name"); if (res == COMMAND_CANCELLED_RC) { // Dialog cancelled. Abort. message("command cancelled"); return; } enum_name = _param1; if (enum_name == '') { // Name is still empty. Abort. message("no tag name is given"); return; } } _str inner_name, outer_name; tag_split_class_name(enum_name, inner_name, outer_name); typeless tag_files = p_window_id.tags_filenamea(p_window_id.p_LangId); if (!tag_check_for_enum(inner_name, outer_name, tag_files, p_EmbeddedCaseSensitive)) { message(enum_name" is not of type enum."); _beep(); return; } // Collect enum member names from the tag files. _str enum_members[]; enum_members._makeempty(); int i = 0; for (;;) { _str tf = next_tag_filea(tag_files, i, false, true); if (tf == '') break; int status = tag_find_in_class(enum_name); while (!status) { _str tag_name, type_name, file_name, class_name; int line_no, tag_flags; tag_get_info(tag_name, type_name, file_name, line_no, class_name, tag_flags); if (type_name == "enumc") { // Only pick up enum members. enum_members[enum_members._length()] = tag_name; } status = tag_next_in_class(); } } // Now, insert a switch statement using the member names. When doing so, // keep extending the selection and run beautify on the selected lines to // get the indentation correctly. insert_line("switch ("inner_name")"); select_line(); insert_line("{"); int memcount = enum_members._length(); for (i = 0; i < memcount; ++i) { insert_line("case "enum_members[i]":"); insert_line("break;"); } insert_line("default:"); insert_line(";"); insert_line("}"); beautify_selection(); } |
The following are the rest of my custom Slick-C macro commands that I have yet to annotate.
#include "slick.sh" #include "tagsdb.sh" _command void kohei_header_guard() name_info(',') { if (p_buf_name == '') { message("buffer name is empty."); return; } _str cur_file_name = stranslate(p_buf_name, '', '.*/', 'u'); cur_file_name = upcase(stranslate(cur_file_name, '_', '.')); _insert_text_raw('#ifndef __'cur_file_name'__'); insert_line('#define __'cur_file_name'__'); insert_line(''); insert_line(''); typeless p; _save_pos2(p); insert_line(''); insert_line('#endif'); _restore_pos2(p); } _command void kohei_write_class_dec(_str name='') name_info(COMMAND_ARG',') { if (name == '') { // no class name given return; } _insert_text_raw('class 'name); insert_line('{'); insert_line('public:'); insert_line(name'();'); indent_line(); insert_line('~'name'();'); indent_line(); insert_line('private:'); end_line(); // save this position to come back later. typeless p; _save_pos2(p); insert_line('};'); insert_line(''); // constructor insert_line(name'::'name'()'); insert_line('{'); insert_line('}'); // destructor insert_line(name'::~'name'()'); insert_line('{'); insert_line('}'); // go back to the saved position. _restore_pos2(p); } _command void insert_date_today() name_info(',') { int pin, pout, perr; _str datecmd = "/bin/date"; _str cmd = datecmd :+ " +%Y-%m-%d"; _str output = _PipeShellResult(cmd, 0, ''); output = substr(output, 1, length(output)-2); cmd = datecmd :+ " +(%A)"; output = output :+ " " :+ _PipeShellResult(cmd, 0, ''); output = substr(output, 1, length(output)-2); _insert_text(output, false, "\n"); } /** * 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("Activate Project", 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; } } // Load the workspace XML file of the current workspace. int status = 0; int handle = _xmlcfg_open(_workspace_filename, status); if (status < 0) { message("failed to load workspace file"); return; } // Go through all project names. _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 OpenGrok. * * @param symbol_name Symbol name to look up. Leave it blank to * just go to OpenGrok's main page. */ _command void ooo_grok(_str symbol_name='') name_info(COMMAND_ARG',') { _str baseurl = 'http://svn.services.openoffice.org/opengrok/'; if (symbol_name == '') { goto_url(baseurl, true); } else { goto_url(baseurl'search?project=%2FCurrent+(trunk)&defs='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");'); _restore_pos2(p); } _command void c_insert_class_method_debug_statement_win32() name_info(',') { _str cur_class = current_class(0); _str cur_proc = current_proc(0); _insert_text('{ char tmp[256]; sprintf(tmp, "'); if (cur_class != '') { // inside class context. cur_class = stranslate(cur_class, '', '^[a-zA-Z\/]@\/', 'r'); _insert_text(cur_class'::'cur_proc': '); } else { // stand-alone function. _insert_text(cur_proc': '); } typeless p; _save_pos2(p); _insert_text('\n"); OutputDebugStringA(tmp); }'); _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) { 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"); } } |