📄 query.c
字号:
/* * This file was originally console.c, but I split that into three separate * files for each of the systems. These query functions were what was left * over - jmh. * * New editor name: TDE, the Thomson-Davis Editor. * Author: Frank Davis * Date: June 5, 1991, version 1.0 * Date: July 29, 1991, version 1.1 * Date: October 5, 1991, version 1.2 * Date: January 20, 1992, version 1.3 * Date: February 17, 1992, version 1.4 * Date: April 1, 1992, version 1.5 * Date: June 5, 1992, version 2.0 * Date: October 31, 1992, version 2.1 * Date: April 1, 1993, version 2.2 * Date: June 5, 1993, version 3.0 * Date: August 29, 1993 version 3.1 * Date: November 13, version 3.2 * Date: June 5, 1994, version 4.0 * Date: December 5, 1998, version 5.0 (jmh) * * This code is released into the public domain, Frank Davis. * You may distribute it freely. */#include "tdestr.h"#include "common.h"#include "define.h"#include "tdefunc.h"#include "config.h"#include "syntax.h"#include <stdarg.h>#define CopyWord NextLine#define CopyString BegNextLinestatic int prompt_line;static const char *prompt_text;static int prompt_len = ERROR;static int prompt_col;static int dlg_active = FALSE;static int dlg_tab = FALSE;static int dlg_move = 0;static int first_edit, last_edit;static int first_cbox, num_cbox;static DIALOG* current_dlg;static int dlg_col, dlg_row;static int dlg_id;static DLG_PROC dlg_proc;static int dlg_drawn;static HISTORY *search_history( char *, int, HISTORY *, HISTORY *, int );static void display_prompt( void );static void init_dialog( DIALOG * );static void display_dialog( void );static void hlight_label( int, int );/* * Name: getfunc * Purpose: get the function assigned to key c * Date: July 11, 1991 * Passed: c: key just pressed * Notes: key codes less than 256 or 0x100 are not assigned a function. * The codes in the range 0-255 are ASCII and extended ASCII chars. * jmh 980727: 0 is used to represent the insert_overwrite function for * normal characters, and an unassigned function key or two-key. * If the function is PlayBack, point g_status.key_macro to * the macro structure; otherwise it's undefined. * jmh 020824: use a bitmask to indicate the key is actually a function. */int getfunc( long c ){int func = 0;TREE *two_key = NULL;TDE_WIN *win;LANGUAGE *language;int scan, shift; if (c >= 256) { if (PARENT_KEY( c )) { win = g_status.current_window; if (win->syntax) { language = win->file_info->syntax; do { two_key = search_tree( c, language->key_tree.right ); language = language->parent; } while ((two_key == NULL || two_key->func == 0) && language != NULL); } if (two_key == NULL || two_key->func == 0) two_key = search_tree( c, key_tree.right ); if (two_key != NULL) { func = two_key->func; g_status.key_macro = two_key->macro; } } else if ((int)c & _FUNCTION) func = (int)c & ~_FUNCTION; else { scan = KEY( c ); shift = SHIFT( c ); func = key_func[shift][scan]; if (func == PlayBack) g_status.key_macro = macro[shift][scan]; } } return( func );}/* * Name: translate_key * Purpose: to transform the key to something else * Author: Jason Hood * Date: July 25, 1998 * Passed: key: the TDE code of the key to be translated * mod: the modifiers (shift, ctrl, alt, extended) * ch: the associated (OS) character * Returns: the new key; * ERROR if the key should be ignored. * Notes: basically the same as Int15 service 4Fh keyboard intercept. * _FUNCTION modifier is used to indicate an extended key. * * Treat Grey/-*+ the same as the keypad numbers: if NumLock is on * they are their characters; if NumLock is off they are function * keys. With Shift this is inverted. GreyEnter is always treated * as a function key. * * jmh 980726: Translate two-keys directly. Keys are now a long, where normal * ASCII and Extended-ASCII are 0-255, function keys are from 256, * pseudo-macros are 8481-65535 (as hi- and lo-byte), and two-keys * are 16842753 onwards (as hi- and lo-word for the two keys, * where the hi-key parent must be a function key). * jmh 990428: recognize viewer keys. * jmh 020903: with the modified keyboard handling, this function can accept * more responsibilty, leaving getkey() to read the scancode and * shift state, and retrieve the system character. The viewer * keys are also proper keys now, not transformed characters. * Unfortunately, this means the keypad won't work. I'm not too * bothered, at the moment. * jmh 020924: make two-keys also use keys, not characters. */long translate_key( int key, int mod, text_t ch ){long new_key;int func = 0;static int two_key = 0;int viewer = FALSE; /* * I should probably have unnamed keys (key89, key90, ...) so * those people with fancy keyboards can use them. */ if (KEY( key ) > MAX_KEYS) return( ERROR ); if (g_status.viewer_key) { if (g_status.current_file->read_only) viewer = TRUE; g_status.viewer_key = FALSE; } if (two_key) viewer = TRUE; key = scancode_map[KEY( key )]; /* * Prevent enter, escape, backspace and tab mapping to characters. */ if (key == _ENTER || key == _ESC || key == _BACKSPACE || key == _TAB) ch = 0; if (mod == 0 || mod == _FUNCTION) { /* * No shifted keys, so test the characters. */ if (!viewer && !(ch == 0 || (!numlock_active() && (key == _GREY_STAR || key == _GREY_SLASH || key == _GREY_PLUS || key == _GREY_MINUS)))) key = ch; } else if ((mod & ~_FUNCTION) == _SHIFT) { /* * Shift key only, again test characters, as well as extended "keypad". */ if (ch == 0 || viewer) { if ((mod & _FUNCTION) || (key < _HOME || key > _DEL)) key |= _SHIFT; } else if (!(numlock_active() && (key == _GREY_STAR || key == _GREY_SLASH || key == _GREY_PLUS || key == _GREY_MINUS))) key = ch; /* * Other combinations of shift keys. */ } else key |= mod & ~_FUNCTION; if (two_key) { show_search_message( CLR_SEARCH ); new_key = CREATE_TWOKEY( two_key, key ); two_key = 0; func = getfunc( new_key ); } else { func = getfunc( key ); if (func == TwoCharKey) { /* * Next key.. */ show_search_message( NEXTKEY ); two_key = key; return( ERROR ); } else new_key = key; } /* * Test for a single-key macro. */ if (func == PlayBack && g_status.key_macro->len == 1 && (!mode.record || new_key != g_status.recording_key)) { new_key = g_status.key_macro->key.key; if ((unsigned long)new_key < 256 && capslock_active( )) new_key = (bj_islower( (int)new_key )) ? bj_toupper( (int)new_key ) : bj_tolower( (int)new_key ); /* * Toggle the graphic chararacters. This allows them to be used anywhere * (as I feel they should), but at the expense of flexible macro * definitions (it wouldn't use the graphic character of the current set, * but the recorded character). */ } else if (func == ToggleGraphicChars) { toggle_graphic_chars( NULL ); /* Note: dummy argument */ new_key = ERROR; /* * Translate numbers and minus to an appropriate graphic character. * Use F1 - F6 to select the set: * F1 - single line; * F2 - double line; * F3 - single horizontal, double vertical; * F4 - double horizontal, single vertical. * F5 - solid (24568), "arrows" (79), stipples (013), and small block (-). * F6 - ASCII (+-|) (991019) */ } else if (mode.graphics > 0) { if (key >= _F1 && key <= _F6) { mode.graphics = (key == _F6) ? 1 : key - _F1 + 2; show_graphic_chars( ); new_key = ERROR; } else if ((key >= '0' && key <= '9') || key == '-') { key = (key == '-') ? 10 : key - '0'; new_key = graphic_char[mode.graphics-1][key]; } } return( new_key );}/* * Name: get_name * Purpose: To prompt the user and read the string entered in response. * Date: June 5, 1992 * Passed: prompt: prompt to offer the user * line: line to display prompt * name: default answer * hist: history to search/add answer to * Returns: name: user's answer * length of the answer * ERROR if user aborted the command * * jmh 031115: turned into a wrapper for get_string(). * jmh 050918: if using file history, turn leading "~/" into TDE's home dir. */int get_name( const char *prompt, int line, char *name, HISTORY *hist ){DISPLAY_BUFF;int rc; /* * set up prompt */ prompt_len = strlen( prompt ); prompt_line = line; prompt_text = prompt; prompt_col = (g_status.current_window != NULL && g_status.current_window->syntax) ? syntax_color[0] : Color( Text ); assert( prompt_len < g_display.ncols ); SAVE_LINE( line ); rc = get_string( prompt_len, line, g_display.ncols - prompt_len, prompt_col, ' ', name, hist ); if (rc > 1 && hist == &h_file && *name == '~' && (name[1] == '/'#if !defined( __UNIX__ ) || name[1] == '\\'#endif )) { char buf[PATH_MAX+2]; join_strings( buf, g_status.argv[0], name + 2 ); rc = strlen( buf ); memcpy( name, buf, rc + 1 ); } RESTORE_LINE( line ); prompt_len = ERROR; return( rc );}/* * Name: display_prompt * Class: helper function * Purpose: display the prompt from get_string() * Author: Jason Hood * Date: November 15, 2003 * Notes: get_name() needs to be called first */static void display_prompt( void ){ s_output( prompt_text, prompt_line, 0, Color( Message ) ); eol_clear( prompt_len, prompt_line, prompt_col );}/* * Name: get_string * Purpose: Read a string from the user (or macro) * Date: June 5, 1992 * Passed: col: column position for input * line: line position for input * width: width of input display * normal: color to blank unused portion * blank: character to blank unused portion * name: default answer * hist: history to search/add answer to * Returns: name: user's answer * length of the answer * ERROR if user aborted the command * Notes: with the addition of macros in tde, this function became a little * more complicated. we have to deal with both executing macros * and macros that are the user uses when entering normal text * at the prompt. i call these local and global macros. a global * macro is when this function is called from a running macro. * the running macro can enter text and return from this function * w/o any action from the user. a local macro is when the user * presses a key inside this function, which happens quite often * when keys are assigned to ASCII and Extended ASCII characters. * * jmh 980718: If a global macro executes another macro, make it the local * macro. If the global macro finishes before entry is complete * (which can only happen from a config definition) then assume * Rturn rather than AbortCommand. * * jmh 980727: If a global macro pauses, continue input from the keyboard. * jmh 980731: Use NextLine and BegNextLine (ie. Shift+ & Ctrl+Enter) to copy * the word and string from the current window. * jmh 980813: moved from utils.c and added WordLeft and WordRight functions. * Removed color parameter; always use g_display.message_color. * * jmh 990424: Added history. * jmh 990425: Added filename completion. This filename completion does not * currently support reverse cycle, but does allow wildcards. This * means that "*.tdm", for example, will be used as the pattern, * not "*.tdm*" that would normally occur. * jmh 990505: don't display anything in a macro unless Pause is used; * consolidated all the display updates into one place; * allow the name to be longer than the screen; assume if it's file * history the maximum length is PATH_MAX, otherwise MAX_COLS. * jmh 990506: deleted lines are placed in the history; * added WordDelete, WordDeleteBack and Transpose operations; * use normal syntax coloring, when appropriate, to display blanks. * jmh 990507: the delete words delete a group of whitespace or non-whitespace, * but not both. * jmh 010521: fixed bug with copy_word() doing nothing when it was first. * jmh 021021: added clipboard support; * added SetDirectory. * jmh 021028: made filename completion complete prefix before cycling. * jmh 021029: added history completion (when not filename completing). * jmh 030226: added ToggleCWD. * jmh 030316: return the length of the answer; * added DelEndOfLine and DelBegOfLine. * jmh 031115: added column and width parameters, dialog processing; * replaced Tab history completion with Ctrl+Up (ScrollUpLine) * and Ctrl+Down (ScrollDnLine). * jmh 031119: recognise StreamDeleteChar; * using (Stream)DeleteChar first will clear the previous answer. * jmh 050705: close the handle used by filename completion. * jmh 050710: Pause the entire dialog, not just the current edit field. * jmh 050721: GotoMark<n> will move to the <n>th edit field. */int get_string( int col, int line, int width, int normal, int blank, char *name, HISTORY *hist ){long c = 0; /* character user just typed */int func = 0; /* function of key pressed */char *cp; /* cursor position in answer */int pos; /* cursor position in answer */#if PATH_MAX > MAX_COLSchar answer[PATH_MAX]; /* user's answer */#elsechar answer[MAX_COLS]; /* user's answer */#endifint first = TRUE; /* first character typed */register int len; /* length of answer */int max; /* maximum length allowed */int scol; /* start column */int stop; /* flag to stop getting characters */char *p; /* for copying text in answer */MACRO *local_macro = NULL;int next = 0; int paused = FALSE; /* Is a global macro wanting keyboard input? */HISTORY *h; /* Position within history list */int complete = FALSE; /* Starting or continuing filename completion */char cname[NAME_MAX+2];int stem = 0;int prefix;FTYPE *ftype = NULL;FFIND dta;int done_empty = FALSE; /* do dialog callback for empty string */int done_one = FALSE; /* do dialog callback for non-empty string */int i;int color = Color( Message );int displayed = FALSE;int reset = TRUE;char *disp = NULL; /* the first position to redisplay */int dlen = 0; /* number of characters to redisplay */int dcol = 0; /* position to begin redisplay */int max_col; /* last column on screen */int cols; /* number of columns available */char *old_cp;#define DLEN( len ) if ((len) > dlen) dlen = (len) strcpy( answer, name ); h = hist; max = (h == &h_file || h == &h_exec) ? PATH_MAX-1 : MAX_COLS-1; max_col = col + width - 1; cols = width;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -