📄 history.c
字号:
/* 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 + -