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

📄 macro.c

📁 一个开源著名的TDE编辑器源代码
💻 C
📖 第 1 页 / 共 4 页
字号:
             * find the first keystroke in the macro.  when we pop the stack,             *  all this stuff is reset by the pop -- do not reset it again.             */            g_status.macro_next = 0;            mac = g_status.current_macro = g_status.key_macro;            mode.insert    = mac->mode[0];            mode.smart_tab = mac->mode[1];            mode.indent    = mac->mode[2];            g_status.macro_mark.marked = FALSE;            if (mac->flag & USESBLOCK) {               block.marked = g_status.marked;               block.file   = g_status.marked_file;               block.type   = file->block_type;               block.bc     = file->block_bc;               block.br     = file->block_br;               block.ec     = file->block_ec;               block.er     = file->block_er;               unmark_block( window );            }         }         popped = recursed = FALSE;         while (rc != ERROR  &&  g_status.macro_next < mac->len) {            /*             * set up all editor variables as if we were entering             *  keys from the keyboard.             */            window = g_status.current_window;            display_dirty_windows( window );            CEH_OK;            g_status.key_pressed = (mac->len == 1) ? mac->key.key :                                   mac->key.keys[g_status.macro_next];            g_status.command = getfunc( g_status.key_pressed );            if (g_status.wrapped) {               g_status.wrapped = FALSE;               show_search_message( CLR_SEARCH );            }            if (found_rline) {               found_rline = 0;               show_curl_line( window );            }            /*             * while there are no errors or Control-Breaks, let's keep on             *  executing a macro.  g_status.control_break is a global             *  editor flag that is set in our Control-Break interrupt             *  handler routine.             */            if (g_status.control_break == TRUE) {               rc = ERROR;               break;            }            /*             * we haven't called any editor function yet.  we need             *  to look at the editor command that is to be executed.             *  if the command is PlayBack, we need to break out of             *  this inner do loop and start executing the macro             *  from the beginning (the outer do loop).             *             * if we don't break out now from a recursive macro, we will             *  recursively call PlayBack and we will likely overflow             *  the main (as opposed to the macro) stack.             */            if (g_status.command == PlayBack ||                g_status.command == PseudoMacro) {               if (g_status.command == PseudoMacro) {                  if ((pkey = find_combination( window )) == 0 ||                      (pmac = find_pseudomacro( pkey, window )) == NULL) {                     ++g_status.macro_next;                     continue;                  }                  g_status.key_macro = pmac;               }               /*                * recursive macros are handled differently from                *  macros that call other macros.                * recursive macros - continue the macro from the beginning.                * standard macros - save the next instruction of this                *  macro on the stack and begin executing the called macro.                */               if (g_status.current_macro != g_status.key_macro) {                  if (push_macro_stack( ) != OK) {                     error( WARNING, window->bottom_line, ed16 );                     rc = ERROR;                  }                  recursed = TRUE;                  break;               } else {                  if (file->break_point != 0 &&                      file->break_point == window->rline) {                     rc = ERROR;                     break;                  }                  g_status.macro_next = 0;                  continue;               }            }            ++g_status.macro_next;            rc = execute( window );            /*             * jmh - A recursive macro that is closing windows could             *       close the editor.             */            if (g_status.stop == TRUE)               rc = ERROR;         }         /*          * restore the block, irrespective of how the macro finished.          */         if (!recursed  &&  !g_status.stop  &&  (mac->flag & USESBLOCK)) {            unmark_block( window );            g_status.marked_file = block.file;            g_status.marked  = block.marked;            file->block_type = block.type;            file->block_bc   = block.bc;            file->block_br   = block.br;            file->block_ec   = block.ec;            file->block_er   = block.er;            if (g_status.marked && g_status.marked_file != file) {               g_status.marked_file->dirty = GLOBAL;               g_status.marked_file->block_type = -block.file->block_type;            }         }         /*          * A recursive macro will always finish with an error condition.          * Make it OK instead, to allow other macros to call it and continue.          */         if (g_status.current_macro == g_status.key_macro  &&             !g_status.stop && !g_status.control_break) {            rc = OK;            g_status.macro_next = mac->len;         }         /*          * If the macro finished, goto the marker if one was set.          * If there's nothing on the stack, then get out.          */         if (rc != ERROR && g_status.macro_next == mac->len) {            g_status.command = MacroMark;            goto_marker( window );            if (g_status.mstack == NULL)               rc = ERROR;            else if (pop_macro_stack( ) != OK) {               error( WARNING, window->bottom_line, ed17 );               rc = ERROR;            } else {               popped = TRUE;               mac = g_status.current_macro;            }         }      }      /*       * If the macro successfully finished, the last command       * will be MacroMark.       */      if (g_status.command == MacroMark)         rc = OK;      /*       * If the macro was aborted, tidy up the macro stack.       */      else while (g_status.mstack != NULL) {         MACRO_STACK *ms = g_status.mstack;         g_status.mstack = ms->prev;         free( ms );      }      g_status.macro_executing = FALSE;      mode.insert    = cur_mode[0];      mode.smart_tab = cur_mode[1];      mode.indent    = cur_mode[2];      if (!mode.record) {         show_insert_mode( );         show_tab_modes( );         show_indent_mode( );      }   }   if (old_ms != NULL) {      g_status.mstack = old_ms;      g_status.macro_executing = TRUE;      g_status.current_macro   = ms.macro;      g_status.macro_next = ms.pos;      g_status.macro_mark = ms.mark;   }   return( rc );}/* * Name:    push_macro_stack * Purpose: push the next key in a currently executing macro on local stack * Date:    October 31, 1992 * Notes:   finally got tired of letting macros only "jump" and not call *           other macros. *          the first time in, mstack is NULL. *          Rewritten by Jason Hood, July 18, 1998. */int  push_macro_stack( void ){MACRO_STACK *ms;   /*    * first, make sure we have room to push the key.    */   if ((ms = malloc( sizeof(MACRO_STACK) )) != NULL) {      /*       * Store the current macro, its next key and its marker.       * Point to the previous macro on the stack and make this macro       *  the top of the stack.       */      ms->macro = g_status.current_macro;      ms->pos   = g_status.macro_next+1;      ms->mark  = g_status.macro_mark;      ms->block = block;      ms->prev  = g_status.mstack;      g_status.mstack = ms;      return( OK );   } else      return( STACK_OVERFLOW );}/* * Name:    pop_macro_stack * Purpose: pop currently executing macro on local stack * Date:    October 31, 1992 * Notes:   finally got tired of letting macros only "jump" and not "call" *           other macros. *          pop the macro stack.  stack pointer is pointing to last key saved *           on stack. *          Rewritten by Jason Hood, July 18, 1998. */int  pop_macro_stack( void ){MACRO_STACK *ms = g_status.mstack;   /*    * before we pop the stack, make sure there is something in it.    */   if (ms != NULL) {      /*       * Pop the macro, its position and marker. Point to the previous macro.       * Restore the editor modes to the original macro.       */      g_status.current_macro = ms->macro;      g_status.macro_next = ms->pos;      g_status.macro_mark = ms->mark;      block               = ms->block;      g_status.mstack     = ms->prev;      free( ms );      mode.insert    = g_status.current_macro->mode[0];      mode.smart_tab = g_status.current_macro->mode[1];      mode.indent    = g_status.current_macro->mode[2];      return( OK );   } else      return( STACK_UNDERFLOW );}/* * Name:    macro_pause * Purpose: Enter pause state for macros * Date:    June 5, 1992 * Passed:  arg_filler:  argument to satisfy function prototype * Returns: ERROR if the ESC key was pressed, OK otherwise. * Notes:   this little function is quite useful in macro definitions.  if *          it is called near the beginning of a macro, the user may decide *          whether or not to stop the macro. * * jmh 980525: only pause if a macro is recording or playing. * jmh 031114: don't display halt message if recording; *             test being called from a prompt */int  macro_pause( TDE_WIN *arg_filler ){long c = 0;     /* 0 != ESC so returns OK if no macro */   if (mode.record || g_status.macro_executing) {      /*       * tell user we are paused.       */      s_output( paused1, g_display.mode_line, 22, Color( Special ) );      s_output( (mode.record) ? paused1a : paused2, g_display.mode_line,                22 + strlen( paused1 ), Color( Mode ) );      /*       * get the user's response and restore the mode line.       */      if (g_status.command == Pause) {         c = getkey( );         show_modes( );      }   }   return( c == ESC ? ERROR : OK );}/* * Name:    getkey_macro * Purpose: read a key from a macro or the keyboard * Author:  Jason Hood * Date:    July 26, 1998 * Passed:  nothing * Returns: key read * Notes:   If no macro is executing, or its next function is Pause, *           or it is finished, read the key from the keyboard. *          Record the key unless it's from a macro. *          If the key read from the keyboard is the pause function, *           and it's record mode, record it, wait for another key, *           but don't record that. */long getkey_macro( void ){long key = ERROR;int  func;   if (g_status.macro_executing &&       g_status.macro_next < g_status.current_macro->len) {      key = g_status.current_macro->key.keys[g_status.macro_next++];      if (getfunc( key ) == Pause)         key = ERROR;   }   if (key == ERROR) {      key = getkey( );      if (!g_status.macro_executing && mode.record) {         func = getfunc( key );         record_key( key, func );         if (func == Pause)            key = getkey( );      }   }   return( key );}/* * Name:    set_break_point * Purpose: set or remove a break point * Author:  Jason Hood * Date:    August 15, 1998 * Passed:  window:  pointer to current window * Notes:   if the break point is already set, either move it to the new *           line, or clear it. *          The break-point is used to stop recursive/infinite macros, *           or an infinite repeat. * * jmh 991006: moved from findrep.c, since searches no longer use it. */int  set_break_point( TDE_WIN *window){file_infos *file;   if (window->ll->len == EOF)      return( ERROR );   file = window->file_info;   file->break_point = (file->break_point == window->rline) ? 0 :                       window->rline;   file->dirty = GLOBAL;   return( OK );}

⌨️ 快捷键说明

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