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

📄 ed.c

📁 C++游戏开发书籍的实例非常适合初学但又又想往游戏开发方面发展的人学习哦
💻 C
📖 第 1 页 / 共 5 页
字号:


#include "tdestr.h"     /* typedefs for global variables */
#include "define.h"     /* editor function defs */
#include "tdefunc.h"    /* prototypes for all functions in tde */
#include "global.h"     /* global variables */
#include "prompts.h"    /* prompt assignments */
#include "default.h"    /* default function key assignments */


/*
 * Name:    insert_newline
 * Purpose: insert a newline
 * Date:    June 5, 1991
 * Passed:  window:  pointer to current window
 * Notes:   There a several ways to insert a line into a file:  1) pressing
 *          a key, 2) word wrap, 3) any others?
 *          When doing word wrap or format paragraph, don't show any changes.
 *            Wait until the function finishes then show all changes at once.
 */
int  insert_newline( WINDOW *window )
{
char *source;           /* source for block move to make room for c */
char *dest;             /* destination for block move */
int  len;               /* length of current line */
int  split_len;
int  add;               /* characters to be added (usually 1 in insert mode) */
int  rcol;
int  rc;
long length;
int  carriage_return;
int  split_line;
int  wordwrap;
int  dirty;
int  old_bcol;
register WINDOW *win;   /* put window pointer in a register */
file_infos *file;       /* pointer to file structure in current window */
line_list_ptr new_node;
text_ptr new_line;      /* new line */

   rc = OK;
   win = window;
   file = win->file_info;
   length = file->length;
   wordwrap = mode.word_wrap;
   switch (g_status.command) {
      case WordWrap :
         carriage_return = TRUE;
         split_line = FALSE;
         break;
      case AddLine  :
         split_line = carriage_return = FALSE;
         break;
      case SplitLine :
         split_line = carriage_return = TRUE;
         break;
      case Rturn :
      default    :

         /*
          * if file is opened in BINARY mode, lets keep the user from
          *   unintentially inserting a line feed into the text.
          */
         if (file->crlf == BINARY)
            return( next_line( win ) );

         show_ruler_char( win );
         carriage_return = TRUE;
         split_line = FALSE;
         break;
   }

   /*
    * make window temporarily invisible to the un_copy_line function
    */
   new_node = (line_list_ptr)my_malloc( sizeof(line_list_struc), &rc );
   new_line = NULL;
   win->visible = FALSE;
   old_bcol = win->bcol;
   if (rc == OK) {
      new_node->line  = new_line;
      new_node->len   = 0;
      new_node->dirty = FALSE;

      if (win->ll->len != EOF) {
         win->file_info->modified = TRUE;
         if (mode.do_backups == TRUE)
            rc = backup_file( win );
         copy_line( win->ll );
         detab_linebuff( );
         len = g_status.line_buff_len;
         split_len = 0;
         if (win->rcol < len)
            win->ll->dirty = TRUE;

         source = g_status.line_buff + len;
         if (carriage_return || split_line) {
            if (win->rcol < len) {
               source = g_status.line_buff + win->rcol;
               split_len = len - win->rcol;
               len = win->rcol;
            }
         }
         g_status.line_buff_len = len;
         entab_linebuff( );
         if (un_copy_line( win->ll, win, TRUE ) == OK) {

            assert( split_len >= 0 );
            assert( split_len < MAX_LINE_LENGTH );

            memmove( g_status.line_buff, source, split_len );
            g_status.line_buff_len = len = split_len;
            g_status.copied = TRUE;
            entab_linebuff( );
         } else
            rc = ERROR;
      } else {
         g_status.line_buff_len = len = 0;
         g_status.copied = TRUE;
      }

      if (rc == OK) {
         new_node->line  = new_line;
         new_node->len   = 0;
         new_node->dirty = TRUE;

         /*
          * we are somewhere in the list and we need to insert the new node.
          *  if we are anywhere except the EOF node, insert the new node
          *  after the current node.  if the current node is the EOF node,
          *  insert the new node before the EOF node.  this keeps the
          *  EOF node at the end of the list.
          */
         if (win->ll->next != NULL) {
            win->ll->next->prev = new_node;
            new_node->next = win->ll->next;
            win->ll->next = new_node;
            new_node->prev = win->ll;
         } else {
            new_node->next = win->ll;
            if (win->ll->prev != NULL)
               win->ll->prev->next = new_node;
            new_node->prev = win->ll->prev;
            win->ll->prev = new_node;
            if (new_node->prev == NULL)
               win->file_info->line_list = new_node;
            win->ll = new_node;
         }

         ++file->length;
         detab_linebuff( );
         entab_linebuff( );
         rc = un_copy_line( new_node, win, FALSE );
         adjust_windows_cursor( win, 1 );

         file->dirty = NOT_LOCAL;
         if (length == 0l || wordwrap || win->cline == win->bottom_line)
            file->dirty = GLOBAL;
         else if (!split_line)
            update_line( win );

         /*
          * If the cursor is to move down to the next line, then update
          *  the line and column appropriately.
          */
         if (rc == OK  &&  (carriage_return || split_line)) {
            dirty = file->dirty;
            if (win->cline < win->bottom_line)
               win->cline++;
            win->rline++;
            if (win->ll->next != NULL) {
               win->bin_offset += win->ll->len;
               win->ll = win->ll->next;
            }
            rcol = win->rcol;
            old_bcol = win->bcol;

            if (win->ll->next != NULL) {
               if (mode.indent || wordwrap) {
                  /*
                   * autoindentation is required. Match the indentation of
                   *  the first line above that is not blank.
                   */
                  add = find_left_margin( wordwrap == FIXED_WRAP ?
                                          win->ll : win->ll->prev, wordwrap );

                  assert( add >= 0 );
                  assert( add < MAX_LINE_LENGTH );

                  copy_line( win->ll );
                  detab_linebuff( );
                  len = g_status.line_buff_len;
                  source = g_status.line_buff;
                  if (len + add > MAX_LINE_LENGTH)
                     add = MAX_LINE_LENGTH - len;
                  dest = source + add;

                  assert( len >= 0);
                  assert( len < MAX_LINE_LENGTH );

                  memmove( dest, source, len );

                  /*
                   * now put in the autoindent characters
                   */

                  assert( add >= 0 );
                  assert( add < MAX_LINE_LENGTH );

                  memset( source, ' ', add );
                  win->rcol = add;
                  g_status.line_buff_len += add;
                  entab_linebuff( );
                  rc = un_copy_line( win->ll, win, TRUE );
               } else
                  win->rcol = 0;
            }
            if (rc == OK  &&  split_line) {
               win->rline--;
               win->ll = win->ll->prev;
               if (win->cline > win->top_line + window->ruler)
                  win->cline--;
               win->rcol = rcol;
            }
            check_virtual_col( win, win->rcol, win->ccol );
            if (dirty == GLOBAL || file->dirty == LOCAL || wordwrap)
               file->dirty = GLOBAL;
            else
               file->dirty = dirty;
         }
      } else {
         if (new_node != NULL)
            my_free( new_node );
      }
   } else {
      if (new_node != NULL)
         my_free( new_node );
      error( WARNING, window->bottom_line, main4 );
   }

   /*
    * record that file has been modified
    */
   win->visible = TRUE;
   if (rc == OK) {
      if (file->dirty != GLOBAL)
         my_scroll_down( win );
      restore_marked_block( win, 1 );
      show_size( win );
      show_avail_mem( );
      if (old_bcol != win->bcol) {
         make_ruler( win );
         show_ruler( win );
      }
   }
   return( rc );
}


/*
 * Name:    insert_overwrite
 * Purpose: To make the necessary changes after the user has typed a normal
 *           printable character
 * Date:    June 5, 1991
 * Passed:  window:  pointer to current window
 */
int  insert_overwrite( WINDOW *window )
{
char *source;           /* source for block move to make room for c */
char *dest;             /* destination for block move */
int  len;               /* length of current line */
int  pad;               /* padding to add if cursor beyond end of line */
int  add;               /* characters to be added (usually 1 in insert mode) */
register int rcol;
register WINDOW *win;  /* put window pointer in a register */
int  rc;

   win = window;
   if (win->ll->len == EOF || g_status.key_pressed >= 256)
      rc = OK;
   else {
      rcol = win->rcol;
      /*
       * first check we have room - the editor can not
       *  cope with lines wider than g_display.line_length
       */
      if (rcol >= g_display.line_length) {
         /*
          * cannot insert more characters
          */
         error( WARNING, win->bottom_line, ed2 );
         rc = ERROR;
      } else {
         copy_line( win->ll );
         detab_linebuff( );

         /*
          * work out how many characters need to be inserted
          */
         len = g_status.line_buff_len;
         pad = rcol > len ? rcol - len : 0;

         if (mode.insert || rcol >= len)
            /*
             * inserted characters, or overwritten characters at the end of
             *  the line, are inserted.
             */
            add = 1;
         else
            /*
             *  and no extra space is required to overwrite existing characters
             */
            add = 0;

         /*
          * check that current line would not get too long.
          */
         if (len + pad + add >= g_display.line_length) {
            /*
             * no more room to add
             */
            error( WARNING, win->bottom_line, ed3 );
            rc = ERROR;
         } else {

            /*
             * make room for whatever needs to be inserted
             */
            if (pad > 0  || add > 0) {
               source = g_status.line_buff + rcol - pad;
               dest = source + pad + add;

               assert( len + pad - rcol >= 0 );
               assert( len + pad - rcol < MAX_LINE_LENGTH );

               memmove( dest, source, len + pad - rcol );

               /*
                * put in the required padding
                */

               assert( pad >= 0 );
               assert( pad < MAX_LINE_LENGTH );

               memset( source, ' ', pad );
            }
            g_status.line_buff[rcol] = (char)g_status.key_pressed;
            g_status.line_buff_len += pad + add;
            entab_linebuff( );

            /*
             * always increment the real column (rcol) then adjust the
             * logical and base column as needed.   show the changed line
             * in all but the LOCAL window.  In the LOCAL window, there are
             * two cases:  1) update the line, or 2) redraw the window if
             * cursor goes too far right.
             */
            win->file_info->dirty = NOT_LOCAL;
            win->ll->dirty = TRUE;
            show_changed_line( win );
            if (win->ccol < win->end_col) {
               show_curl_line( win );
               show_ruler_char( win );
               win->ccol++;
            } else {
               win->bcol++;
               win->file_info->dirty = LOCAL;
               make_ruler( win );
               show_ruler( win );
            }
            rcol++;
         }

         /*
          * record that file has been modified and adjust cursors,
          * file start and end pointers as needed.
          */
         check_virtual_col( win, rcol, win->ccol );
         win->file_info->modified = TRUE;
         if (mode.word_wrap) {
            add = mode.right_justify;
            mode.right_justify = FALSE;
            g_status.command = FormatText;
            word_wrap( win );
            mode.right_justify = add;
         }
         rc = OK;
      }
   }
   return( rc );
}


