📄 term.c
字号:
/* terminal control module for terminals described by TERMCAP Copyright (C) 1985, 1986, 1987 Free Software Foundation, Inc.This file is part of GNU Emacs.GNU Emacs is free software; you can redistribute it and/or modifyit under the terms of the GNU General Public License as published bythe Free Software Foundation; either version 1, or (at your option)any later version.GNU Emacs is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; without even the implied warranty ofMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See theGNU General Public License for more details.You should have received a copy of the GNU General Public Licensealong with GNU Emacs; see the file COPYING. If not, write tothe Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */#include <stdio.h>#include <ctype.h>#include "config.h"#include "termhooks.h"#include "termchar.h"#include "termopts.h"#include "cm.h"#define max(a, b) ((a) > (b) ? (a) : (b))#define min(a, b) ((a) < (b) ? (a) : (b))#define OUTPUT(a) tputs (a, screen_height - curY, cmputc)#define OUTPUT1(a) tputs (a, 1, cmputc)#define OUTPUTL(a, lines) tputs (a, lines, cmputc)#define OUTPUT_IF(a) { if (a) tputs (a, screen_height - curY, cmputc); }#define OUTPUT1_IF(a) { if (a) tputs (a, 1, cmputc); }/* Terminal charateristics that higher levels want to look at. These are all extern'd in termchar.h */int screen_width; /* Number of usable columns */int screen_height; /* Number of lines */int must_write_spaces; /* Nonzero means spaces in the text must actually be output; can't just skip over some columns to leave them blank. */int min_padding_speed; /* Speed below which no padding necessary */int line_ins_del_ok; /* Terminal can insert and delete lines */int char_ins_del_ok; /* Terminal can insert and delete chars */int scroll_region_ok; /* Terminal supports setting the scroll window */int memory_below_screen; /* Terminal remembers lines scrolled off bottom */int fast_clear_end_of_line; /* Terminal has a `ce' string */int dont_calculate_costs; /* Nonzero means don't bother computing */ /* various cost tables; we won't use them. *//* Nonzero means no need to redraw the entire screen on resuming a suspended Emacs. This is useful on terminals with multiple pages, where one page is used for Emacs and another for all else. */int no_redraw_on_reenter;/* DCICcost[n] is cost of inserting N characters. DCICcost[-n] is cost of deleting N characters. */#define DCICcost (&DC_ICcost[screen_width])int *DC_ICcost;/* Hook functions that you can set to snap out the functions in this file. These are all extern'd in termhooks.h */int (*move_cursor_hook) ();int (*raw_move_cursor_hook) ();int (*clear_to_end_hook) ();int (*clear_screen_hook) ();int (*clear_end_of_line_hook) ();int (*ins_del_lines_hook) ();int (*change_line_highlight_hook) ();int (*reassert_line_highlight_hook) ();int (*insert_chars_hook) ();int (*output_chars_hook) ();int (*delete_chars_hook) ();int (*ring_bell_hook) ();int (*reset_terminal_modes_hook) ();int (*set_terminal_modes_hook) ();int (*update_begin_hook) ();int (*update_end_hook) ();int (*set_terminal_window_hook) ();int (*read_socket_hook) ();int (*fix_screen_hook) ();int (*calculate_costs_hook) ();/* Strings, numbers and flags taken from the termcap entry. */char *TS_ins_line; /* termcap "al" */char *TS_ins_multi_lines; /* "AL" (one parameter, # lines to insert) */char *TS_bell; /* "bl" */char *TS_clr_to_bottom; /* "cd" */char *TS_clr_line; /* "ce", clear to end of line */char *TS_clr_screen; /* "cl" */char *TS_set_scroll_region; /* "cs" (2 params, first line and last line) */char *TS_set_scroll_region_1; /* "cS" (4 params: total lines, lines above scroll region, lines below it, total lines again) */char *TS_del_char; /* "dc" */char *TS_del_multi_chars; /* "DC" (one parameter, # chars to delete) */char *TS_del_line; /* "dl" */char *TS_del_multi_lines; /* "DL" (one parameter, # lines to delete) */char *TS_delete_mode; /* "dm", enter character-delete mode */char *TS_end_delete_mode; /* "ed", leave character-delete mode */char *TS_end_insert_mode; /* "ei", leave character-insert mode */char *TS_ins_char; /* "ic" */char *TS_ins_multi_chars; /* "IC" (one parameter, # chars to insert) */char *TS_insert_mode; /* "im", enter character-insert mode */char *TS_pad_inserted_char; /* "ip". Just padding, no commands. */char *TS_end_keypad_mode; /* "ke" */char *TS_keypad_mode; /* "ks" */char *TS_pad_char; /* "pc", char to use as padding */char *TS_repeat; /* "rp" (2 params, # times to repeat and character to be repeated) */char *TS_end_standout_mode; /* "se" */char *TS_fwd_scroll; /* "sf" */char *TS_standout_mode; /* "so" */char *TS_rev_scroll; /* "sr" */char *TS_end_termcap_modes; /* "te" */char *TS_termcap_modes; /* "ti" */char *TS_visible_bell; /* "vb" */char *TS_end_visual_mode; /* "ve" */char *TS_visual_mode; /* "vi" */char *TS_set_window; /* "wi" (4 params, start and end of window, each as vpos and hpos) */int TF_hazeltine; /* termcap hz flag. */int TF_insmode_motion; /* termcap mi flag: can move while in insert mode. */int TF_standout_motion; /* termcap mi flag: can move while in standout mode. */int TF_underscore; /* termcap ul flag: _ underlines if overstruck on nonblank position. Must clear before writing _. */int TF_teleray; /* termcap xt flag: many weird consequences. For t1061. */int TF_xs; /* Nonzero for "xs". If set together with TN_standout_width == 0, it means don't bother to write any end-standout cookies. */int TN_standout_width; /* termcap sg number: width occupied by standout markers */static int RPov; /* # chars to start a TS_repeat */static int delete_in_insert_mode; /* delete mode == insert mode */static int se_is_so; /* 1 if same string both enters and leaves standout mode *//* internal state *//* Number of chars of space used for standout marker at beginning of line, or'd with 0100. Zero if no standout marker at all. *//* used iff TN_standout_width >= 0. */char *chars_wasted;static char *copybuf;/* nonzero means supposed to write text in standout mode. */int standout_requested;int insert_mode; /* Nonzero when in insert mode. */int standout_mode; /* Nonzero when in standout mode. *//* Size of window specified by higher levels. This is the number of lines, starting from top of screen, to participate in ins/del line operations. Effectively it excludes the bottom screen_height - specified_window_size lines from those operations. */int specified_window;char *tparam ();ring_bell (){ if (ring_bell_hook) { (*ring_bell_hook) (); return; } OUTPUT (TS_visible_bell && visible_bell ? TS_visible_bell : TS_bell);}set_terminal_modes (){ if (set_terminal_modes_hook) { (*set_terminal_modes_hook) (); return; } OUTPUT_IF (TS_termcap_modes); OUTPUT_IF (TS_visual_mode); OUTPUT_IF (TS_keypad_mode); losecursor ();}reset_terminal_modes (){ if (reset_terminal_modes_hook) { (*reset_terminal_modes_hook) (); return; } if (TN_standout_width < 0) turn_off_highlight (); turn_off_insert (); OUTPUT_IF (TS_end_keypad_mode); OUTPUT_IF (TS_end_visual_mode); OUTPUT_IF (TS_end_termcap_modes);}update_begin (){ if (update_begin_hook) (*update_begin_hook) ();}update_end (){ if (update_end_hook) { (*update_end_hook) (); return; } turn_off_insert (); background_highlight (); standout_requested = 0;}set_terminal_window (size) int size;{ if (set_terminal_window_hook) { (*set_terminal_window_hook) (size); return; } specified_window = size ? size : screen_height; if (!scroll_region_ok) return; set_scroll_region (0, specified_window);}set_scroll_region (start, stop) int start, stop;{ char *buf; if (TS_set_scroll_region) { buf = tparam (TS_set_scroll_region, 0, 0, start, stop - 1); } else if (TS_set_scroll_region_1) { buf = tparam (TS_set_scroll_region_1, 0, 0, screen_height, start, screen_height - stop, screen_height); } else { buf = tparam (TS_set_window, 0, 0, start, 0, stop, screen_width); } OUTPUT (buf); free (buf); losecursor ();}turn_on_insert (){ if (!insert_mode) OUTPUT (TS_insert_mode); insert_mode = 1;}turn_off_insert (){ if (insert_mode) OUTPUT (TS_end_insert_mode); insert_mode = 0;}/* Handle highlighting when TN_standout_width (termcap sg) is not specified. In these terminals, output is affected by the value of standout mode when the output is written. These functions are called on all terminals, but do nothing on terminals whose standout mode does not work that way. */turn_off_highlight (){ if (TN_standout_width < 0) { if (standout_mode) OUTPUT_IF (TS_end_standout_mode); standout_mode = 0; }}turn_on_highlight (){ if (TN_standout_width < 0) { if (!standout_mode) OUTPUT_IF (TS_standout_mode); standout_mode = 1; }}/* Set standout mode to the state it should be in for empty space inside windows. What this is, depends on the user option inverse-video. */background_highlight (){ if (TN_standout_width >= 0) return; if (inverse_video) turn_on_highlight (); else turn_off_highlight ();}/* Set standout mode to the mode specified for the text to be output. */statichighlight_if_desired (){ if (TN_standout_width >= 0) return; if (!inverse_video == !standout_requested) turn_off_highlight (); else turn_on_highlight ();}/* Handle standout mode for terminals in which TN_standout_width >= 0. On these terminals, standout is controlled by markers that live inside the screen memory. TN_standout_width is the width that the marker occupies in memory. Standout runs from the marker to the end of the line on some terminals, or to the next turn-off-standout marker (TS_end_standout_mode) string on other terminals. *//* Write a standout marker or end-standout marker at the front of the line at vertical position vpos. */write_standout_marker (flag, vpos) int flag, vpos;{ if (flag || (TS_end_standout_mode && !TF_teleray && !se_is_so && !(TF_xs && TN_standout_width == 0))) { cmgoto (vpos, 0); cmplus (TN_standout_width); OUTPUT (flag ? TS_standout_mode : TS_end_standout_mode); chars_wasted[curY] = TN_standout_width | 0100; }}/* External interface to control of standout mode. Call this when about to modify line at position VPOS and not change whether it is highlighted. */reassert_line_highlight (highlight, vpos) int highlight; int vpos;{ if (reassert_line_highlight_hook) { (*reassert_line_highlight_hook) (highlight, vpos); return; } if (TN_standout_width < 0) /* Handle terminals where standout takes affect at output time */ standout_requested = highlight; else if (chars_wasted[vpos] == 0) /* For terminals with standout markers, write one on this line if there isn't one already. */ write_standout_marker (highlight, vpos);}/* Call this when about to modify line at position VPOS and change whether it is highlighted. */change_line_highlight (new_highlight, vpos, first_unused_hpos) int new_highlight, vpos, first_unused_hpos;{ standout_requested = new_highlight; if (change_line_highlight_hook) { (*change_line_highlight_hook) (new_highlight, vpos, first_unused_hpos); return; } move_cursor (vpos, 0); if (TN_standout_width < 0) background_highlight (); /* If line starts with a marker, delete the marker */ else if (TS_clr_line && chars_wasted[curY]) { turn_off_insert (); /* On Teleray, make sure to erase the SO marker. */ if (TF_teleray) { cmgoto (curY - 1, screen_width - 4); OUTPUT ("\033S");
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -