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

📄 ed.c

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

   /*
    * if there any tabs in the next line, expand them because we
    *   probably have to redo them anyway.
    */
   next_len = next_node->len;
   tab_free = detab_a_line( next_node->line, &next_len );

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

   /*
    * check room to combine lines
    */
   new_len = len + pad + next_len;
   if (new_len >= g_display.line_length) {
      /*
       * cannot combine lines.
       */
      error( WARNING, win->bottom_line, ed4 );
      rc = ERROR;
   } else {
      if (mode.do_backups == TRUE) {
         win->file_info->modified = TRUE;
         rc = backup_file( win );
      }
      q = (text_ptr)(g_status.line_buff + len);
      /*
       * insert padding
       */
      if (pad > 0) {
         while (pad--)
            *q++ = ' ';
      }
      _fmemcpy( q, tab_free, next_len );
      g_status.line_buff_len = new_len;
      entab_linebuff( );

      if ((rc = un_copy_line( win->ll, win, FALSE )) == OK) {

         if (next_node->next != NULL)
            next_node->next->prev = win->ll;
         win->ll->next = next_node->next;
         win->ll->dirty = TRUE;

         --win->file_info->length;
         ++win->rline;
         adjust_windows_cursor( win, -1 );
         restore_marked_block( win, -1 );
         --win->rline;

         wp = g_status.window_list;
         while (wp != NULL) {
            if (wp->file_info == win->file_info) {
               /*
                * make sure none of the window pointers point to the
                *   node we are about to delete.
                */
               if (wp != win) {
                  if (wp->ll == next_node)
                     wp->ll = win->ll->next;
               }
            }
            wp = wp->next;
         }

         /*
          * now, it's safe to delete the next_node line as well as
          *   the next node.
          */
         if (next_node->line != NULL)
            my_free( next_node->line );
         my_free( next_node );

         show_size( win );
         show_avail_mem( );
         win->file_info->dirty = GLOBAL;
      }
   }
   return( rc );
}


/*
 * Name:    word_delete
 * Purpose: To delete from the cursor to the start of the next word.
 * Date:    September 1, 1991
 * Passed:  window:  pointer to current window
 * Notes:   If the cursor is at the right of the line, then combine the
 *           current line with the next one, leaving the cursor where it
 *           is.
 *          If the cursor is on an alphanumeric character, then all
 *           subsequent alphanumeric characters are deleted.
 *          If the cursor is on a space, then all subsequent spaces
 *           are deleted.
 *          If the cursor is on a punctuation character, then all
 *           subsequent punctuation characters are deleted.
 */
int  word_delete( WINDOW *window )
{
int  len;               /* length of current line */
int  count;             /* number of characters deleted from line */
register int start;     /* column that next word starts in */
char *source;           /* source for block move to delete word */
char *dest;             /* destination for block move */
text_ptr p;
register WINDOW *win;   /* put window pointer in a register */
int  rc;

   win = window;
   if (win->rline > win->file_info->length  || win->ll->len == EOF)
      return( ERROR );

   rc = OK;
   copy_line( win->ll );
   detab_linebuff( );
   if (win->rcol >= (len = g_status.line_buff_len)) {
      rc = join_line( win );
      if (rc == OK) {
         p = win->ll->line;
         if (p != NULL) {
            p += win->rcol;
            if (win->rcol < win->ll->len) {
               len = win->ll->len - win->rcol;
               load_undo_buffer( win->file_info, p, len );
            }
         }
      }
   } else {

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

      /*
       * normal word delete
       *
       * find the start of the next word
       */
      start = win->rcol;
      if (isspace( g_status.line_buff[start] )) {
         /*
          * the cursor was on a space, so eat all consecutive spaces
          *  from the cursor onwards.
          */
         while (start < len  &&  isspace( g_status.line_buff[start] ))
            ++start;
      } else {
         /*
          * eat all consecutive characters in the same class (spaces
          *  are considered to be in the same class as the cursor
          *  character)
          */
         while (start < len  &&  !isspace( g_status.line_buff[start] ))
            ++start;
         while (start < len  &&  isspace( g_status.line_buff[start] ))
            ++start;
      }

      /*
       * move text to delete word
       */
      count = start - win->rcol;
      source = g_status.line_buff + start;
      dest = g_status.line_buff + win->rcol;

      assert( len - start >= 0 );

      memmove( dest, source, len - start );
      g_status.line_buff_len = len - count;
      entab_linebuff( );
      win->file_info->modified = TRUE;
      win->file_info->dirty = GLOBAL;
      win->ll->dirty = TRUE;

      /*
       * word_delete is also called by the word processing functions to get
       *   rid of spaces.
       */
      if (g_status.command == WordDelete)
         show_changed_line( win );
   }
   return( rc );
}


/*
 * Name:    dup_line
 * Purpose: Duplicate current line
 * Date:    June 5, 1991
 * Passed:  window:  pointer to current window
 * Notes:   cursor stays on current line
 */
int  dup_line( WINDOW *window )
{
register int len;       /* length of current line */
text_ptr p;
register WINDOW *win;   /* put window pointer in a register */
line_list_ptr next_node;
int  rc;

   win = window;

   /*
    * don't dup a NULL line
    */
   if (win->rline > win->file_info->length  ||  win->ll->len == EOF)
      return( ERROR );

   entab_linebuff( );
   rc = un_copy_line( win->ll, win, TRUE );
   len = win->ll->len;

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

   p = NULL;
   next_node = NULL;
   if (rc == OK) {
      p = (text_ptr)my_malloc( len, &rc );
      next_node = (line_list_ptr)my_malloc( sizeof(line_list_struc), &rc );
   }

   if (rc == OK) {
      win->file_info->modified = TRUE;
      if (mode.do_backups == TRUE)
         rc = backup_file( win );
      ++win->file_info->length;

      if (len > 0)
         _fmemcpy( p, win->ll->line, len );

      next_node->line  = p;
      next_node->dirty = TRUE;
      next_node->len   = len;

      if (win->ll->next != NULL)
         win->ll->next->prev = next_node;

      next_node->next = win->ll->next;
      next_node->prev = win->ll;
      win->ll->next = next_node;

      adjust_windows_cursor( win, 1 );

      /*
       * if current line is the bottom line, we can't see the dup line because
       * cursor doesn't move and dup line is added after current line.
       */
      if  (win->cline != win->bottom_line)
         my_scroll_down( win );
      win->file_info->dirty = NOT_LOCAL;

      /*
       * record that file has been modified
       */
      restore_marked_block( win, 1 );
      show_size( win );
      show_avail_mem( );
   } else {
      /*
       * cannot duplicate line
       */
      if (p != NULL)
         my_free( p );
      if (next_node != NULL)
         my_free( next_node );
      error( WARNING, win->bottom_line, ed5 );
   }
   return( rc );
}


/*
 * Name:    back_space
 * Purpose: To delete the character to the left of the cursor.
 * Date:    June 5, 1991
 * Passed:  window:  pointer to current window
 * Notes:   If the cursor is at the left of the line, then combine the
 *           current line with the previous one.
 *          If in indent mode, and the cursor is on the first non-blank
 *           character of the line, then match the indentation of an
 *           earlier line.
 */
int  back_space( WINDOW *window )
{
int  rc;                /* return code */
int  len;               /* length of the current line */
char *source;           /* source of block move to delete character */
char *dest;             /* destination of block move */
text_ptr p;             /* previous line in file */
int  plen;              /* length of previous line */
int  del_count;         /* number of characters to delete */
int  pos;               /* the position of the first non-blank char */
register int rcol;
int  ccol;
int  old_bcol;
register WINDOW *win;  /* put window pointer in a register */
WINDOW *wp;
line_list_ptr temp_ll;

   win = window;
   if (win->rline > win->file_info->length || win->ll->len == EOF)
      return( ERROR );
   rc = OK;
   copy_line( win->ll );
   detab_linebuff( );
   len = g_status.line_buff_len;
   rcol = win->rcol;
   ccol = win->ccol;
   old_bcol = win->bcol;
   if (rcol == 0) {
      if (win->rline > 1) {
         /*
          * combine this line with the previous, if any
          */

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

         p = win->ll->prev->line;
         plen = win->ll->prev->len;
         if (len + 2 + plen >= g_display.line_length) {
            /*
             * cannot combine lines
             */
            error( WARNING, win->bottom_line, ed4 );
            return( ERROR );
         }

         win->file_info->modified = TRUE;
         if ((rc = un_copy_line( win->ll, win, TRUE )) == OK) {
            --win->rline;
            win->ll = win->ll->prev;
            win->bin_offset -= win->ll->len;
            win->ll->dirty = TRUE;
            copy_line( win->ll );
            detab_linebuff( );
            len = g_status.line_buff_len;
            rcol = len;

            p = win->ll->next->line;
            plen = win->ll->next->len;

            /*
             * copy previous line into new previous line.
             */
            assert( plen >= 0 );
            assert( len  >= 0 );

            _fmemcpy( g_status.line_buff+len, p, plen );
            g_status.line_buff_len = len + plen;

            load_undo_buffer( win->file_info, p, plen );
            if (p != NULL)
               my_free( p );

            temp_ll = win->ll->next;

            if (temp_ll->prev != NULL)
               temp_ll->prev->next = temp_ll->next;
            temp_ll->next->prev = temp_ll->prev;

            --win->file_info->length;
            ++win->rline;
            restore_marked_block( win, -1 );
            adjust_windows_cursor( win, -1 );
            --win->rline;

            wp = g_status.window_list;
            while (wp != NULL) {
               if (wp->file_info == win->file_info) {
                  if (wp != win) {
                     if (wp->ll == temp_ll)
                        wp->ll = win->ll->next;
                  }
               }
               wp = wp->next;
            }

            my_free( temp_ll );

            if (win->cline > win->top_line + win->ruler)
               --win->cline;

            /*
             * make sure cursor stays on the screen, at the end of the
             *  previous line
             */
            ccol = rcol - win->bcol;
            show_size( win );
            show_avail_mem( );
            check_virtual_col( win, rcol, ccol );
            win->file_info->dirty = GLOBAL;
            make_ruler( win );
            show_ruler( win );
         }
      } else
         return( ERROR );
   } else {
      /*
       * normal delete
       *
       * find out how much to delete (depends on indent mode)
       */
      del_count = 1;   /* the default */
      if (mode.indent) {
         /*
          * indent only happens if the cursor is on the first
          *  non-blank character of the line
          */
         pos = first_non_blank( (text_ptr)g_status.line_buff, len );
         if (pos == rcol  ||
                         is_line_blank( (text_ptr)g_status.line_buff, len )) {
            /*
             * now work out how much to indent
             */
            temp_ll = win->ll->prev;
            for (; temp_ll != NULL; temp_ll=temp_ll->prev) {
               p = temp_ll->line;
               plen = first_non_blank( p, temp_ll->len );
               if (plen < rcol  &&  plen != temp_ll->len) {
                  /*
                   * found the line to match
                   */
                  del_count = rcol - plen;
                  break;
               }
            }
         }
      }

      /*
       * move text to delete char(s), unless no chars actually there
       */
      if (rcol - del_count < len) {
         dest = g_status.line_buff + rcol - del_count;

⌨️ 快捷键说明

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