/*
 * Name:    join_line
 * Purpose: To join current line and line below at cursor
 * Date:    June 5, 1991
 * Passed:  window:  pointer to current window
 * Notes:   trunc the line.  then, join with line below, if it exists.
 */
int  join_line( WINDOW *window )
{
int  len;               /* length of current line */
int  new_len;           /* length of the joined lines */
int  next_len;          /* length of the line below current line */
text_ptr q;             /* next line in file */
text_ptr tab_free;      /* next line in file -- with the tabs removed */
int  pad;               /* padding spaces required */
register WINDOW *win;   /* put window pointer in a register */
WINDOW *wp;
line_list_ptr next_node;
int  rc;

   win = window;
   if (win->ll->len == EOF  ||  win->ll->next->len == EOF)
      return( ERROR );

   rc = OK;

   assert( win->ll->next != NULL );

   next_node = win->ll->next;
   load_undo_buffer( win->file_info, win->ll->line, win->ll->len );
   copy_line( win->ll );
   detab_linebuff( );

   /*
    * if cursor is in line before eol, reset len to rcol
    */
   if (win->rcol < (len = g_status.line_buff_len))
      len = win->rcol;

   /*
    * calculate needed padding
    */
   pad = win->rcol > len ? win->rcol - len : 0;

   assert( pad >= 0 );

⌨️ 快捷键说明

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