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

📄 undo.c

📁 一个开源著名的TDE编辑器源代码
💻 C
字号:
/* * Editor:      TDE, the Thomson-Davis Editor * Filename:    undo.c * Author:      Jason Hood * Date:        November 19, 1999 * * Functions dealing with undo and redo. * * Frank's original undo just stored a copy of the line before it was changed. * Whilst being nice and easy to implement, it's very limited. My undo will * restore every change made to a file (except SortBoxBlock and the box tabs) * and cursor (if it changes line number and/or column) movement. It's not * perfect, since it works with only one file - to undo a block move from one * file to another will require an undo in each file. */#include "tdestr.h"#include "tdefunc.h"#include "common.h"int  copied_rcol;               /* original rcol position for RestoreLine */int  copied_mod;                /* original modified flag for RestoreLine */int  copied_dirty;/* * Name:    restore_line * Purpose: To retrieve unaltered line if possible. * Date:    June 5, 1991 * Passed:  window:  pointer to current window * Notes:   Changes are made to the line buffer so the underlying text has *          not changed.  Put the unchanged line from the file into the *          line buffer and display it. * jmh 010521: remember what it was, so you can change between original and *              modified. * jmh 021011: restore original column position, as well. * jmh 030225: restore modified flag. * jmh 031114: use the copied buff_node pointer to determine if the buffer is *              still valid (instead of swapping the line with the buffer). */int  restore_line( TDE_WIN *window ){register TDE_WIN *win;   /* put window pointer in a register */int  rcol;   win = window;   if (g_status.buff_node == win->ll) {      if (!copied_dirty) {         win->ll->type ^= DIRTY;         win->file_info->modified = copied_mod || (win->ll->type & DIRTY);      }      g_status.copied = !g_status.copied;      win->file_info->dirty = GLOBAL;      show_changed_line( win );      if (copied_rcol != win->rcol) {         show_ruler_char( win );         rcol = win->rcol;         check_virtual_col( win, copied_rcol, copied_rcol );         copied_rcol = rcol;      }   }   return( OK );}/* * Name:    retrieve_line * Purpose: To retrieve (pop) a line from the undo stack * Date:    September 26, 1991 * Passed:  window:  pointer to current window * Notes:   Insert an empty line into the file then pop the line in the undo *          stack.  When we pop line 0, there are no more lines on the stack. *          Set the stack pointer to -1 to indicate an empty stack. */int  retrieve_line( TDE_WIN *window ){register TDE_WIN *win;   /* put window pointer in a register */line_list_ptr node;   win = window;   if (win->file_info->undo_lines > 0 && win->ll->prev != NULL) {      if (un_copy_line( win->ll, win, TRUE, TRUE ) == ERROR)         return( ERROR );      node = win->file_info->undo_top;      win->file_info->undo_top = node->next;      win->file_info->undo_top->prev = NULL;      --win->file_info->undo_lines;      node->next = node->prev = NULL;      ++win->file_info->length;      win->ll->prev->next = node;      node->prev = win->ll->prev;      win->ll->prev = node;      node->next = win->ll;      win->ll = node;      win->ll->type |= DIRTY;      --win->rline;      adjust_windows_cursor( win, 1 );      restore_marked_block( win, 1 );      ++win->rline;      syntax_check_lines( win->ll, win->file_info->syntax );      /*       * we have now undeleted a line.  increment the file length and display       * it.       */      win->file_info->dirty = GLOBAL;      win->file_info->modified = TRUE;      show_size( win );      show_avail_mem( );   }   return( OK );}/* * Name:    load_undo_buffer * Purpose: To copy the cursor line to the undo buffer. * Date:    September 26, 1991 * Passed:  file:          pointer to file *          line_to_undo:  pointer to line in file to save * Notes:   save the last mode.undo_max_lines lines in a stack.  when we *           overflow the stack, dump the oldest line. * jmh 010522: if undo_max_lines is zero, store an "unlimited" number of lines. */void load_undo_buffer( file_infos *file, text_ptr line_to_undo, int len ){int  rc;text_ptr l;line_list_ptr temp_ll;   rc = OK;   if (mode.undo_max_lines  &&  file->undo_lines >= mode.undo_max_lines) {      --file->undo_lines;      temp_ll = file->undo_bot->prev;      temp_ll->prev->next = file->undo_bot;      file->undo_bot->prev = temp_ll->prev;      my_free( temp_ll->line );   } else      temp_ll = (line_list_ptr)my_malloc( sizeof(line_list_struc), &rc );   assert( len >= 0 );   assert( len < MAX_LINE_LENGTH );   l = my_malloc( len, &rc );   if (rc == ERROR) {      my_free( l );      my_free( temp_ll );   } else {      my_memcpy( l, line_to_undo, len );      temp_ll->line = l;      temp_ll->len  = len;      temp_ll->type = DIRTY;      temp_ll->prev = NULL;      temp_ll->next = file->undo_top;      file->undo_top->prev = temp_ll;      file->undo_top = temp_ll;      ++file->undo_lines;   }}/* * Name:    new_undo * Purpose: allocate memory for the undo structure * Author:  Jason Hood * Date:    November 19, 1999 * Passed:  file:  pointer to file requiring undo * Returns: pointer to structure or NULL if no memory */UNDO *new_undo( file_infos *file ){UNDO *undo;   if (mode.undo_max && file->undo_count > mode.undo_max) {      undo = file->undo_last->next;      if ((unsigned long)file->undo_last->text > 255)         my_free( file->undo_last->text );      my_free( file->undo_last );      undo->prev = NULL;      file->undo_last = undo;      --file->undo_count;   }   undo = my_calloc( sizeof(UNDO) );   if (undo != NULL) {      if (file->undo != NULL) {         undo->prev = file->undo;         file->undo->next = undo;      }      file->undo = undo;      ++file->undo_count;   }   return( undo );}/* * Name:    undo_move * Purpose: undo a cursor movement * Author:  Jason Hood * Date:    November 19, 1999 * Passed:  window:  pointer to window requiring undo *          func:    function to effect undo * Notes:   If func is 0, remember the current position, otherwise use func. */void undo_move( TDE_WIN *window, int func ){file_infos *file;UNDO *undo;   if (mode.undo_move) {      file = window->file_info;      undo = file->undo;      if (func == 0 || undo == NULL || undo->op != func) {         undo = new_undo( file );         if (undo == NULL)            return;         undo->op = func;         if (g_status.command_count > 0)            ++undo->group;      }      undo->line = window->rline;      undo->col  = window->rcol;      ++undo->len;   }}/* * Name:    undo_char * Purpose: undo a character overwrite or delete * Author:  Jason Hood * Date:    November 19, 1999 * Passed:  window:  pointer to window requiring undo *          ch:      character to undo *          ins:     insert (U_INS) or overwrite (U_OVR) */void undo_char( TDE_WIN *window, char ch, int ins ){file_infos *file = window->file_info;UNDO *undo = file->undo;int  op;char c;   op = U_CHAR | ins;   if (undo == NULL || undo->op != op || mode.cur_dir != CUR_RIGHT) {      undo = new_undo( file );      if (undo == NULL)         return;      undo->op    = op;      undo->dirty = (int)window->ll->type & DIRTY;      undo->mod   = file->modified;      undo->text  = (text_ptr)(int)ch;   } else {      if (undo->len == 1) {         c = (char)(long)undo->text;         undo->text = my_malloc( 2, &op );         if (op == ERROR)            return;         *undo->text = c;      } else {         undo->text = my_realloc( undo->text, undo->len + 1, &op );         if (op == ERROR)            return;      }      undo->text[undo->len] = ch;   }   undo->line = window->rline;   undo->col  = window->rcol;   ++undo->len;}/* * Name:    undo_line * Purpose: undo a line or string overwrite or delete * Author:  Jason Hood * Date:    November 19, 1999 * Passed:  window:  pointer to window requiring undo *          line:    pointer to line/string *          len:     length of above *          op:      insert/overwrite, line/string */void undo_line( TDE_WIN *window, text_ptr line, int len, int op ){UNDO *undo;file_infos *file = window->file_info;   undo = new_undo( file );   if (undo == NULL)      return;   undo->line  = window->rline;   undo->col   = window->rcol;   undo->op    = op;   undo->dirty = (int)window->ll->type & DIRTY;   undo->mod   = file->modified;   undo->len   = len;   undo->text  = my_malloc( len, &op );   if (op != ERROR)      my_memcpy( undo->text, line, len );}/* * Name:    undo_del * Purpose: undo a character, string or line insertion * Author:  Jason Hood * Date:    November 20, 1999 * Passed:  window:  pointer to window requiring undo *          len:     length to delete *          type:    type of delete * Notes: if type is U_CHAR, len is assumed to be one. */void undo_del( TDE_WIN *window, int len, int type ){file_infos *file = window->file_info;UNDO *undo = file->undo;int  op;   op = U_DEL | type;   if (type == U_CHAR && undo != NULL && undo->op == op &&       mode.cur_dir == CUR_RIGHT) {      ++undo->len;   } else {      undo = new_undo( file );      if (undo == NULL)         return;      undo->len   = len;      undo->op    = op;      undo->dirty = (int)window->ll->type & DIRTY;      undo->mod   = file->modified;   }   undo->line = window->rline;   undo->col  = window->rcol;}/* * Name:    undo_space * Purpose: undo an indentation or tab * Author:  Jason Hood * Date:    November 20, 1999 * Passed:  window:  pointer to window requiring undo *          len:     number of spaces *          type:    insert or delete */void undo_space( TDE_WIN *window, int len, int type ){UNDO *undo;file_infos *file = window->file_info;   undo = new_undo( file );   if (undo == NULL)      return;   undo->line  = window->rline;   undo->col   = window->rcol;   undo->op    = U_SPACE | type;   undo->len   = len;   undo->dirty = (int)window->ll->type & DIRTY;   undo->mod   = file->modified;}/* * Name:    undo * Purpose: reverse an action * Author:  Jason Hood * Date:    November 20, 1999 * Passed:  window:  pointer to current window * Notes: */int  undo( TDE_WIN *window ){   return( OK );}/* * Name:    redo * Purpose: reverse an undo action * Author:  Jason Hood * Date:    November 20, 1999 * Passed:  window:  pointer to current window * Notes: */int  redo( TDE_WIN *window ){   return( OK );}/* * Name:    toggle_undo_group * Purpose: toggle between group and individual undo * Author:  Jason Hood * Date:    November 20, 1999 * Passed:  arg_filler:  argument to satisfy function prototype * Notes:   use the diagnostic display to indicate current state */int  toggle_undo_group( TDE_WIN *arg_filler ){   mode.undo_group = !mode.undo_group;   show_undo_mode( );   return( OK );}/* * Name:    toggle_undo_move * Purpose: toggle movement undo * Author:  Jason Hood * Date:    May 20, 2001 * Passed:  arg_filler:  argument to satisfy function prototype * Notes:   use the diagnostic display to indicate current state */int  toggle_undo_move( TDE_WIN *arg_filler ){   mode.undo_move = !mode.undo_move;   show_undo_move( );   return( OK );}

⌨️ 快捷键说明

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