⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 macro.c

📁 一个开源著名的TDE编辑器源代码
💻 C
📖 第 1 页 / 共 4 页
字号:
   while (twokey != NULL) {      write_twokeymacro( file, twokey->left );      if (twokey->macro != NULL) {         fprintf( file, "%s %s", key_name( twokey->key, buf ),                                 func_str[PlayBack] );         write_macro( file, twokey->macro, twokey->key );      }      twokey = twokey->right;   }}/* * Name:    key_name * Purpose: determine the string associated with a key * Author:  Jason Hood * Date:    August 21, 1998 * Passed:  key:     key number to convert *          buffer:  place to store the string * Returns: buffer * Notes:   minimum buffer size should be KEY_STR_MAX characters (see config.h) * * 990428:  place ';' in quotes. *          recognize the viewer keys. * 990429:  write '"' correctly (""""). */char *key_name( long key, char *buffer ){int  twokey;int  j = 0;   twokey = PARENT_KEY( key );   if (twokey) {      j = strlen( key_name( twokey, buffer ) );      buffer[j++] = ' ';      key = CHILD_KEY( key );   }   if (key & _SHIFT) {      buffer[j++] = 's';      buffer[j++] = '+';   }   if (key & _CTRL) {      buffer[j++] = 'c';      buffer[j++] = '+';   }   if (key & _ALT) {      buffer[j++] = 'a';      buffer[j++] = '+';   }   strcpy( buffer+j, cfg_key[KEY( key )] );   return( buffer );}/* * Name:    clear_macros * Purpose: reset all macro buffers, pointers, functions. * Date:    April 1, 1992 * Notes:   reset the available macro stroke count.  reset all fields in *           macro structure.  clear any keys assigned to macros in the *           function assignment array. * July 17, 1998 (jmh): if syntax highlighting is on, only clear the *                       language macros; conversely, if syntax highlighting *                       is off, only clear the global macros. */int  clear_macros( TDE_WIN *window ){register int i, j;TREE *tree;   if (!window->syntax) {      for (j = 0; j < MODIFIERS; ++j) {         for (i = 0; i < MAX_KEYS; i++) {            if (macro[j][i] != NULL) {               my_free( macro[j][i]->key.keys );               my_free( macro[j][i] );               macro[j][i] = NULL;               key_func[j][i] = 0;            }         }      }      tree = &key_tree;   } else      tree = &window->file_info->syntax->key_tree;   delete_pseudomacro( tree->left );   tree->left = NULL;   delete_twokeymacro( tree->right );   return( OK );}/* * Name:    delete_pseudomacro * Purpose: remove the pseudo-macro tree * Author:  Jason Hood * Date:    July 17, 1998 * Passed:  tree: tree to be deleted * Notes:   recursively delete all pseudo-macros */void delete_pseudomacro( TREE *tree ){   if (tree == NULL)      return;   if (tree->left == NULL && tree->right == NULL) {      if (tree->macro != NULL) {         if (tree->macro->len > 1)            my_free( tree->macro->key.keys );         my_free( tree->macro );      }      my_free( tree );   } else {      delete_pseudomacro( tree->left );      tree->left = NULL;      delete_pseudomacro( tree->right );      tree->right = NULL;      delete_pseudomacro( tree );   }}/* * Name:    delete_twokeymacro * Purpose: delete all two-key macros * Author:  Jason Hood * Date:    July 30, 1998 * Passed:  tree: tree to be deleted * Notes:   unlike delete_pseudomacro, this does not actually delete anything, *           since the two-key functions need to be preserved. * 020819:  remove tail recursion. */void delete_twokeymacro( TREE *tree ){   while (tree != NULL) {      if (tree->macro != NULL) {         if (tree->macro->len > 1)            my_free( tree->macro->key.keys );         my_free( tree->macro );         tree->func = 0;         tree->macro = NULL;      }      delete_twokeymacro( tree->left );      tree = tree->right;   }}/* *              keystroke play back functions *//* * Name:    test_for_html * Class:   macro helper function * Purpose: special pseudo-macro case for HTML * Author:  Jason Hood * Date:    June 1, 2001 * Passed:  window:  current window * Returns: TRUE if special case was found, ERROR otherwise. * Notes:   if a pseudo-macro was not found, see if we're on a word that begins *           with '<'; if so, use it to form an HTML pair. Eg: *           <font --> <font></font> with the cursor left unchanged (ie. at the *           first '>'). *          only takes the word from before the cursor. *          always uses insert mode. * 050908:  fix cursor position due to scrolling. */static int  test_for_html( TDE_WIN *window ){LANGUAGE *language;line_list_ptr line;text_ptr      text;int  len;text_t buf[MAX_LINE_LENGTH];int  rcol, ccol;int  pos;int  ins;int  rc = ERROR;   language = window->file_info->syntax;   if (language == NULL)      return( ERROR );   do {      /* no need for my_strcmp, since "html" is English */      if (stricmp( language->name, "html" ) == 0)         break;      language = language->parent;   } while (language != NULL);   if (language == NULL)      return( ERROR );   rcol = window->rcol;   if (g_status.copied) {      text = g_status.line_buff;      len  = g_status.line_buff_len;   } else {      line = window->ll;      text = line->line;      len  = line->len;   }   if (window->file_info->inflate_tabs)      rcol = entab_adjust_rcol( text, len, rcol, window->file_info->ptab_size );   if (len >= 2 && rcol >= 2 && rcol <= len) {      len = 0;      while (--rcol > 0  &&  myisnotwhitespc( text[rcol] ))         ++len;      if (text[rcol] == '<' && len > 0) {         buf[0] = '>';         buf[1] = '<';         buf[2] = '/';         pos = 3;         do            buf[pos++] = text[++rcol];         while (--len != 0);         buf[pos++] = '>';         buf[pos]   = '\0';         rcol = window->rcol;         ccol = window->ccol;         ins  = mode.insert;         mode.insert = TRUE;         rc = add_chars( buf, window );         mode.insert = ins;         check_virtual_col( window, rcol, ccol );      } else         rc = ERROR;   }   return( rc );}static BLOCK block;/* * Name:    play_back * Purpose: play back a series of keystrokes assigned to key * Date:    April 1, 1992 * Modified: November 13, 1993, Frank Davis per Byrial Jensen * Notes:   go thru the macro key list playing back the recorded keystrokes. *          to let macros call other macros, we have to 1) save the next *           keystroke of the current macro in a stack, 2) execute the *           the called macro, 3) pop the key that saved by the calling *           macro, 4) continue executing the macro, beginning with the *           key we just popped. *          use a stack to store keys. *          Rewritten by Jason Hood, July 18, 1998. * jmh 980726: with the repeat function, this function needs to return *              an appropriate status. * jmh 990214: recognize the break-point for recursive macros (why wasn't it *              already done??) * jmh 990410: changed (rc == OK) conditions to (rc != ERROR) since not all *              functions return OK (such as set_*_margin() ). * jmh 991027: corrected a bug where using a macro to play a macro twice *              would result in a false recursive macro. * jmh 010601: special case for pseudo-macros and HTML. * jmh 021210: have recursive macros return OK (so other macros can call them). * jmh 050709: test for valid block type. */int  play_back( TDE_WIN *window ){int    rc = OK;int    popped;          /* flag is set when macro is popped */MACRO *mac = NULL;int    cur_mode[3];     /* remember the current editor settings */unsigned pkey = 0;MACRO *pmac = NULL;MACRO_STACK ms;MACRO_STACK *old_ms = NULL;int    html = FALSE;    /* are we using the HTML language? */file_infos *file;int    recursed;   if (g_status.macro_executing) {      /*       * jmh 021024: It is possible for the startup macro to recurse       *             (typically by ending it with File); if that is the case,       *             restart it and let the current play_back() execute it.       */      if (g_status.current_macro == macro[KEY_IDX( _CONTROL_BREAK )]) {         g_status.macro_next = 0;         return( ERROR );      }      old_ms   = g_status.mstack;      g_status.mstack = NULL;   }   ms.macro = g_status.current_macro;   /* these are part of the above if */   ms.pos   = g_status.macro_next;      /* but moved outside to avoid GCC */   ms.mark  = g_status.macro_mark;      /* uninitialised warnings         */   /*    * Determine if it is a valid pseudo-macro.    * If so, set the key pressed to the combination.    * If not, and we're recording, forget the key.    */   if (g_status.command == PseudoMacro) {      if ((pkey = find_combination( window )) == 0 ||          (pmac = find_pseudomacro( pkey, window )) == NULL) {         rc = test_for_html( window );         if (rc == OK)            html = TRUE;         else if (mode.record == TRUE)            show_avail_strokes( +1 );      } else {         g_status.key_pressed = pkey;         g_status.key_macro   = pmac;      }   }   /*    * if we are recording a macro, let's just return if we do a recursive    *  definition.  Otherwise, we end up executing our recursive macro    *  while we are defining it.    * jmh 980722: may as well stop recording altogether.    */   if (mode.record == TRUE && g_status.key_pressed == g_status.recording_key) {      record_on_off( window );      rc = ERROR;   }   if (rc == OK  &&  !html  &&  (g_status.key_macro->flag & NEEDBLOCK)) {      const char *errmsg = NULL;      if (g_status.marked) {         int type;         switch (g_status.marked_file->block_type) {            case BOX:    type = NEEDBOX;    break;            case LINE:   type = NEEDLINE;   break;            case STREAM: type = NEEDSTREAM; break;            default:               type = 0;               assert( FALSE );         }         if (!(type & g_status.key_macro->flag))            errmsg = main18;      } else         errmsg = main17;      if (errmsg) {         error( WARNING, window->bottom_line, errmsg );         rc = ERROR;      }   }   if (rc == OK  &&  !html) {      cur_mode[0] = mode.insert;      cur_mode[1] = mode.smart_tab;      cur_mode[2] = mode.indent;      file = window->file_info;      /*       * set the global macro flags, so other routines will know       *  if a macro is executing.       * initialize the popped flag to FALSE being that we haven't       *  popped any thing off the stack, yet.       */      g_status.macro_executing = TRUE;      popped = FALSE;      rc     = OK;      while (rc != ERROR) {         /*          * the first time thru the loop, popped is FALSE.          */         if (popped == FALSE) {            /*

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -