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

📄 history.c

📁 功能强大的文本编辑器
💻 C
📖 第 1 页 / 共 2 页
字号:
/*      history.c                           14.02.04       */
/*!
/  --------------------------------------------------------------
/  Copyright (C) 1993: Michael Braun
/                      Kaetinger Muehlenweg 103 A
/                      D-28816 Stuhr
/  --------------------------------------------------------------
/
/    handling of history buffers / history file
/
*/

/****************************************************************
*                                                               *
*  BENUTZTE UNTERPROGRAMME (C LIBRARY)                          *
*                                                               *
****************************************************************/

#include "config.h"
#include "standard.h"
#include "global.h"
#include "history.h"
#include "disp_hnd.h"
#include "perform.h"
#include "kb_input.h"
#include "mon_outp.h"
#include "err_mess.h"
#include "mousec.h"


/****************************************************************
*                                                               *
*  BENUTZTE UNTERPROGRAMME / GLOBALE VARIABLEN                  *
*                                                               *
****************************************************************/

#define SMALL_BUFFERS_WG_CODEVIEW 0

/* zum debuggen kann der history-buffer verkleinert werden,   */
/* codeview nimmt sonst zuviel speicher weg. das abspeichern  */
/* des history-buffers im file wird in dem fall unterdrueckt. */


/* buffer speichert strings in voller laenge ab.        */
/* dargestellt werden nur die ersten window_length chars. */

#if SMALL_BUFFERS_WG_CODEVIEW
#define BUFFER_SIZE 2           /* fuer debug */
#else
#define BUFFER_SIZE BUF_256     /* normal */
#endif

struct HIST {char delete_protected;
             char text [BUFFER_SIZE];
            };

static struct HIST hist [HIST_NUM] [HIST_SIZE];

#define max_text   sizeof (hist [0][0].text)
#define max_total  sizeof (hist [0][0])

static int window_length;    /* = f (strlen (...text)) */

/* -FF-  */

/* Darstellung des History Windows */

/* PROM-Tabelle */
static const char semi_grafik [] [4]      /* 2. index = 0 : ASCII  */
                                          /*          = 1 : VGA    */
                                          /*          = 2 : VT100  */
                                          /*          = 3 : ANSI   */
                = {  /*  0           1     2    3   */
   /* DEL_PROT_CHAR */  '*',  (char)254,  '*', '*',   /* 0xfe */
                                               
   /* GR_TOP_LEFT   */  '+',  (char)218,  'l', 'Z',   /* 0xda */
   /* GR_TOP_RIGHT  */  '+',  (char)191,  'k', '?',   /* 0xbf */
   /* GR_BOT_LEFT   */  '+',  (char)192,  'm', '@',   /* 0xc0 */
   /* GR_BOT_RIGHT  */  '+',  (char)217,  'j', 'Y',   /* 0xd9 */
                                                     
   /* GR_TICK_RIGHT */  '+',  (char)195,  't', '4',   /* 0xc3 */
   /* GR_TICK_LEFT  */  '+',  (char)180,  'u', 'C',   /* 0xb4 */
   /* GR_TICK_DOWN  */  '+',  (char)194,  'w', 'B',   /* 0xc2 */
   /* GR_TICK_UP    */  '+',  (char)193,  'v', 'A',   /* 0xc1 */
                                                     
   /* GR_VERTICAL   */  '|',  (char)179,  'x', '3',   /* 0xb3 */
   /* GR_HORIZONT   */  '-',  (char)196,  'q', 'D',   /* 0xc4 */
   /* GR_CROSS      */  '+',  (char)197,  'n', 'E'    /* 0xc5 */
                  };

enum SEMIGRAF_INDEX
       {
         IND_DEL_PROT_CHAR,

         IND_GR_TOP_LEFT,
         IND_GR_TOP_RIGHT,
         IND_GR_BOT_LEFT,
         IND_GR_BOT_RIGHT,

         IND_GR_TICK_RIGHT,
         IND_GR_TICK_LEFT,
         IND_GR_TICK_DOWN,
         IND_GR_TICK_UP,

         IND_GR_VERTICAL,
         IND_GR_HORIZONT,
         IND_GR_CROSS
       };


#define DEL_PROT_CHAR  (semi_grafik [IND_DEL_PROT_CHAR] [graf_index])

#define GR_TOP_LEFT    (semi_grafik [IND_GR_TOP_LEFT]   [graf_index])
#define GR_TOP_RIGHT   (semi_grafik [IND_GR_TOP_RIGHT]  [graf_index])
#define GR_BOT_LEFT    (semi_grafik [IND_GR_BOT_LEFT]   [graf_index])
#define GR_BOT_RIGHT   (semi_grafik [IND_GR_BOT_RIGHT]  [graf_index])
   
#define GR_TICK_RIGHT  (semi_grafik [IND_GR_TICK_RIGHT] [graf_index])
#define GR_TICK_LEFT   (semi_grafik [IND_GR_TICK_LEFT]  [graf_index])
#define GR_TICK_DOWN   (semi_grafik [IND_GR_TICK_DOWN]  [graf_index])
#define GR_TICK_UP     (semi_grafik [IND_GR_TICK_UP]    [graf_index])
   
#define GR_VERTICAL    (semi_grafik [IND_GR_VERTICAL]   [graf_index])
#define GR_HORIZONT    (semi_grafik [IND_GR_HORIZONT]   [graf_index])
#define GR_CROSS       (semi_grafik [IND_GR_CROSS]      [graf_index])


static int graf_index = (ACT_SERVER == SERVER_VT_100);

/* only one array for all functions: NEW !! 23.06.94 */
static char pathname [BUF_256 + FILENAME_LEN]; 


/****************************************************************
*                                                               *
*  ENDE DER DEKLARATIONEN                                       *
*                                                               *
****************************************************************/

/* -FF-  */

#if 0

   format of entries in (binary) history-file :
   ============================================
   
   3 1:the quick brown fox ...'\0'<cr><lf>
   | |||                      |   |
   | |||                      |   +-- for possible editing with any text-editor
   | |||                      |
   | |||                      +-- end of string
   | |||
   | ||+-- text with all ASCII-characters except '\0'
   | ||
   | |+-- marker for begin of text
   | |
   | +-- delete protected
   |
   +-- history id

#endif

/* -FF-  */

void set_grafik_status (int flag)
{
/* flag   graf_index   mode  */
/* ------------------------- */
/*   0 -----> 0        ASCII */
/*   1 --+--> 1        VGA   */
/*   1   `--> 2        VT100 */
/*   2 -----> 3        ANSI  */

   if      (flag == 1) graf_index = 1 + (ACT_SERVER == SERVER_VT_100);
   else if (flag == 2) graf_index = 3;   /* ANSI    */
   else if (flag == 3) graf_index = 1;   /* ANSI/PC */
   else                graf_index = 0;   /* ASCII   */

   return;
}  /* set_grafik_status */

/* -FF-  */

void plot_rectangle (int top, int left, int bot, int right)
{
/* plot rectangle with given koordinates on screen. */

/* the upper left corner has coordinates (0,0) */

int row, col;

   push_cursor ();

   if (graf_index >= 2)
      set_grafik_on (graf_index-2);

/* 1. upper horizontal line (incl. corners) */
   row = top;
   col = left;
   set_cursor_to (row, col);

   out_1_char (GR_TOP_LEFT, 1);
   for (col = (left + 1) ; col < right ; col++)
   {
      out_1_char (GR_HORIZONT, 1);
   }
   out_1_char (GR_TOP_RIGHT, 1);


/* 2. lower horizontal line (incl. corners) */
   row = bot;
   col = left;
   set_cursor_to (row, col);

   out_1_char (GR_BOT_LEFT, 1);
   for (col = (left + 1) ; col < right ; col++)
   {
      out_1_char (GR_HORIZONT, 1);
   }
   out_1_char (GR_BOT_RIGHT, 1);


/* 3. left vertical line (excl. corners) */
   col = left;
   for (row = (top + 1) ; row < bot ; row++)
   {
      set_cursor_to (row, col);
      out_1_char (GR_VERTICAL, 1);
   }


/* 4. right vertical line (excl. corners) */
   col = right;
   for (row = (top + 1) ; row < bot ; row++)
   {
      set_cursor_to (row, col);
      out_1_char (GR_VERTICAL, 1);
   }


#if 0
/* 5. clear content of window */
   for (row = (top + 1) ; row < bot ; row++)
   {
      col = left + 1;
      set_cursor_to (row, col);
      for (col = (left + 1) ; col < right ; col++)
      {
         out_1_char (' ', 1);
      }
   }
#endif

   if (graf_index >= 2)
      set_grafik_off (graf_index-2);

   pop_cursor ();

   return;
   
}  /* plot_rectangle */

/* -FF-  */

static void plot_content (enum HIST_ID id, int select_line)
{
int entry;

/* loop for all entries up to the selected one */
   for (entry = (HIST_SIZE-1) ; entry >= select_line ; entry--)
   {
      print_history_line (id, entry, (entry == select_line), 1);
   }

   return;
}  /* plot_content */

/* -FF-  */

static int top, left, bot, right;

static void plot_history_window (enum HIST_ID id)
{
int  entry, max_len, dummy, len;

   push_cursor ();


/* bestimme max. laenge aller eintraege dieser history id */
   max_len = 0;
   for (entry = 0 ; entry < HIST_SIZE ; entry++)
   {
      len = strlen (build_modified_string (hist [id] [entry].text, 0,
                                           &dummy, &dummy));
      max_len = max (max_len, len);
   }

/* begrenzen */
   max_len = max (max_len, HIST_MIN_LEN);
   max_len = min (max_len, HIST_MAX_LEN);   
   max_len = min (max_len, (COLUMNS - 5));  

   window_length = max_len + 1;   /* 1 byte for DELETE_PROT_CHAR */


/* fenster mitten auf bildschirm */
   top   = (ROWS    - (HIST_SIZE     + 2)) / 2;
   left  = (COLUMNS - (window_length + 2)) / 2;
   bot   = top  + (HIST_SIZE     + 1);
   right = left + (window_length + 1);

/* begrenzen */
   top  = max (0, top);
   left = max (0, left);

/* plotten */
   plot_rectangle (top, left, bot, right);


/* history inhalt plotten */
   plot_content (id, 0);

   pop_cursor ();

   return;

}  /* plot_history_window */

/* -FF-  */

static void print_history_line (enum HIST_ID id, int entry,
                                int select_flag, int modified)
{
int row, col, dummy;
char line_buf [HIST_MAX_LEN+1];
int ii;

   push_cursor ();

   row = bot - 1 - entry;
   col = left + 1;

   if (hist [id] [entry].delete_protected)
      line_buf [0] = DEL_PROT_CHAR;
   else
      line_buf [0] = ' ';

   strncpy (&line_buf [1],
            build_modified_string (hist [id] [entry].text, 0,
                                   &dummy, &dummy),
            (window_length - 1));
   line_buf [window_length] = '\0';   /* forced end of string */

   set_cursor_to (row, col);

/* display 1 line */
   out_1_char (line_buf[0], 0);

   if (select_flag) set_invers_mode ();
   out_string (&line_buf[1]);

#if (!INVERT_WHOLE_LINE)
   if (select_flag) set_normal_mode ();
#endif

   if ((INVERT_WHOLE_LINE) || (modified))
   {
      for (ii = strlen (line_buf) ; ii < window_length ; ii++)
      {
         out_1_char (' ', 0);    /* fill rest of line with blanks */
      }
   }

#if (INVERT_WHOLE_LINE)
   if (select_flag) set_normal_mode ();
#endif

/* cursor to end of line */
   if (select_flag)
      set_cursor_to (row, right);

   pop_cursor ();

   return;
}  /* print_history_line */

/* -FF-  */

char *get_history_buffer (enum HIST_ID id)
{
int entry, key, ii, return_flag;
char *return_text = NULL;

/* video output ON ? */
   if (!get_video_active (0)) return NULL;

   entry = 0;
   plot_history_window (id);

#if (WITH_MOUSE)
   MouSetMoveArea (0,   0,
                   0, 255,
                   1);
#endif

#if (ACT_SERVER == SERVER_VT_100)
   text_area++;
#endif

/* command loop */
   return_flag = 0;
   while (return_flag == 0)
   {
      key = get_1_key (0);
      switch (key)
      {
         case KEY_UP:
            print_history_line (id, entry, 0, 0);
            entry = (entry + 1) % HIST_SIZE;
            print_history_line (id, entry, 1, 0);
            break;

         case KEY_DOWN:
            print_history_line (id, entry, 0, 0);
            entry = ((entry - 1) + HIST_SIZE) % HIST_SIZE;
            print_history_line (id, entry, 1, 0);
            break;

#if (ACT_OP_SYSTEM == SCO_UNIX)
         case KEY_RUBOUT:    /* rubout */
#endif
         case KEY_DEL:
            if (hist [id][entry].delete_protected)
            {
               beep ();
            }
            else
            {
               for (ii = entry ; ii < (HIST_SIZE-1) ; ii++)
               {
                  memcpy (&hist [id][ii], &hist [id][ii+1], max_total);
               }
               memset (&hist [id][HIST_SIZE-1], 0, max_total);
            }
            plot_content (id, entry);
            write_history_file (0);
            break;

         case KEY_INS:
            if (*hist [id][entry].text)               /* no empty lines */
            {
               hist [id][entry].delete_protected++;   /* toggle protect mode */
               hist [id][entry].delete_protected &= 1;
               print_history_line (id, entry, 1, 0);
               write_history_file (0);
            }
            break;

#if (VAR_EOLN)
         case 0x0d:    /* <cr>     */
         case 0x0a:    /* <lf>     */
         case 0x0d0a:  /* <cr><lf> */
#else
         case C_R:     /* <cr> */
#endif
            refresh_display_window (top, left, bot, right);
            return_flag = 1;
            return_text = hist [id][entry].text;
            break;

         case 0x1b:    /* <esc> */
         case 0x03:    /* ^C */
            refresh_display_window (top, left, bot, right);
            return_flag = 1;
            return_text = NULL;
            break;

         case KEY_DO_NOTHING:
            break;

         default:
            beep ();
            break;
      }
   }  /* while */

#if (WITH_MOUSE)
   MouSetMoveArea ( 0                , (byte) TOP_ROW,
                   (byte) (COLUMNS-1), (byte) MAX_ROW,
                    -1);
#endif

#if (ACT_SERVER == SERVER_VT_100)
   text_area--;

⌨️ 快捷键说明

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