Debian bug report logs - #1724 unexpected keypress translations Package: ae ; Reported by: Ian Jackson ; 10 days old. ----------------------------------------------------------------------- Message received at debian-bugs: From sentex.net!achowe Sat Oct 28 08:26:46 1995 Return-Path: Received: from pixar.com by mongo.pixar.com with smtp (Smail3.1.28.1 #15) id m0t9D9i-000DPoC; Sat, 28 Oct 95 08:26 PDT Received: from granite.sentex.net ([199.212.134.1]) by pixar.com with SMTP id AA13284 (5.67b/IDA-1.5 for debian-bugs-pipe@mongo.pixar.com); Sat, 28 Oct 1995 08:26:11 -0700 Received: (from achowe@localhost) by granite.sentex.net (8.6.12/8.6.9) id LAA04989; Sat, 28 Oct 1995 11:25:47 -0400 Date: Sat, 28 Oct 1995 11:25:47 -0400 From: Anthony Howe Message-Id: <199510281525.LAA04989@granite.sentex.net> To: achowe@sentex.net, mitchell@mdd.comm.mot.com Subject: Re: Bug#1724: unexpected keypress translations (fwd) Cc: debian-bugs@pixar.com Sorry for the delay. Here is a shar archive containing replacement source modules to fix portability for TERMCAP and TERMINFO. Check ae.man in the configuration section about how to configure for either database method. NOTE these changes should be tested. I've only been able to test using BSDI Curses and Termcap, and noticed a problem with the help message which I suspect is a bug in BSDI Curses addstr(). THIS CODE NEEDS TO BE TESTED FOR TERMINFO. To compile for a termcap system, ensure that -DTERMCAP is define, else undefined for terminfo. Note the two new configuration files : modeless.ti TERMINFO version modeless.tc TERMCAP version Install the desired version that corresponds with your system. Anthony ----update95.shar---- # This is a shell archive. Save it in a file, remove anything before # this line, and then unpack it by entering "sh file". Note, it may # create directories; files and directories will be owned by you and # have default permissions. # # This archive contains: # # ae.man # header.h # command.c # key.c # main.c # modeless.tc # modeless.ti # echo x - ae.man sed 's/^X//' >ae.man << 'END-of-ae.man' X0. NAME X X ae Anthony's Editor October 95 X X X1. SYNOPSIS X X ae [-f config_file] [filename] X X X2. OPERANDS X Xconfig_file The pathname of an AE configuration file. The X pathname may be absolute, relative the current X directory, or relative the user's home directory. X Xfilename The name of a existing or new file to edit. X X X3. DESCRIPTION X XAE is a simple full screen text editor that can be configured for Xeither a modual (VI-style interface) or a modeless (EMACS-style Xinterface). X XText files consist of lines of printable text or tab characters. XA line can be of arbitary length and is delimited by either a Xnewline or the end of file. Carriage return is mapped to newline Xon input and ignored on output. Carriage returns already in the file Xare preserved. Tab stops are every eight columns. X X X4. COMMANDS X XTwo default configuration files are supplied. One of them should be Xrenamed to "ae.rc" and placed in the user's home directory. The two Xsupplied files are "mode.rc" and "modeless.rc" which configure the Xeditor for either modual (VI-style) or modeless (EMACS-style) Xoperation. X X X4.1. MODUAL CONFIGURATION X X4.1.1. SUPPORT X X? Toggle help on/off. XM Macro add, change, delete, or view. Xr Refresh the screen. XR W Read and write file to and from the buffer. Xq Q Quit with and without query. XV Display version. X X4.1.2. MOVEMENT X Xh j k l Left, down, up, right cursor movement. XH J K L Word left, page down, page up, word right. X[ ] Beginning and end of line. XT B Top and bottom of file. X X4.1.3. EDIT X Xi ESC ERASE Enter insert mode, escape to leave, backspace. X^V Next character typed will be treated as a literal. XX x Delete character left or under the cursor. XSPACE Toggle block on/off. XC Cut block to scrap. XP Paste scrap into buffer. Xu Undo last cut, delete, paste, read, insert, or undo. X~ Invert case of letters. X X4.1.4. MACROS X Xa Append after cursor. XA Append at teh end of a line. Xcw Change word. XD Delete from cursor to end of line. Xdd Delete line. Xdw Delete word. Xo O Open line below or above. Xy Yank current block. X X X4.2. MODELESS CONFIGURATION X X4.2.1. SUPPORT X XF1 Toggle help on/off. X^K^M Macro add, change, delete, or view. X^L Refresh the screen. X^R ^W Read and write file to and from the buffer. X^C ^K^C Quit with and without query. X^K^V Display version. X X X4.2.2. MOVEMENT X Xcursor keys Left, down, up, right cursor movement (ansi defined). X^A ^D Word left, word right. X^F ^E Front and end of line. X^N ^P Next and previous page. X^T ^B Top and bottom of file. X X X4.2.3. EDIT X Xunbound keys Insert. XBACKSPACE ^X Delete character left or under the cursor. X^V Next character typed will be treated as a literal. XF2 Toggle block on/off. XF3 Cut block to scrap. XF4 Paste scrap into buffer. X^U Undo last cut, paste, read, or undo. X^^ Invert case of letters. X X4.2.4. MACROS X XNo pre-defined macros. X X X5. CONFIGURATION X XIt is possible to redefine copies of the sample configuration files in Xorder to support key-bindings and text messages of the user's choice. XThe user can define an interface similar to either Vi or Emacs, and Xsupport multibyte key sequences. The text messages can be rephrased or Xtranslated into any 8-bit character set. X XThe configuration file layout is fairly simple. All keywords begin Xon a line starting with a period (.). Messages begin with a message Xnumber followed by a colon (:) and end with the first unescaped newline. XInvalid keywords and messages are ignored. X XThe parameters and can be any text other than Xwhitspace (blank, tab, carriage-return, and newline). It is possible Xto specify control keys by prefixing the following characters with a Xcaret (^): X X @ a b c d e f g h i j k l m n o X p q r s t u v w x y z [ \ ] ^ _ X XThe sequence ^? represents ASCII DEL (0x7f). The following escape Xconstants are recognised: X X backspace \b X formfeed \f X newline \n X return \r X space \s X tab \t X XAlso numeric escapes are possible. The value represented must be Xbetween 0 and 255 inclusive. X X decimal \ddd X octal \0ooo X hex \0xhh X XA literal escape begins with a backslash and is followed by any Xcharacter that does not specify an escape constant or start a Xnumber, and will represent the character itself. X XAlso, there is support for termcap and terminfo by using $(id) or X$(capname) strings in the . An id is a two letter termcap Xid name used to identify a string capbility; capname is a two to five Xletter terminfo capability name. These strings can be used to specify Xkey bindings in a portable manner. Below are some common capabilities X(see your system's man page for termcap or terminfo for a complete list). XThe files modeless.tc and modeless.ti are examples using termcap and Xterminfo. An invalid id or capname or a missing capability will map to Xthe alert character (\a). X X TERMCAP TERMINFO XLeft kl kcuf1 XRight kr kcub1 XUp ku kcuu1 XDown kd kcud1 XF1 k1 kf1 X... XF10 k0 kf10 X XSome examples of the paragraphs above : X X .insert_enter i <-- single character string X .insert_exit ^[ <-- defines ASCII ESC X .delete_right \0x7f <-- defines ASCII DEL X .cursor_up ^[[A <-- defines sequence ESC [ A X .cursor_down $(kd) <-- termcap arrow down X .cursor_down $(kcud1) <-- terminfo arrow down X X X5.1. KEYWORDS X X5.1.1. SUPPORT X X.file_read X.file_write X Read or write a file to or from a buffer. X X.help X Toggle the help text and ruler line on and off. X X.help_off X Disable initial help message at startup. X X.itself X The following character represents itself. This is really a X redundant keyword since any key not defined by a keyword, X automatically represents itself. X X.macro X Define a macro during an edit session. The user will be X prompted for an input line consisting of zero, one, or two X separated by whitespace. X X Pressing at the prompt, with no input strings, will X display the current set of macros definitions and how many X slots have been used versus the total number of slots available. X X One string entered will remove the macro defined to have X that string as the left-hand-side. X X Two input strings defines a macro, where the first string, X when typed, pushes the second string onto an input stack. X X Macros may be nested. It is only possible to delete or change X macros that appear in the listing of currently defined macros. X All other key-bindings cannot be redefined during an edit X session. X X.macro_define X.macro_define X The first case reserves space for one macro definition that X may be defined during the edit session. The other case will X actually define a macro, where the left-hand-side, when typed X will push onto an input stack the right-hand-side. Either X case may be used as many times as desired (memory permiting). X Macros may be nested. X X.quit X.quit_ask X Exit the editor. X X.redraw X Force a screen redraw. X X.show_version X Display the release information. X X X5.1.2. CURSOR MOTION X X.cursor_up X.cursor_down X.cursor_left X.cursor_right X Cursor motion in four directions. Typically the arrow keys. X X.file_top X.file_bottom X Move to the top and bottom of the file buffer. X X.line_left X.line_right X Move to the beginning or end of the line. X X.page_up X.page_down X Previous or next screen full of text. X X.word_left X.word_right X Move the cursor to start of the previous or next word. X A word is defined as a sequence of alpha and/or numeric X characters. X X X5.1.3. EDIT X X.block X.cut X.paste X Block on/off toggle, cut block, and paste before. X X.delete_left X.delete_right X Delete character to the left or right of the cursor. X X.insert_enter X.insert_exit X Enter and exit insert mode. The use of .insert_enter denotes X a modual user interface. Insert mode does not perform macro X expansion. X X.literal X Next character entered is treated as a literal. X X.stty_erase X.stty_kill X Declare that the terminal's values for the erase and kill X characters should be used in insert mode to backspace-erase, X or discard and restart input. X X.undo X Undo last cut, delete, insert, paste, read, or undo. X X.flip_case X Invert the case of letters from lower to upper and visa-versa. X When no region is selected, the cursor will advance right one X character position. X X X5.2. MESSAGES X XEach message has the form: X X number : text X XLong messages can be continued by escaping the newline with a backslash (\). XThe first unescaped newline terminates the message text and is not included Xas part of the text. X XThe following is a list of messages: X X1: X Help text. See the sample configuration files for an example. X X2:%s: Terminated successfully.\n X Exit succesfully. %s is the program name. X X3:%s: Unspecified error.\n X Exit due to an unknown error. %s is the program name. X X4:usage: %s [-f ] [file]\n X Exit with usage error. %s is the program name. X X5:%s: Failed to initialize the screen.\n X Exit because Curses couldn't be initialized. %s is the program name. X X6:%s: Problem with configuration file.\n X Exit due to a problem with the configuration file. %s is the X program name. Possible causes are: X X o Configuration file not found. X o Invalid control character, ^X, specified. X o Numeric escape not in range 0 .. 255. X X7:%s: Failed to allocate required memory.\n X Exit because required memory is not available. %s is the program X name. X X8:Ok. X No error. X X9:An unknown error occured. X Internal error. X X10:No more memory available. X Requests for additional memory to either grow the edit buffer X or macro definitions failed. X X11:File \"%s\" is too big to load. X The file is too large to load into available memory. %s is the X name of the file that could not be loaded. X X12:Scrap is empty. Nothing to paste. X An attempt to paste the scrap buffer failed because is was empty. X X13:Failed to find file \"%s\". X %s is a file that could not be found. X X14:Failed to open file \"%s\". X %s is a file that could not be opened. X X15:Failed to close file \"%s\". X %s is a file that could not be closed. X X16:Failed to read file \"%s\". X A read error occur for a file %s. X X17:Failed to write file \"%s\". X A write error occur for a file %s. X X18:Not a portable POSIX file name. X File names must be portable POSIX file names. X X19:File \"%s\" %ld bytes. X %ld is the current length of the file named by %s in the buffer. X X20:File \"%s\" %ld bytes saved. X %ld is the length of the file named by %s just saved. X X21:File \"%s\" %ld bytes read. X %ld is the length of the file named by %s just read. X X22:File \"%s\" modified. X The file named by %s has been modified. X X23:Invalid control character or \\number not 0..255. X An invalid control character was specified by ^X, or a X numeric escape is not in the range 0 .. 255. X X24:No such macro defined. X The left-hand-side of a macro is not currently defined and so X cannot be changed or deleted. X X25:No more macro space. X All the macro space, allocated in the configuration file, is X currently being used. X X26:Interrupt. X An interrupt occured. X X27:<< EOF >> X End of file marker. X X28:Macro : X Prompt for a macro to define, delete, or list. X X29:File not saved. Quit (y/n) ? X Ask the user if he really wants to quit before he has saved X his changes. X X30:[ Press a key to continue. ] X Prompt the user for a key press in order to proceed. X X31:Read file : X Prompt the user for a file name to read. X X32:Write file : X Prompt the user for a file name to save the buffer to. X X33:Write block : X Prompt the user for a file name to save a block of text to. X X34:\smore\s X Pause output till user responds with either Q, q, or another key. X X35:\sy\b X Yes response. X X36:\sn\b X No response. X X37:\sq\b X Quit response. X X38:Nothing to undo. X An attempt was made to undo a change when the buffer had not yet X been modified. X X X6. EXIT STATUS X X0 Success. X1 Unknown error. X2 Usage error. X3 Understood failure. X X X7. INSTALLATION X XThe source has been know to compile on a wide variety of machines and Xcompilers like BSD and System V Unix with GNU C, PC mahcines with XWatCom C or Turbo C, and ATARI ST machines with Sozobon C. Any machine Xthat provides at least K&R C and a BSD CURSES library (as described by XKen Arnolds's paper) should have no trouble getting AE to compile. X XTo build AE on most unix-like systems, type X X make X XThe supplied makefile is configured for a BSD environment. Some Xsystems may require that the macros CC, CFLAGS, LD, LDFLAGS, and LIBS Xbe configured. X XThe minimum Curses implementation supported is that defined by Kenneth XArnold's paper "Screen Updating and Cursor Movement Optimization: A Library XPackage". Some BSD Curses implementations have been noted to omit the Xfunctions erasechar(), killchar(), and idlok(). For BSD systems with poor XCurses implementations, alter the following macro: X X CFLAGS = -O -DBADCURSES X XFor a System V environment alter the following macros to: X X CFLAGS = -O X LIBS = -lcurses X XTo build AE on systems that have POSIX.1 or System V termios library, Xmodify the CFLAGS macro to X X CFLAGS = -O -DTERMIOS=1 X XIf the constants CHUNK or CONFIG are not defined by CFLAGS then Xthe defaults used are X X CHUNK = 8096L X CONFIG = "ae.rc" X XCHUNK is the size by which the buffer is expanded when the buffer Xbecomes full while inserting text. CONFIG is the name of the default Xconfiguration file. The name chosen aims to satisfy both unix and Xpersonal systems. Unix affectionados may want to reconfigure this Xto ".aerc". X XTERMIOS should be defined for systems that have POSIX.1 termios Xsupport (which is based on System V termios). This has the affect of Xdisabling the INTR, QUIT, and SUSP signals. XON/XOFF is left Xunchanged. If TERMIOS is not defined, then cbreak() and nocbreak() Xare used which do not disable the above mentioned signals. X XMost EBCDIC machines use block mode terminals. This is a problem Xthat has not been addressed and/or tested for. X X X8. BUGS X XNo known bugs. X X X9. REFERENCES X X[Fin80] Craig A. Finseth, "Theory and Practice of Text Editors or X A Cookbook For An EMACS", TM-165, MIT Lab. for Computer X Science X X[KeP81] Kernighan & Plauger, "Software Tools in Pascal", X Addison-Wesley, 81, chapter 6 X X[Mil86] Eugene W. Myers & Webb Miller, "Row-replacement Algorithums X for Screen Editors", TR 86-19, Dept. of Compter Science, X U. of Arizona X X[MyM86] Eugene W. Myers & Webb Miller, "A simple row-replacement X method", TR 86-28, Dept. of Compter Science, U. of Arizona X X[Mil87] Webb Miller, "A Software Tools Sampler", Prentice Hall, 87 X ISBN 0-13-822305-X, chapter 5 X X[net90] "Editor 101/102" articles from comp.editors X X X10. FILES X Xae.man Manual. Xae.rc Default configuration file used by AE. Xmode.rc Sample configuration for modual style. Xmodeless.rc Sample configuration for modeless style (ansi cursor keys). Xmodeless.tc Sample configuration for modeless style (TERMCAP). Xmodeless.ti Sample configuration for modeless style (TERMINFO). X X X11. NOTICES X XCopyright 1993, 1995 by Anthony Howe. All rights reserved. No warranty. X END-of-ae.man echo x - header.h sed 's/^X//' >header.h << 'END-of-header.h' X/* X * header.h X * X * Anthony's Editor October 95 X * X * Copyright 1993, 1995 by Anthony Howe. All rights reserved. No warranty. X */ X X#ifndef __header_h__ X#define __header_h__ 1 X X#ifdef __STDC__ X#include X#include X#include X#include X#endif /* __STDC__ */ X X#ifdef ATARI_ST X/* Atari's Sozobon C has ANSI-like libraries X * and headers but no prototypes. X */ X#include X#include X#include X#include X X#define DRIVE_COLON 1 X#define EITHER_SLASH 1 X X#ifndef FILE_MODE X#define FILE_MODE 0 X#endif X#endif /* ATARI_ST */ X X#ifdef __WATCOMC__ X#ifdef MSDOS X#define __MSDOS__ 1 X#endif X#endif /* __WATCOMC__ */ X X#ifdef __MSDOS__ X#define DRIVE_COLON 1 X#define EITHER_SLASH 1 X X#ifndef FILE_MODE X#define FILE_MODE 0 X#endif X#endif /* __MSDOS__ */ X X#ifdef BSD X#ifndef __STDC__ X#include X#include X#include Xextern char *getenv(); Xextern char *malloc(); Xextern char *realloc(); Xextern char *strtok(); X#endif /* __STDC__ */ X#endif /* BSD */ X X#ifndef SIG_ERR X#define SIG_ERR ((void (*) _((int))) -1) X#endif X X#include X#include X#include "key.h" X X#ifdef BADCURSES X#define erasechar() '\b' X#define killchar() CTRL('x') X#define idlok(w,f) OK X#endif /* BADCURSES */ X X#undef _ X#ifdef __STDC__ X#define _(x) x X#else X#define _(x) () X#define const X#endif X X#define VERSION \ X"0:AE July 93. Copyright 1993, 1993 by Anthony Howe. No warranty." X X#ifndef CONFIG X#define CONFIG "ae.rc" X#endif /* CONFIG */ X X#ifndef CHUNK X#define CHUNK 8096L X#endif /* CHUNK */ X X#ifndef FILE_MODE X#define FILE_MODE 0600 X#endif /* FILE_MODE */ X X/* Screen partitioning. */ X#define MSGLINE 0 X#define HELPLINE 1 X#undef TEXTLINE X X#define NOMARK -1 X Xtypedef long SSIZE_T; /* ssize_t not defined all systems. */ Xtypedef char *t_msg; Xtypedef unsigned char t_char; Xtypedef long t_point; X Xtypedef struct t_keytable { X short key; X void (*func) _((void)); X void (*disp) _((void)); X} t_keytable; X Xtypedef struct t_region { X t_point left; X t_point right; X} t_region; X X/* X * Function return codes. X */ X#define GETBLOCK_EOF (-1L) X#define GETBLOCK_ERROR (-2L) X#define GETBLOCK_ALLOC (-3L) X X/* X * Some compilers define size_t as a unsigned 16 bit number while X * t_point and off_t might be defined as a signed 32 bit number. X * malloc(), realloc(), fread(), and fwrite() take size_t parameters, X * which means there will be some size limits because size_t is too X * small of a type. X */ X#define MAX_SIZE_T ((unsigned long) (size_t) ~0) X#define MAX_SSIZE_T ((unsigned long) (SSIZE_T) ~(size_t) 0 >> 1) X X/* X * X */ Xextern int done; /* Quit flag. */ Xextern int modified; /* Text buffer modified flag. */ Xextern int modeless; /* Command-set style. */ Xextern int msgflag; /* True if msgline should be displayed. */ X Xextern int row; /* Cursor screen row */ Xextern int col; /* Cursor screen column. */ Xextern int textline; /* First screen line used for text. */ X Xextern t_point point; /* Cursor offset in text buffer. */ Xextern t_point pointline; /* Cursor line number. */ Xextern t_point page; /* Top of screen page. */ Xextern t_point epage; /* End of screen page +1 */ Xextern t_point marker; /* Block anchor point. */ X Xextern t_char *buf; /* Base of allocated text buffer. */ Xextern t_char *ebuf; /* End of text buffer +1 */ Xextern t_char *gap; /* Start of gap. */ Xextern t_char *egap; /* End of gap +1 */ X Xextern t_point nscrap; /* Length of scrap buffer. */ Xextern t_char *scrap; /* Allocated scrap buffer. */ X Xextern int count; /* Command repeat count. */ Xextern int input; /* Current input character. */ Xextern char msgline[]; /* Message line input/output buffer. */ Xextern char filename[]; /* Current filename for text buffer. */ Xextern char temp[]; /* Temporary buffer. */ Xextern char *prog_name; /* Name used to invoke editor. */ X Xextern t_keytable table[]; /* Command jump table. */ Xextern t_keymap *key_map; /* Command key mappings. */ Xextern t_keymap key_mode[]; /* Key mappings used in insert_mode() */ X X/* fatal() messages. */ Xextern t_msg f_ok; /* EXIT_OK */ Xextern t_msg f_error; /* EXIT_ERROR */ Xextern t_msg f_usage; /* EXIT_USAGE */ Xextern t_msg f_initscr; /* EXIT_FAILURE ... */ Xextern t_msg f_config; Xextern t_msg f_alloc; X X/* Messages. */ Xextern t_msg m_version; Xextern t_msg m_help; Xextern t_msg m_ok; Xextern t_msg m_error; Xextern t_msg m_alloc; Xextern t_msg m_toobig; Xextern t_msg m_scrap; Xextern t_msg m_stat; Xextern t_msg m_open; Xextern t_msg m_close; Xextern t_msg m_read; Xextern t_msg m_write; Xextern t_msg m_badname; Xextern t_msg m_file; Xextern t_msg m_modified; Xextern t_msg m_saved; Xextern t_msg m_loaded; Xextern t_msg m_badescape; Xextern t_msg m_nomacro; Xextern t_msg m_slots; Xextern t_msg m_interrupt; Xextern t_msg m_eof; Xextern t_msg m_undo; X X/* Prompts */ Xextern t_msg p_macro; Xextern t_msg p_notsaved; Xextern t_msg p_press; Xextern t_msg p_read; Xextern t_msg p_write; Xextern t_msg p_bwrite; Xextern t_msg p_yes; Xextern t_msg p_no; Xextern t_msg p_quit; Xextern t_msg p_more; X Xextern t_msg message[]; X X/* X * X */ X#ifdef TERMIOS Xextern void lineinput _((int)); X#else X#define lineinput(bf) (bf ? nocbreak() : cbreak()) X#endif /* TERMIOS */ X Xextern void fatal _((t_msg)); Xextern void msg _((t_msg, ...)); Xextern char *getmsg _((t_msg)); Xextern char *strlwr _((char *)); Xextern char *strdup _((const char *)); Xextern char *strrep _((char *, int, int, int)); Xextern char *pathname _((char *, char *)); Xextern FILE *openrc _((char *)); Xextern long getblock _((FILE *, char **)); Xextern char *encode _((char *)); X Xextern void display _((void (*)(void))); Xextern void dispfull _((void)); Xextern void dispcursor _((void)); Xextern t_point lnstart _((t_point)); Xextern t_point lnnext _((t_point)); Xextern t_point lncolumn _((t_point, int)); Xextern t_point segstart _((t_point, t_point)); Xextern t_point segnext _((t_point, t_point)); Xextern t_point upup _((t_point)); Xextern t_point dndn _((t_point)); Xextern void ruler _((int)); Xextern char *printable _((unsigned)); X Xextern int growgap _((t_point)); Xextern t_point movegap _((t_point)); Xextern t_point pos _((t_char *)); Xextern t_char *ptr _((t_point)); Xextern void getregion _((t_region *)); Xextern int posix_file _((char *)); Xextern int save _((char *)); Xextern int load _((char *)); Xextern void undoset _((void)); Xextern void undosave _((void)); Xextern void undo _((void)); X Xextern void backsp _((void)); Xextern void block _((void)); Xextern void bottom _((void)); Xextern void cut _((void)); Xextern void delete _((void)); Xextern void down _((void)); Xextern void help _((void)); Xextern void insert _((void)); Xextern void insert_mode _((void)); Xextern void left _((void)); Xextern void lnbegin _((void)); Xextern void lnend _((void)); Xextern void macro _((void)); Xextern void paste _((void)); Xextern void pgdown _((void)); Xextern void pgup _((void)); Xextern void quit _((void)); Xextern void quit_ask _((void)); Xextern void redraw _((void)); Xextern void readfile _((void)); Xextern void right _((void)); Xextern void top _((void)); Xextern void up _((void)); Xextern void version _((void)); Xextern void wleft _((void)); Xextern void wright _((void)); Xextern void writefile _((void)); Xextern void flipcase _((void)); Xextern int iscrlf _((t_point)); X X#endif /* __header_h__ */ END-of-header.h echo x - command.c sed 's/^X//' >command.c << 'END-of-command.c' X/* X * command.c X * X * Anthony's Editor October 95 X * X * Copyright 1993, 1995 by Anthony Howe. All rights reserved. No warranty. X */ X X#include X#include "header.h" X Xvoid prt_macros _((void)); Xint yesno _((int)); Xint more _((int)); Xvoid prompt _((t_msg, char *, size_t)); X Xvoid Xtop() X{ X point = 0; X} X Xvoid Xbottom() X{ X epage = point = pos(ebuf); X} X Xvoid Xquit_ask() X{ X if (modified) { X standout(); X mvaddstr(MSGLINE, 0, getmsg(p_notsaved)); X standend(); X clrtoeol(); X if (!yesno(FALSE)) X return; X } X quit(); X} X Xint Xyesno(flag) Xint flag; X{ X int ch; X X addstr(getmsg(flag ? p_yes : p_no)); X refresh(); X ch = getliteral(); X if (ch == '\r' || ch == '\n') X return (flag); X return (ch == getmsg(p_yes)[1]); X} X Xvoid Xquit() X{ X done = 1; X} X Xvoid Xredraw() X{ X int col; X X clear(); X if (textline != HELPLINE) { X move(HELPLINE, 0); X addstr(getmsg(m_help)); X ruler(COLS); X getyx(stdscr, textline, col); X } X display(dispfull); X} X Xvoid Xleft() X{ X if (0 < point && iscrlf(--point) == 2) X --point; X} X Xvoid Xright() X{ X if (point < pos(ebuf) && iscrlf(point++) == 1) X ++point; X} X Xvoid Xup() X{ X point = lncolumn(upup(point), col); X if (iscrlf(point) == 2) X --point; X} X Xvoid Xdown() X{ X point = lncolumn(dndn(point), col); X if (iscrlf(point) == 2) X --point; X} X Xvoid Xlnbegin() X{ X point = segstart(lnstart(point), point); X} X Xvoid Xlnend() X{ X point = dndn(point); X left(); X} X Xvoid Xwleft() X{ X while (!isalnum(*ptr(--point)) && 0 < point) X ; X while (isalnum(*ptr(--point)) && 0 <= point) X ; X ++point; X} X Xvoid Xwright() X{ X t_point epoint = pos(ebuf); X while (isalnum(*ptr(point)) && point < epoint) X ++point; X while (!isalnum(*ptr(point)) && point < epoint) X ++point; X} X Xvoid Xpgdown() X{ X page = point = upup(epage); X while (textline < row--) X down(); X epage = pos(ebuf); X} X Xvoid Xpgup() X{ X int i = LINES; X while (textline < --i) { X page = upup(page); X up(); X } X} X Xvoid Xinsert() X{ X assert(gap <= egap); X if (gap == egap && !growgap(CHUNK)) X return; X point = movegap(point); X *gap++ = input == K_LITERAL ? getliteral() : input; X if (input == '\r' && (gap < egap || growgap(CHUNK))) X *gap++ = '\n'; X modified = TRUE; X point = pos(egap); X} X Xvoid Xinsert_mode() X{ X int ch; X t_point opoint; X point = opoint = movegap(point); X undoset(); X while ((ch = getkey(key_mode)) != K_INSERT_EXIT) { X if (ch == K_STTY_ERASE) { X if (opoint < point) { X if (*--gap == '\n' X && buf < gap && gap[-1] == '\r') X --gap; X modified = TRUE; X } X } else { X assert(gap <= egap); X if (gap == egap && !growgap(CHUNK)) X break; X *gap++ = ch == K_LITERAL ? getliteral() : ch; X if (ch == '\r' && (gap < egap || growgap(CHUNK))) X *gap++ = '\n'; X modified = TRUE; X } X point = pos(egap); X display(dispfull); X } X} X Xvoid Xbacksp() X{ X point = movegap(point); X undoset(); X if (buf < gap) { X if (*--gap == '\n' && buf < gap && gap[-1] == '\r') X --gap; X point = pos(egap); X modified = TRUE; X } X} X Xvoid Xdelete() X{ X point = movegap(point); X undoset(); X if (egap < ebuf) { X if (*egap++ == '\r' && egap < ebuf && *egap == '\n') X ++egap; X point = pos(egap); X modified = TRUE; X } X} X Xvoid Xreadfile() X{ X temp[0] = '\0'; X prompt(p_read, temp, BUFSIZ); X (void) load(temp); X if (filename[0] == '\0') { X strcpy(filename, temp); X modified = FALSE; X } X} X Xvoid Xwritefile() X{ X standout(); X if (marker == NOMARK || point == marker) { X strcpy(temp, filename); X prompt(p_write, temp, BUFSIZ); X } else { X temp[0] = '\0'; X prompt(p_bwrite, temp, BUFSIZ); X } X (void) save(temp); X if (marker == NOMARK && filename[0] == '\0') X strcpy(filename, temp); X} X Xvoid Xhelp() X{ X textline = textline == HELPLINE ? -1 : HELPLINE; X /* When textline != HELPLINE, then redraw() will compute the X * actual textline that follows the help text. X */ X redraw(); X} X Xvoid Xblock() X{ X marker = marker == NOMARK ? point : NOMARK; X} X Xvoid Xcut() X{ X if (marker == NOMARK || point == marker) X return; X if (scrap != NULL) { X free(scrap); X scrap = NULL; X } X if (point < marker) { X (void) movegap(point); X nscrap = marker - point; X } else { X (void) movegap(marker); X nscrap = point - marker; X } X if ((scrap = (t_char*) malloc(nscrap)) == NULL) { X msg(m_alloc); X } else { X undoset(); X (void) memcpy(scrap, egap, nscrap * sizeof (t_char)); X egap += nscrap; X block(); X point = pos(egap); X modified = TRUE; X } X} X Xvoid Xpaste() X{ X if (nscrap <= 0) { X msg(m_scrap); X } else if (nscrap < egap-gap || growgap(nscrap)) { X point = movegap(point); X undoset(); X memcpy(gap, scrap, nscrap * sizeof (t_char)); X gap += nscrap; X point = pos(egap); X modified = TRUE; X } X} X Xvoid Xversion() X{ X msg(m_version); X} X Xvoid Xmacro() X{ X t_keymap *kp; X size_t buflen, rhsoff; X char *buf, *lhs, *rhs; X X if ((buf = (char *) malloc(BUFSIZ)) == NULL) { X msg(m_alloc); X return; X } X buf[0] = '\0'; X prompt(p_macro, buf, BUFSIZ); X buflen = strlen(buf)+1; X X if ((lhs = strtok(buf, " \t")) == NULL) { X prt_macros(); X } else if (buf < lhs) { X /* Ideally we should shuffle the buffer down so that X * the lhs starts at the beginning of buffer. X */ X msg(m_error); X } else if ((lhs = encode(lhs)) == (char *) 0) { X msg(m_badescape); X } else { X kp = findkey(key_map, lhs); X if ((rhs = strtok(NULL, " \t")) == NULL) { X /* Delete macro. */ X if (kp == NULL || kp->code != K_MACRO_DEFINE) { X msg(m_nomacro); X } else { X free(kp->lhs); X free(kp->rhs); X kp->lhs = kp->rhs = NULL; X } X } else if ((rhs = encode(rhs)) == (char *) 0) { X msg(m_badescape); X } else { X if (kp == NULL) { X /* Find free slot to add macro. */ X for (kp = key_map; kp->code != K_ERROR; ++kp) { X if (kp->code == K_MACRO_DEFINE X && kp->lhs == NULL) X break; X } X } X if (kp->code == K_ERROR) { X msg(m_slots); X } else if (kp->code == K_MACRO_DEFINE) { X /* Change macro. */ X kp->lhs = lhs; X kp->rhs = rhs; X } else { X msg(m_nomacro); X } X } X } X free(buf); X} X Xvoid Xprt_macros() X{ X t_keymap *kp; X int used, total; X unsigned char *ptr; X X erase(); X scrollok(stdscr, TRUE); X for (used = total = 0, kp = key_map; kp->code != K_ERROR; ++kp) { X if (kp->code == K_MACRO_DEFINE) { X ++total; X if (kp->rhs != NULL) { X ++used; X addch('{'); X ptr = (unsigned char *) kp->lhs; X for (; *ptr != '\0'; ++ptr) X addstr(printable(*ptr)); X addstr("}\t{"); X ptr = (unsigned char *) kp->rhs; X for (; *ptr != '\0'; ++ptr) X addstr(printable(*ptr)); X addstr("}\n"); X (void) more(used); X } X } X } X printw("\n%d/%d\n", used, total); X scrollok(stdscr, FALSE); X (void) more(-1); X redraw(); X} X X/* X * Return true if more should continue. X */ Xint Xmore(row) Xint row; X{ X int ch; X X if (0 < row % (LINES-1)) X return (TRUE); X standout(); X addstr(getmsg(p_more)); X standend(); X clrtoeol(); X refresh(); X ch = getliteral(); X addch('\r'); X clrtoeol(); X return (ch != getmsg(p_quit)[1] && ch != getmsg(p_no)[1]); X} X X/* X * Flip the case of a region. X */ Xvoid Xflipcase() X{ X t_char *p; X t_region r; X for (getregion(&r); r.left <= r.right; ++r.left) { X p = ptr(r.left); X if (islower(*p)) { X *p = toupper(*p); X modified = TRUE; X } else if (isupper(*p)) { X *p = tolower(*p); X modified = TRUE; X } X } X if (marker == NOMARK) X right(); X} X Xvoid Xprompt(m, buf, len) Xt_msg m; Xchar *buf; Xsize_t len; X{ X standout(); X mvaddstr(MSGLINE, 0, getmsg(m)); X standend(); X clrtoeol(); X addch(' '); X refresh(); X getinput(buf, len, TRUE); X} X X/* X * Return 1 if offset points to first-half of CR-LF; X * 2 if offset points to second-half of CR-LF; 0 otherwise. X */ Xint Xiscrlf(offset) Xregister t_point offset; X{ X register t_char *p; X X p = ptr(offset); X if (*p == '\r') { X /* Look to the right for '\n'. */ X if (++offset < pos(ebuf) && *ptr(offset) == '\n') X return (1); X } else if (*p == '\n') { X /* Look to the left for '\r'. */ X if (pos(buf) < offset && *ptr(--offset) == '\r') X return (2); X } X return (0); X} END-of-command.c echo x - key.c sed 's/^X//' >key.c << 'END-of-key.c' X/* X * key.c X * X * Anthony's Editor October 95 X * X * Copyright 1993, 1995 by Anthony Howe. All rights reserved. No warranty. X */ X X#include X#include X#include X#include "header.h" X#include "key.h" X X/* Variable length structure. */ Xtypedef struct t_input { X struct t_input *next; X char *ptr; X char buf[1]; X} t_input; X Xstatic t_input *istack = NULL; Xstatic char blank[] = " \t\r\n"; X Xstatic int k_default _((t_keymap *)); Xstatic int k_define _((t_keymap *)); Xstatic int k_erase _((t_keymap *)); Xstatic int k_itself _((t_keymap *)); Xstatic int k_kill _((t_keymap *)); Xstatic int k_token _((t_keymap *)); Xstatic t_keymap *growkey _((t_keymap *, size_t)); Xstatic int ipush _((char *)); Xstatic int ipop _((void)); Xstatic void iflush _((void)); X Xt_keyinit keywords[] = { X { K_INSERT_ENTER, ".insert_enter", k_default }, X { K_INSERT_EXIT, ".insert_exit", k_default }, X { K_DELETE_LEFT, ".delete_left", k_default }, X { K_DELETE_RIGHT, ".delete_right", k_default }, X { K_FLIP_CASE, ".flip_case", k_default }, X { K_BLOCK, ".block", k_default }, X { K_CUT, ".cut", k_default }, X { K_PASTE, ".paste", k_default }, X { K_UNDO, ".undo", k_default }, X { K_CURSOR_UP, ".cursor_up", k_default }, X { K_CURSOR_DOWN, ".cursor_down", k_default }, X { K_CURSOR_LEFT, ".cursor_left", k_default }, X { K_CURSOR_RIGHT, ".cursor_right", k_default }, X { K_PAGE_UP, ".page_up", k_default }, X { K_PAGE_DOWN, ".page_down", k_default }, X { K_WORD_LEFT, ".word_left", k_default }, X { K_WORD_RIGHT, ".word_right", k_default }, X { K_LINE_LEFT, ".line_left", k_default }, X { K_LINE_RIGHT, ".line_right", k_default }, X { K_FILE_TOP, ".file_top", k_default }, X { K_FILE_BOTTOM, ".file_bottom", k_default }, X { K_HELP, ".help", k_default }, X { K_HELP_OFF, ".help_off", k_token }, X { K_MACRO, ".macro", k_default }, X { K_MACRO_DEFINE, ".macro_define", k_define }, X { K_QUIT, ".quit", k_default }, X { K_QUIT_ASK, ".quit_ask", k_default }, X { K_FILE_READ, ".file_read", k_default }, X { K_FILE_WRITE, ".file_write", k_default }, X { K_STTY_ERASE, ".stty_erase", k_erase }, X { K_STTY_KILL, ".stty_kill", k_kill }, X { K_ITSELF, ".itself", k_itself }, X { K_REDRAW, ".redraw", k_default }, X { K_SHOW_VERSION, ".show_version", k_default }, X { K_LITERAL, ".literal", k_default }, X { K_ERROR, NULL, NULL } X}; X Xint Xismsg(str) Xchar *str; X{ X char *ptr; X for (ptr = str; isdigit(*ptr); ++ptr) X ; X return (str < ptr && *ptr == ':'); X} X X/* X * Read a configuration file from either the current directory or X * the user's home directory. Return an error status. Pass-back X * either a pointer to a key mapping table, or NULL if an error X * occured. X */ Xint Xinitkey(fn, keys) Xchar *fn; Xt_keymap **keys; X{ X FILE *fp; X int error; X t_keyinit *kp; X t_keymap *array; X size_t len, count; X char *buf, *token, *lhs, *rhs; X X *keys = NULL; X if ((fp = openrc(fn)) == NULL) X return (INITKEY_OPEN); X X /* Allocate an array big enough to hold at least one of everything. */ X if ((array = growkey(NULL, len = K_MAX_CODES)) == NULL) { X error = INITKEY_ALLOC; X goto error1; X } X X count = 0; X for ( ; (error = getblock(fp, &buf)) != GETBLOCK_EOF; free(buf)) { X if (error == GETBLOCK_ALLOC) { X error = INITKEY_ALLOC; X goto error1; X } X X /* Strip \r\n from end of buffer. */ X if ((token = strrchr(buf, '\n')) != NULL) { X if (buf < token && token[-1] == '\r') X --token; X *token = '\0'; X } X X if (ismsg(buf)) { X long index; X X token = encode(buf); X if (token == (char *) 0) { X error = INITKEY_ALLOC; X goto error1; X } X X index = strtol(token, &token, 0); X if (0 < index) X message[index] = token+1; X continue; X } X X if (buf[0] != '.' X || (token = strtok(buf, blank)) == NULL X || (kp = findikey(keywords, strlwr(token))) == NULL) X continue; X X array[count].code = kp->code; X X /* Determine lhs and rhs parameters. */ X if ((lhs = strtok((char *) 0, blank)) != (char *) 0) { X rhs = strtok((char *) 0, blank); X X array[count].lhs = encode(lhs); X if (array[count].lhs == (char *) 0) { X error = INITKEY_ERROR; X goto error1; X } X X /* Find rhs if present. */ X if (rhs != (char *) 0 X && (array[count].rhs = encode(token)) == (char *) 0) { X error = INITKEY_ERROR; X goto error1; X } X } else { X /* No parameters for keyword. */ X array[count].lhs = array[count].rhs = (char *) 0; X } X X if (kp->fn != NULL && !(*kp->fn)(&array[count])) { X error = INITKEY_ERROR; X goto error1; X } X ++count; X X if (len <= count) { X t_keymap *new; X len += K_MAX_CODES; X if ((new = growkey(array, len)) == NULL) { X error = INITKEY_ALLOC; X goto error1; X } X array = new; X } X } X error = INITKEY_OK; X *keys = array; Xerror1: X (void) fclose(fp); X array[count].code = K_ERROR; X if (error != INITKEY_OK) X finikey(array); X X return (error); X} X Xvoid Xfinikey(keys) Xt_keymap *keys; X{ X t_keymap *kp; X if (keys != NULL) { X for (kp = keys; kp->code != K_ERROR; ++kp) { X if (kp->lhs != (char *) 0) X free(kp->lhs); X if (kp->rhs != (char *) 0) X free(kp->rhs); X } X free(keys); X } X} X X/* X * .function string X */ Xstatic int Xk_default(kp) Xt_keymap *kp; X{ X if (kp->lhs == NULL) X return (FALSE); X if (kp->rhs != NULL) { X free(kp->lhs); X return (FALSE); X } X return (TRUE); X} X X/* X * .macro_define X * .macro_define lhs rhs X * X * The first case is used as a place holder to reserve macro X * space. The second case actual defines a macro. X */ Xstatic int Xk_define(kp) Xt_keymap *kp; X{ X if (kp->lhs != NULL && kp->rhs == NULL) { X free(kp->lhs); X return (FALSE); X } X return (TRUE); X} X X/* X * .token X */ Xstatic int Xk_token(kp) Xt_keymap *kp; X{ X if (kp->lhs != NULL) { X free(kp->lhs); X return (FALSE); X } X return (TRUE); X} X X/* X * .itself character X */ Xstatic int Xk_itself(kp) Xt_keymap *kp; X{ X if (!k_default(kp)) X return (FALSE); X kp->code = *(unsigned char *) kp->lhs; X kp->lhs[1] = '\0'; X return (TRUE); X} X X/* X * .stty_erase X */ Xstatic int Xk_erase(kp) Xt_keymap *kp; X{ X char buf[2]; X X if (!k_token(kp)) X return (FALSE); X buf[0] = erasechar(); X buf[1] = '\0'; X return ((kp->lhs = strdup(buf)) != NULL); X} X X/* X * .stty_kill X */ Xstatic int Xk_kill(kp) Xt_keymap *kp; X{ X char buf[2]; X X if (!k_token(kp)) X return (FALSE); X buf[0] = killchar(); X buf[1] = '\0'; X return ((kp->lhs = strdup(buf)) != NULL); X} X X/* X * Find token and return corresponding table entry; else NULL. X */ Xt_keymap * Xfindkey(kp, token) Xt_keymap *kp; Xchar *token; X{ X for (; kp->code != K_ERROR; ++kp) X if (kp->lhs != NULL && strcmp(token, kp->lhs) == 0) X return (kp); X return (NULL); X} X Xt_keyinit * Xfindikey(kp, token) Xt_keyinit *kp; Xchar *token; X{ X for (; kp->code != K_ERROR; ++kp) X if (kp->lhs != NULL && strcmp(token, kp->lhs) == 0) X return (kp); X return (NULL); X} X X/* X * X */ Xstatic t_keymap * Xgrowkey(array, len) Xt_keymap *array; Xsize_t len; X{ X t_keymap *new; X if (len == 0) X return (NULL); X len *= sizeof (t_keymap); X if (array == NULL) X return ((t_keymap *) malloc(len)); X return ((t_keymap *) realloc(array, len)); X} X Xint Xgetkey(keys) Xt_keymap *keys; X{ X t_keymap *k; X int submatch; X static char buffer[K_BUFFER_LENGTH]; X static char *record = buffer; X X /* If recorded bytes remain, return next recorded byte. */ X if (*record != '\0') X return (*(unsigned char *)record++); X /* Reset record buffer. */ X record = buffer; X do { X if (K_BUFFER_LENGTH < record - buffer) { X record = buffer; X buffer[0] = '\0'; X return (K_ERROR); X } X /* Read and record one byte. */ X *record++ = getliteral(); X *record = '\0'; X X /* If recorded bytes match any multi-byte sequence... */ X for (k = keys, submatch = FALSE; k->code != K_ERROR; ++k) { X if (k->lhs == NULL || k->code == K_DISABLED) X continue; X if (strncmp(buffer, k->lhs, record-buffer) != 0) X continue; X if (k->lhs[record-buffer] == '\0') { X /* Exact match. */ X if (k->code != K_MACRO_DEFINE) { X /* Return extended key code. */ X return (k->code); X } X if (k->rhs != NULL) { X (void) ipush(k->rhs); X record = buffer; X } X } X /* Recorded bytes match anchored substring. */ X submatch = TRUE; X break; X } X /* If recorded bytes matched an anchored substring, loop. */ X } while (submatch); X /* Return first recorded byte. */ X record = buffer; X return (*(unsigned char *)record++); X} X Xint Xgetliteral() X{ X int ch; X X ch = ipop(); X if (ch == EOF) X return ((unsigned) getch()); X return (ch); X} X X/* X * Return true if a new input string was pushed onto the stack, X * else false if there was no more memory for the stack. X */ Xstatic int Xipush(buf) Xchar *buf; X{ X t_input *new; X X new = (t_input *) malloc(sizeof (t_input) + strlen (buf)); X if (new == NULL) X return (FALSE); X (void) strcpy(new->buf, buf); X new->ptr = new->buf; X new->next = istack; X istack = new; X return (TRUE); X} X X/* X * Pop and return a character off the input stack. Return EOF if X * the stack is empty. If the end of an input string is reached, X * then free the node. This will allow clean tail recursion that X * won't blow the stack. X */ Xstatic int Xipop() X{ X int ch; X t_input *node; X X if (istack == NULL) X return (EOF); X ch = (unsigned) *istack->ptr++; X if (*istack->ptr == '\0') { X node = istack; X istack = istack->next; X free(node); X } X return (ch); X} X X/* X * Flush the entire input stack. X */ Xstatic void Xiflush() X{ X t_input *node; X X while (istack != NULL) { X node = istack; X istack = istack->next; X free(node); X } X} X Xint Xismacro() X{ X return (istack != NULL); X} X X/* X * Field input. X */ Xtypedef struct t_keyfield { X int code; X int (*func) _((void)); X} t_keyfield; X Xstatic int fld_done _((void)); Xstatic int fld_erase _((void)); Xstatic int fld_kill _((void)); Xstatic int fld_left _((void)); Xstatic int fld_insert _((void)); X X#define ERASE_KEY 0 X#define KILL_KEY 1 X Xstatic t_keyfield ktable[] = { X { K_STTY_ERASE, fld_erase }, X { K_STTY_KILL, fld_kill }, X { '\r', fld_done }, X { '\n', fld_done }, X { '\b', fld_erase }, X { -1, fld_insert } X}; X Xstatic int fld_row; Xstatic int fld_col; Xstatic int fld_key; Xstatic int fld_echo; Xstatic int fld_index; Xstatic int fld_length; Xstatic char *fld_buffer; X X#ifndef getmaxyx X#define getmaxyx(w,r,c) (r=LINES,c=COLS) X#endif X Xint Xgetinput(buf, len, echoing) Xchar *buf; Xint len, echoing; X{ X int first; X t_keyfield *k; X fld_buffer = buf; X fld_index = (int) strlen(fld_buffer); X fld_length = len < 0 ? COLS : len; X if (--fld_length < 1) X return (FALSE); X ktable[ERASE_KEY].code = erasechar(); X ktable[KILL_KEY].code = killchar(); X fld_echo = echoing; X getyx(stdscr, fld_row, fld_col); X addstr(fld_buffer); X move(fld_row, fld_col); X for (first = TRUE;; first = FALSE) { X refresh(); X fld_key = getliteral(); X for (k = ktable; k->code != -1 && k->code != fld_key; ++k) X ; X if (first && k->func == fld_insert) X fld_kill(); X if (k->func != NULL && !(*k->func)()) { X fld_buffer[fld_index] = '\0'; X break; X } X } X return (TRUE); X} X Xstatic int Xfld_done() X{ X return (FALSE); X} X Xstatic int Xfld_left() X{ X int row, col, max_row, max_col; X getyx(stdscr, row, col); X getmaxyx(stdscr, max_row, max_col); X if (0 < fld_index) { X --fld_index; X /* Assume that if 0 < fld_index then fld_row <= row X * and fld_col < col. So when fld_index == 0, then X * fld_row == row and fld_col == col. X */ X if (0 < col) { X --col; X } else if (0 < row) { X /* Handle reverse line wrap. */ X --row; X col = max_col-1; X } X move(row, col); X } X return (TRUE); X} X Xstatic int Xfld_erase() X{ X int row, col; X if (0 < fld_index) { X fld_left(); X getyx(stdscr, row, col); X addch(' '); X move(row, col); X fld_buffer[fld_index] = '\0'; X } X return (TRUE); X} X Xstatic int Xfld_kill() X{ X move(fld_row, fld_col); X while (0 < fld_index--) X addch(' '); X move(fld_row, fld_col); X fld_buffer[0] = '\0'; X fld_index = 0; X return (TRUE); X} X Xstatic int Xfld_insert() X{ X if (fld_index < fld_length) { X if (!ISFUNCKEY(fld_key)) { X fld_buffer[fld_index++] = fld_key; X if (fld_echo) X addch(fld_key); X } X } X return (fld_index < fld_length); X} X X END-of-key.c echo x - main.c sed 's/^X//' >main.c << 'END-of-main.c' X/* X * main.c X * X * Anthony's Editor October 95 X * X * Copyright 1993, 1995 by Anthony Howe. All rights reserved. No warranty. X */ X X#include X#include X#include "header.h" X Xstatic int intsig = FALSE; X X#ifdef SIGINT Xstatic void Xsigint(sig) Xint sig; X{ X intsig = TRUE; X} X#endif X X#ifdef ATARI_ST X#include X Xstatic jmp_buf ignore; Xstatic void (*old_sigint) _((int)); X Xstatic void Xsigint(sig) Xint sig; X{ X intsig = TRUE; X longjmp(ignore, 1); X} X#endif /* ATARI_ST */ X X#ifndef KEY_LENGTH X#define KEY_LENGTH 10 X#endif X X#ifdef TERMCAP Xextern char *tgetstr _((char *, char **)); Xchar termcap[1024]; X#endif X Xint Xmain(argc, argv) Xint argc; Xchar **argv; X{ X int i; X t_keymap *kp; X char *ap, *config; X X /* Find basename. */ X prog_name = *argv; X i = strlen(prog_name); X while (0 <= i && prog_name[i] != '\\' && prog_name[i] != '/') X --i; X prog_name += i+1; X X /* Parse options. */ X config = CONFIG; X for (--argc, ++argv; 0 < argc && **argv == '-'; --argc, ++argv) { X ap = &argv[0][1]; X if (*ap == '-' && ap[1] == '\0') { X /* -- terminates options. */ X --argc; X ++argv; X break; X } X while (*ap != '\0') { X switch (*ap++) { X case 'f': X /* -f or -f */ X X if (*ap != '\0') { X config = ap; X } else if (1 < argc) { X config = *++argv; X --argc; X } else { X fatal(f_usage); X } X break; X default: X fatal(f_usage); X } X break; X } X } X X if (initscr() == NULL) X fatal(f_initscr); X X#ifdef TERMCAP X (void) tgetent(termcap, getenv("TERM")); X#endif X X if (initkey(config, &key_map) != INITKEY_OK) X fatal(f_config); X X /* Determine if editor is modeless or not. X * Define insert mode keys from the master table. X */ X for (modeless = TRUE, kp = key_map; kp->code != K_ERROR; ++kp) { X switch (kp->code) { X case K_INSERT_ENTER: X modeless = FALSE; X break; X case K_INSERT_EXIT: X kp->code = K_DISABLED; X key_mode[0].lhs = kp->lhs; X break; X case K_STTY_ERASE: X key_mode[1].lhs = kp->lhs; X break; X case K_LITERAL: X key_mode[2].lhs = kp->lhs; X break; X case K_HELP_OFF: X textline = 0; X break; X } X } X X noecho(); X lineinput(FALSE); X idlok(stdscr, TRUE); X X if (0 < argc) { X (void) load(*argv); X /* Save filename irregardless of load() success. */ X strcpy(filename, *argv); X modified = FALSE; X } X if (!growgap(CHUNK)) X fatal(f_alloc); X X top(); X i = msgflag; X help(); X msgflag = i; X X /* Disable recognition of user interrupt. */ X#ifdef SIGQUIT X if (signal(SIGQUIT, SIG_IGN) == SIG_ERR) X fatal(f_error); X#endif X#ifdef SIGINT X if (signal(SIGINT, SIG_IGN) == SIG_ERR) X fatal(f_error); X#endif X#ifdef ATARI_ST X old_sigint = (void (*)()) Setexc(0x102, sigint); X if (setjmp(ignore) != 0) X msg(m_interrupt); X#endif X while (!done) { X i = 0; X input = getkey(key_map); X while (table[i].key != 0 && input != table[i].key) X ++i; X if (table[i].func != NULL) X (*table[i].func)(); X else if (modeless) X insert(); X display(table[i].disp); X } X X#ifdef SIGQUIT X (void) signal(SIGQUIT, SIG_DFL); X#endif X#ifdef SIGINT X (void) signal(SIGINT, SIG_DFL); X#else X#ifdef ATARI_ST X (void) Setexc(0x102, old_sigint); X#endif X#ifdef __MSDOS__ X#endif X#endif /* SIGINT */ X X if (scrap != NULL) X free(scrap); X finikey(key_map); X move(LINES-1, 0); X refresh(); X endwin(); X putchar('\n'); X return (0); X} X X#ifdef TERMIOS X#include X X/* X * Set the desired input mode. X * X * FALSE enables immediate character processing (disable line processing X * and signals for INTR, QUIT, and SUSP). TRUE enables line processing X * and signals (disables immediate character processing). In either X * case flow control (XON/XOFF) is still active. X * X * If the termios function calls fail, then fall back on using X * CURSES' cbreak()/nocbreak() functions; however signals will be X * still be in effect. X */ Xvoid Xlineinput(bf) Xint bf; X{ X int error; X struct termios term; X error = tcgetattr(fileno(stdin), &term) < 0; X if (!error) { X if (bf) X term.c_lflag |= ISIG | ICANON; X else X term.c_lflag &= ~(ISIG | ICANON); X error = tcsetattr(fileno(stdin), TCSANOW, &term) < 0; X } X /* Fall back on CURSES functions that do almost what we need if X * either tcgetattr() or tcsetattr() fail. X */ X if (error) { X if (bf) X nocbreak(); X else X cbreak(); X } X} X#endif /* TERMIOS */ X Xvoid Xfatal(m) Xt_msg m; X{ X if (curscr != NULL) { X move(LINES-1, 0); X refresh(); X endwin(); X putchar('\n'); X } X fprintf(stderr, getmsg(m), prog_name); X if (m == f_ok) X exit(0); X if (m == f_error) X exit(1); X if (m == f_usage) X exit(2); X exit(3); X} X X#ifdef va_dcl Xvoid Xmsg(va_alist) Xva_dcl X{ X long num; X char *f, *m; X va_list args; X X va_start(args); X f = getmsg(va_arg(args, t_msg)); X for (m = msgline; *f != '\0'; ) { X if (*f == '%') { X switch (*++f) { X case 's': X (void) strcpy(m, va_arg(args, char *)); X break; X case 'l': X if (*++f != 'd') { X (void) strcpy(m, "UNSUPPORTED"); X break; X } X num = va_arg(args, long); X /* fall */ X case 'd': X if (f[-1] == '%') X num = (long) va_arg(args, int); X sprintf(m, "%ld", num); X break; X } X m += strlen(m); X ++f; X } else { X *m++ = *f++; X } X } X *m = '\0'; X va_end(args); X msgflag = TRUE; X} X#else /* not va_dcl */ X#ifdef __STDC__ Xvoid Xmsg(t_msg m, ...) X#else Xvoid Xmsg(m) Xt_msg m; X#endif /* __STDC__ */ X{ X va_list args; X va_start(args, m); X (void) vsprintf(msgline, getmsg(m), args); X va_end(args); X msgflag = TRUE; X} X#endif /* va_dcl */ X X/* X * Return a pointer to a message. X * Messages have the format "number:text", where X * number is an index into a message table and text X * is the default text if no message defined. X */ Xchar * Xgetmsg(m) Xt_msg m; X{ X char *text; X long index; X X index = strtol(m, &text, 0); X if (0 <= index && message[index] != NULL) X return (message[index]); X return (text+1); X} X X/* X * Convert a string to lower case. Return the string pointer. X */ Xchar * Xstrlwr(str) Xchar *str; X{ X register char *s; X for (s = str; *s != '\0'; ++s) X if (isupper(*s)) X *s = tolower(*s); X return (str); X} X X/* X * Make a duplicate of a string. Return a pointer to an allocated X * copy of the string, or NULL if malloc() failed. X */ Xchar * Xstrdup(str) Xconst char *str; X{ X char *new; X if ((new = (char*) malloc(strlen(str)+1)) != NULL) X (void) strcpy(new, str); X return (new); X} X X/* X * Replace old with new characters. If method X * negative Nth occurence from the end; X * 0 all occurences; X * positive Nth occurence from the beginning. X */ Xchar * Xstrrep(str, old, new, method) Xchar *str; Xint old, new, method; X{ X register char *ptr = str; X register int direction = 1; X X if (method == 0) { X /* All occurences. */ X for (; *ptr != '\0'; ++ptr) X if (*ptr == old) X *ptr = new; X return (str); X } else if (method < 0) { X /* Start from the end going backwards. */ X direction = -1; X ptr = &str[strlen(str)] - 1; X method = -method; X } X X /* Change the Nth occurence. */ X for (; *ptr != '\0'; ptr += direction) { X if (*ptr == old && --method <= 0) { X *ptr = new; X break; X } X } X X return (str); X} X X/* X * X */ Xchar * Xpathname(path, file) Xchar *path, *file; X{ X char *buf; X size_t plen, flen; X X plen = path == NULL ? 0 : strlen(path); X flen = file == NULL ? 0 : strlen(file); X buf = (char*) malloc(plen + flen + 2); X if (buf == NULL) X return (NULL); X (void) strcpy(buf, path); X buf[plen] = '/'; X (void) strcpy(&buf[plen+1], file); X return (buf); X} X X/* X * Open resource file. X * Search order is: abs, ./rel, $HOME/rel, $ETCDIR/rel X */ XFILE * Xopenrc(fn) Xchar *fn; X{ X FILE *fp; X char *ptr, *buf; X X if ((fp = fopen(fn, "r")) != NULL) X return (fp); X X if ((ptr = getenv("HOME")) != NULL X && (buf = pathname(ptr, fn)) != NULL) { X fp = fopen(buf, "r"); X#ifdef EITHER_SLASH X if (fp == NULL) X fp = fopen(strrep(buf, '/', '\\', 0), "r"); X#endif /* EITHER_SLASH */ X free(buf); X if (fp != NULL) X return (fp); X } X X if ((ptr = getenv("ETCDIR")) != NULL X && (buf = pathname(ptr, fn)) != NULL) { X fp = fopen(buf, "r"); X#ifdef EITHER_SLASH X if (fp == NULL) X fp = fopen(strrep(buf, '/', '\\', 0), "r"); X#endif /* EITHER_SLASH */ X free(buf); X if (fp != NULL) X return (fp); X } X X return (NULL); X} X X/* X * Get an arbitrarily long line of text from a file. X * The read is terminated when an unescaped newline is found. X * The buffer that is passed back in ptr will be '\0' terminated. X * If an error occurs, the contents of ptr will be undefined. X */ Xlong Xgetblock(fp, ptr) XFILE *fp; Xchar **ptr; X{ X int ch, escape; X char *buf, *new; X size_t blen, len = 0; X X *ptr = NULL; X if ((buf = (char *) malloc(blen = BUFSIZ)) == NULL) X return (GETBLOCK_ALLOC); X X escape = FALSE; X while ((ch = fgetc(fp)) != EOF) { X buf[len++] = ch; X X if (ch == '\n') { X if (escape) { X len -= 2; X escape = FALSE; X continue; X } X buf[len] = '\0'; X break; X } X escape = !escape && ch == '\\'; X X if (blen <= len) { X blen += BUFSIZ; X if ((new = (char*) realloc(buf, blen)) == NULL) { X free(buf); X return (GETBLOCK_ALLOC); X } X buf = new; X } X } X X if (ferror(fp)) { X free(buf); X return (GETBLOCK_ERROR); X } X if (feof(fp)) { X free(buf); X return (GETBLOCK_EOF); X } X X buf[len++] = '\0'; X X /* Shrink buffer to exact size required for the string. */ X if ((new = (char *) realloc(buf, len)) == NULL) X new = buf; X *ptr = new; X return (len); X} X X/* X * Return a pointer to an encoded dynamic string, else null. X */ Xchar * Xencode(buf) Xchar *buf; X{ X int count; X unsigned long number; X char *new, *store, *fetch, *ctrl; X static char escmap[] = "\033\033bfnrst"; X static char escvalue[] = "eE\b\f\n\r \t"; X static char control[] = "@abcdefghijklmnopqrstuvwxyz[\\]^_"; X X /* Find end of string and count '$'. */ X for (count = 0, fetch = buf; *fetch != '\0'; ++fetch) X switch (*fetch) { X case '\\': X if (*++fetch == '\0') X --fetch; X break; X case '$': X ++count; X break; X } X X /* Allocate new string buffer with room for expansion of X * $key_name strings. X */ X new = (char *) malloc((fetch - buf) + 1 + count * KEY_LENGTH); X if (new == (char *) 0) X goto error1; X X for (store = new, fetch = buf; *fetch != '\0'; ) { X switch (*fetch) { X case '$': X if (*++fetch != '(') X goto error2; X ++fetch; X#ifdef TERMCAP X /* Termcap ids are two characters long. */ X if (fetch[2] != ')') X goto error2; X X if (tgetstr(fetch, &store) == (char *) 0) X *store++ = '\a'; X X fetch += 3; X#else X /* Terminfo capnames are 2 to 5 characters long. */ X for (ctrl = fetch; *fetch != ')'; ++fetch) X if (*fetch == '\0') X goto error2; X X /* Modify the source buffer! */ X *fetch++ = '\0'; X X if ((ctrl = tigetstr(ctrl)) == (char *) -1) X goto error2; X X (void) strcpy(store, ctrl); X store += strlen(ctrl); X#endif X break; X case '^': X ++fetch; X if (*fetch == '?') { X /* ^? equals ASCII DEL character. */ X *store++ = 0x7f; X } else { X /* ASCII dependant control key mapping. */ X if (isupper(*fetch)) X *fetch = tolower(*fetch); X if ((ctrl = strchr(control, *fetch)) == NULL) X /* Not a control key mapping. */ X goto error2; X *store++ = (char) (ctrl - control); X } X ++fetch; X break; X case '\\': X /* Escapes. */ X ++fetch; X if (isdigit(*fetch)) { X /* Numeric escapes allow for X * octal \0nnn X * hex \0xnn X * decimal \nnn X */ X number = strtol(fetch, &fetch, 0); X if (number < 0 || 255 < number) X /* Number not in range 0..255. */ X goto error2; X *store++ = (char) number; X break; X } X if ((ctrl = strchr(escmap, *fetch)) != NULL) { X *store++ = escvalue[ctrl - escmap]; X ++fetch; X break; X } X /* Literal escapes. */ X default: X /* Character. */ X *store++ = *fetch++; X } X } X *store++ = '\0'; X X return new; Xerror2: X free(new); Xerror1: X return (char *) 0; X} X END-of-main.c echo x - modeless.tc sed 's/^X//' >modeless.tc << 'END-of-modeless.tc' XSample Configuration File XModeless Interface with TERMCAP Function Keys XAnthony's Editor Oct 95 XCopyright 1993, 1995 by Anthony Howe. All rights reserved. No warranty. X X1:\ XFile read and write\t\^R \^W\t\tLeft, down, up, right\tarrow keys\n\ XVersion, quit\t\t\^K\^V \^C \^K\^C\tWord left and right\t\^A \^D\n\ XMacros\t\t\t\^KM\t\tPage down and up\t\^N \^P\n\ XHelp on and off\t\tF1\t\tFront and end of line\t\^F \^E\n\ XRedraw\t\t\t\^L\t\tTop and bottom of file\t\^T \^B\n\ XInsert \t\t\ttyped keys\tDelete left and right\tBACKSPACE \^X\n\ XLiteral escape\t\t\^V\t\tBlock, cut, paste\tF2 F3 F4\n\ XUndo\t\t\t\^U\t\tInvert case\t\t\^\^\n X X#.help_off X.literal ^V X.cursor_up $(ku) X.cursor_down $(kd) X.cursor_left $(kl) X.cursor_right $(kr) X.page_up ^P X.page_down ^N X.word_left ^A X.word_right ^D X.line_left ^F X.line_right ^E X.file_top ^T X.file_bottom ^B X.delete_left ^H X.delete_right ^X X.help $(k1) X.block $(k2) X.cut $(k3) X.paste $(k4) X.flip_case ^^ X.undo ^U X.file_read ^R X.file_write ^W X.redraw ^L X.quit_ask ^C X.quit ^K^C X.quit ^K^X X.show_version ^K^V X.macro ^KM X.macro_define X.macro_define X.macro_define X.macro_define X.macro_define X X2:%s: Terminated successfully.\n X3:%s: Unspecified error.\n X4:usage: %s [-f ] [file]\n X5:%s: Failed to initialize the screen.\n X6:%s: Problem with configuration file.\n X7:%s: Failed to allocate required memory.\n X8:Ok. X9:An error occured. X10:No more memory available. X11:File \"%s\" is too big to load. X12:Scrap is empty. Nothing to paste. X13:Failed to find file \"%s\". X14:Failed to open file \"%s\". X15:Failed to close file \"%s\". X16:Failed to read file \"%s\". X17:Failed to write file \"%s\". X18:Not a portable POSIX file name. X19:File \"%s\" %ld bytes. X20:File \"%s\" %ld bytes saved. X21:File \"%s\" %ld bytes read. X22:File \"%s\" modified. X23:Invalid control character or \\number not 0..255. X24:No such macro defined. X25:No more macro space. X26:Interrupt. X27:<< EOF >> X28:Macro : X29:File not saved. Quit (y/n) ? X30:[ Press a key to continue. ] X31:Read file : X32:Write file : X33:Write block : X34:\smore\s X35:\sy\b X36:\sn\b X37:\sq\b X38:Nothing to undo. END-of-modeless.tc echo x - modeless.ti sed 's/^X//' >modeless.ti << 'END-of-modeless.ti' XSample Configuration File XModeless Interface with TERMINFO Function Keys XAnthony's Editor Oct 95 XCopyright 1993, 1995 by Anthony Howe. All rights reserved. No warranty. X X1:\ XFile read and write\t\^R \^W\t\tLeft, down, up, right\tarrow keys\n\ XVersion, quit\t\t\^K\^V \^C \^K\^C\tWord left and right\t\^A \^D\n\ XMacros\t\t\t\^KM\t\tPage down and up\t\^N \^P\n\ XHelp on and off\t\tF1\t\tFront and end of line\t\^F \^E\n\ XRedraw\t\t\t\^L\t\tTop and bottom of file\t\^T \^B\n\ XInsert \t\t\ttyped keys\tDelete left and right\tBACKSPACE \^X\n\ XLiteral escape\t\t\^V\t\tBlock, cut, paste\tF2 F3 F4\n\ XUndo\t\t\t\^U\t\tInvert case\t\tF5\n X X#.help_off X.literal ^V X.cursor_up $(kcuu1) X.cursor_down $(kcud1) X.cursor_left $(kcub1) X.cursor_right $(kcuf1) X.page_up ^P X.page_down ^N X.word_left ^A X.word_right ^D X.line_left ^F X.line_right ^E X.file_top ^T X.file_bottom ^B X.delete_left ^H X.delete_right ^X X.help $(kf1) X.block $(kf2) X.cut $(kf3) X.paste $(kf4) X.flip_case $(kf5) X.undo ^U X.file_read ^R X.file_write ^W X.redraw ^L X.quit_ask ^C X.quit ^K^C X.quit ^K^X X.show_version ^K^V X.macro ^KM X.macro_define X.macro_define X.macro_define X.macro_define X.macro_define X X2:%s: Terminated successfully.\n X3:%s: Unspecified error.\n X4:usage: %s [-f ] [file]\n X5:%s: Failed to initialize the screen.\n X6:%s: Problem with configuration file.\n X7:%s: Failed to allocate required memory.\n X8:Ok. X9:An error occured. X10:No more memory available. X11:File \"%s\" is too big to load. X12:Scrap is empty. Nothing to paste. X13:Failed to find file \"%s\". X14:Failed to open file \"%s\". X15:Failed to close file \"%s\". X16:Failed to read file \"%s\". X17:Failed to write file \"%s\". X18:Not a portable POSIX file name. X19:File \"%s\" %ld bytes. X20:File \"%s\" %ld bytes saved. X21:File \"%s\" %ld bytes read. X22:File \"%s\" modified. X23:Invalid control character or \\number not 0..255. X24:No such macro defined. X25:No more macro space. X26:Interrupt. X27:<< EOF >> X28:Macro : X29:File not saved. Quit (y/n) ? X30:[ Press a key to continue. ] X31:Read file : X32:Write file : X33:Write block : X34:\smore\s X35:\sy\b X36:\sn\b X37:\sq\b X38:Nothing to undo. END-of-modeless.ti exit ----------------------------------------------------------------------- Acknowledgement sent to Anthony Howe : Extra info received and forwarded. Full text available. ----------------------------------------------------------------------- Information forwarded to debian-devel@pixar.com : Bug#1724 ; Package ae . Full text available. ----------------------------------------------------------------------- Message received at debian-bugs: From mdd.comm.mot.com!mitchell Mon Oct 23 07:42:18 1995 Return-Path: Received: from pixar.com by mongo.pixar.com with smtp (Smail3.1.28.1 #15) id m0t7O4v-0005n8C; Mon, 23 Oct 95 07:42 PDT Received: from motgate.mot.com by pixar.com with SMTP id AA26809 (5.67b/IDA-1.5 for debian-bugs-pipe@mongo.pixar.com); Mon, 23 Oct 1995 07:41:50 -0700 Received: from pobox.mot.com (pobox.mot.com [129.188.137.100]) by motgate.mot.com (8.7.1/8.6.10/MOT-3.8) with ESMTP id JAA26309; Mon, 23 Oct 1995 09:42:05 -0500 (CDT) Received: from mdd.comm.mot.com (mdisea.mdd.comm.mot.com [138.242.64.201]) by pobox.mot.com (8.7.1/8.6.10/MOT-3.8) with SMTP id JAA24446; Mon, 23 Oct 1995 09:41:32 -0500 (CDT) Received: from bb29c.mdd.comm.mot.com by mdd.comm.mot.com (4.1/SMI-4.1) id AA07608; Mon, 23 Oct 95 07:41:28 PDT Received: (from mitchell@localhost) by bb29c.mdd.comm.mot.com (8.7.1/8.7.1) id HAA12310; Mon, 23 Oct 1995 07:41:26 -0700 (PDT) Date: Mon, 23 Oct 1995 07:41:26 -0700 (PDT) From: Bill Mitchell Message-Id: <199510231441.HAA12310@bb29c.mdd.comm.mot.com> To: achowe@sentex.net Subject: Re: Bug#1724: unexpected keypress translations (fwd) Cc: debian-bugs@pixar.com Anthony, Thanks for the prompt response. I'd appreciate it if you'd copy debian-bugs@pixar.com on future emails regarding this, and retain the Subject line intact so that our bug tracking system can handle the email properly. achowe@sentex.net said: > The choice for AE to handle multibyte functions itself instead of using > termcap or terminfo, was due to the fact that I couldn't figure out a > portable way to map AE operations to terminfo or termcap, because at the > time there was no standard for Curses. (Now there is XOpen's XCurses > which specifies terminfo.) It was a cheap bypass. > > The workaround for now is to have different config files for each terminal > type and then specify the config file for the terminal in question on > the command line using -f option > > Mean while I'll attempt to solve this problem for you. BTW does Linux > use termcap or terminfo? There are many linux distributions, and the answer to this question will differ from one to another. I'm building ae for inclusion in the Debian GNU/Linux distribution. Currently, debian supports both curses and terminfo. The ae program for debian currently uses libcurses (and termcap) because that's a shared library and executable size is a primary concern. The plan for future releases, when libncurses is released as a shared library, is to switch to libncurses (and terminfo). ----------------------------------------------------------------------- Acknowledgement sent to Bill Mitchell : Extra info received and forwarded. Full text available. ----------------------------------------------------------------------- Information forwarded to debian-devel@pixar.com : Bug#1724 ; Package ae . Full text available. ----------------------------------------------------------------------- Bug reassigned from package `xstd' to `ae'. Request was from Ian Jackson to debian-bugs-request@pixar.com . Full text available. ----------------------------------------------------------------------- Bug reopened, originator set to Ian Jackson . Request was from Ian Jackson to debian-bugs-request@pixar.com . Full text available. ----------------------------------------------------------------------- Message received at debian-bugs: From chiark.chu.cam.ac.uk!ian Sun Oct 22 19:38:08 1995 Return-Path: Received: from pixar.com by mongo.pixar.com with smtp (Smail3.1.28.1 #15) id m0t7Cm7-0005OHC; Sun, 22 Oct 95 19:38 PDT Received: from artemis.chu.cam.ac.uk by pixar.com with SMTP id AA25881 (5.67b/IDA-1.5 for debian-bugs-pipe@mongo.pixar.com); Sun, 22 Oct 1995 19:37:06 -0700 Received: from chiark.chu.cam.ac.uk by artemis.chu.cam.ac.uk with smtp (Smail3.1.29.1 #33) id m0t7ClC-0007ubC; Mon, 23 Oct 95 02:37 GMT Received: by chiark.chu.cam.ac.uk id m0t7Cl6-0002bCC (Debian /\oo/\ Smail3.1.29.1 #29.33); Mon, 23 Oct 95 02:37 GMT Message-Id: Date: Mon, 23 Oct 95 02:37 GMT From: Ian Jackson To: Debian bugs submission address Cc: achowe@sentex.net Subject: Re: Bug#1724: unexpected keypress translations (fwd) In-Reply-To: References: Bill Mitchell writes ("Re: Bug#1724: unexpected keypress translations (fwd)"): > The program in question is ae. I thought I'd pass this on > to you. ae uses raw keypress defs in the config file, leading > to this problem. I'm guessing that may have been a size or > complexity tradeoff. The keypresses in question are PC > function keys, which generate different escape sequences > at the non-X11 linux console and in an xterm. Well, that won't work. How does ae drive the screen ? Whatever library it's using for that will provide a facility for interpreting (or at least determining) function key sequences. I've reopened this bug and assigned it to the `ae' package. Ian. > ---------- Forwarded message ---------- > Date: Sun, 22 Oct 95 18:40 GMT > From: Ian Jackson > To: Bill Mitchell , debian-bugs-done@Pixar.com, > Debian developers list > Subject: Re: Bug#1724: unexpected keypress translations > > Bill Mitchell writes ("Bug#1724: unexpected keypress translations"): > > I noticed today that keypress translations are different in an > > xterm window than on a VC not running X. I'm really not sure > > if this is a bug or a case of "you should have expected that", > > but it caused a program expecting the VC-style keypress > > translations to misbehave when it got unexpected keypress > > translations in an xterm window. It seems to me that, unless > > there's some good reason otherwise, default keypress translations > > shouldn't change. > > You should have expected that. Different terminals have different > escape sequences, and an xterm is not the same as a Linux console. > > I'm marking this bug as done. > > If you have a program that doesn't correctly use the terminal > information databases (termcap or terminfo) to interpret keystroke > escapes then that program is buggy. > > > To duplicate, type "cat -v", F1, ^D in a VC; observe the results; > > startx; and do the same thing in an xterm. I know that TERM=linux > > doesn't work right in an xterm and it's necessary to set TERM=xterm, > > but that's another issue (or at least I think it is). > > No, it's not another issue. > > Ian. > ----------------------------------------------------------------------- Acknowledgement sent to Ian Jackson : Extra info received and forwarded. Full text available. ----------------------------------------------------------------------- Information forwarded to debian-devel@pixar.com : Bug#1724 ; Package xstd . Full text available. ----------------------------------------------------------------------- Message received at debian-bugs-done: From chiark.chu.cam.ac.uk!ian Sun Oct 22 11:41:25 1995 Return-Path: Received: from pixar.com by mongo.pixar.com with smtp (Smail3.1.28.1 #15) id m0t75Kn-0006PjC; Sun, 22 Oct 95 11:41 PDT Received: from artemis.chu.cam.ac.uk by pixar.com with SMTP id AA02145 (5.67b/IDA-1.5 for debian-bugs-done-pipe@mongo.pixar.com); Sun, 22 Oct 1995 11:40:56 -0700 Received: from chiark.chu.cam.ac.uk by artemis.chu.cam.ac.uk with smtp (Smail3.1.29.1 #33) id m0t75Jf-0007uYC; Sun, 22 Oct 95 18:40 GMT Received: by chiark.chu.cam.ac.uk id m0t75JV-0002bVC (Debian /\oo/\ Smail3.1.29.1 #29.33); Sun, 22 Oct 95 18:40 GMT Message-Id: Date: Sun, 22 Oct 95 18:40 GMT From: Ian Jackson To: Bill Mitchell , debian-bugs-done@Pixar.com, Debian developers list Subject: Re: Bug#1724: unexpected keypress translations Bill Mitchell writes ("Bug#1724: unexpected keypress translations"): > I noticed today that keypress translations are different in an > xterm window than on a VC not running X. I'm really not sure > if this is a bug or a case of "you should have expected that", > but it caused a program expecting the VC-style keypress > translations to misbehave when it got unexpected keypress > translations in an xterm window. It seems to me that, unless > there's some good reason otherwise, default keypress translations > shouldn't change. You should have expected that. Different terminals have different escape sequences, and an xterm is not the same as a Linux console. I'm marking this bug as done. If you have a program that doesn't correctly use the terminal information databases (termcap or terminfo) to interpret keystroke escapes then that program is buggy. > To duplicate, type "cat -v", F1, ^D in a VC; observe the results; > startx; and do the same thing in an xterm. I know that TERM=linux > doesn't work right in an xterm and it's necessary to set TERM=xterm, > but that's another issue (or at least I think it is). No, it's not another issue. Ian. ----------------------------------------------------------------------- Notification sent to Bill Mitchell : Bug acknowledged by developer. Full text available. ----------------------------------------------------------------------- Reply sent to Ian Jackson : You have taken responsibility. Full text available. ----------------------------------------------------------------------- Message received at debian-bugs: From bb29c.mdd.comm.mot.com!mitchell Sat Oct 21 11:49:43 1995 Return-Path: Received: from pixar.com by mongo.pixar.com with smtp (Smail3.1.28.1 #15) id m0t6izH-000BA6C; Sat, 21 Oct 95 11:49 PDT Received: from motgate.mot.com by pixar.com with SMTP id AA23571 (5.67b/IDA-1.5 for debian-bugs-pipe@mongo.pixar.com); Sat, 21 Oct 1995 11:49:17 -0700 Received: from pobox.mot.com (pobox.mot.com [129.188.137.100]) by motgate.mot.com (8.6.11/8.6.10/MOT-3.8) with ESMTP id NAA18648 for ; Sat, 21 Oct 1995 13:49:37 -0500 Received: from mdisea.mdd.comm.mot.com (mdisea.mdd.comm.mot.com [138.242.64.201]) by pobox.mot.com (8.6.11/8.6.10/MOT-3.8) with ESMTP id NAA22063 for ; Sat, 21 Oct 1995 13:49:35 -0500 Received: from bb29c.mdd.comm.mot.com (bb29c.mdd.comm.mot.com [138.242.72.29]) by mdisea.mdd.comm.mot.com (8.7.1/8.7.1) with ESMTP id KAA04425 for ; Sat, 21 Oct 1995 10:06:37 -0700 (PDT) Received: (from mitchell@localhost) by bb29c.mdd.comm.mot.com (8.7.1/8.7.1) id KAA11010; Sat, 21 Oct 1995 10:06:32 -0700 (PDT) Date: Sat, 21 Oct 1995 10:06:31 -0700 (PDT) From: Bill Mitchell X-Sender: mitchell@bb29c To: debian-bugs@pixar.com Subject: unexpected keypress translations Message-Id: Mime-Version: 1.0 Content-Type: TEXT/PLAIN; charset=US-ASCII PACKAGE: xstd VERSION: 3.1.2-3 I noticed today that keypress translations are different in an xterm window than on a VC not running X. I'm really not sure if this is a bug or a case of "you should have expected that", but it caused a program expecting the VC-style keypress translations to misbehave when it got unexpected keypress translations in an xterm window. It seems to me that, unless there's some good reason otherwise, default keypress translations shouldn't change. To duplicate, type "cat -v", F1, ^D in a VC; observe the results; startx; and do the same thing in an xterm. I know that TERM=linux doesn't work right in an xterm and it's necessary to set TERM=xterm, but that's another issue (or at least I think it is). I'm no X-windows jock, as must be apparent by now. Just reporting unexpected behavior. mitchell@mdd.comm.mot.com (Bill Mitchell) ----------------------------------------------------------------------- Acknowledgement sent to Bill Mitchell : New bug report received and forwarded. Full text available. ----------------------------------------------------------------------- Report forwarded to debian-devel@pixar.com : Bug#1724 ; Package xstd . Full text available. ----------------------------------------------------------------------- Ian Jackson / iwj10@thor.cam.ac.uk , with the debian-bugs tracking mechanism This page last modified 07:43:01 GMT Wed 01 Nov