pax_global_header00006660000000000000000000000064141555642410014521gustar00rootroot0000000000000052 comment=c694ea4c4a68839fc5c7e1362d4974a784af13d0 vile-9.8v/000077500000000000000000000000001415556424100125265ustar00rootroot00000000000000vile-9.8v/AUTHORS000066400000000000000000000007261415556424100136030ustar00rootroot00000000000000-- $Id: AUTHORS,v 1.5 2013/05/26 10:53:01 tom Exp $ -- vile:txtmode -- This file is used by a script that collects contributor information from the -- "CHANGES*" files and/or checkin comments and resolves nicknames vs -- fullnames. For a complete list of authors, see the "CHANGES*" files, using -- this key for abbreviated names. bod Brendan O'Dea cmorgan Clark O Morgan garyj Gary Jennejohn jrs J Richard Sladkey kev Kevin Buettner pgf Paul G Fox tom Thomas E Dickey vile-9.8v/CHANGES000066400000000000000000013051021415556424100135230ustar00rootroot00000000000000Changes for vile 9.9 (released ??? ??? ?? ????) 20211212 (v) > Lois Mansot + corrected range for &random function. + move the reframe_cursor_position() in update() to ensure that $cwline is shown correctly when viewing [Variables] while showvariables is set. > Mark Robinson: + modify c-filt.c + include the quote chars in the literal colouring for C/C++/Java/etc to make it the same as most other syntax highlighting + add backquote "`" as a quoting character for JavaScript, e.g., for multi-line quotes. + highlight embedded "${xxx}" markers in JavaScript strings using the Ident2 color. + modify sh-filt.l + improve parsing of the beginning of here-document to allow for here-documents piped to programs, e.g., cat < Stephan Schulz: + add popup-choices mode (Savannah #58999) > Tom Dickey: + eliminate filename conflict between vile/xvile in test-packages for FreeBSD ports, e.g., xvile's vileget becomes xvileget. + suppress some of the gcc warnings due to perl header-files. + updated plink.sh, from xterm, to work around poor performance of gcc on Fedora. + modify perl scripts to use /usr/bin/env to locate the perl program, and eliminate sinstall.sh + modify curses-driver to support italics, e.g., as in ncurses 6. + apply Xaw header-fix for XawPlus, neXtaw and Xaw3dxft. + use Xaw3d menu-headers for x11vile.h and x11menu.c (FreeBSD #186420). + replace Header keywords with Id, to make Git-snapshots match. + continue development of xftplain.c (--enable-freetype). The current driver is able to display a single TrueType font using Xft. The menu entries for the bitmap-fonts are replaced by a single menu with sizes. Some of the remaining issues: + provide conversion for X displays other than 24-bit TrueColor + implement fallback fonts, i.e., --enable-fontsets + modify configure script to check for ssp library, needed for some misconfigured libraries when cross-compiling to MinGW. + fix a case in vile-manfilt where cur_line may not have been allocated before first use. + update configure script to work with _Noreturn changes in ncurses 20210320 development version. + modify makefile.in, wrapping cd commands in a subshell to work around "jobs" misfeature of pmake. + improve c-filt.c support for JavaScript + handle ranges, i.e., to avoid stopping on "/" + check for regex after ":" + add m,s,u,y to permissable flags ending regex + quoting-fixes in autoconf macros, per shellcheck warnings. + add check for 'U' in read_quoted() needed to make ^VUxxxx work. + modify lins_chars() to handle a case where a script inserts a UTF-8 character (report by Thomas Dupond). + modify configure/makefiles to support ".PHONY" feature. + change configure/makefiles to use ARFLAGS rather than AR_OPTS + change configure --with-warnings to --enable-warnings for consistency with other configure scripts, using recent changes in that to filter gcc -Werror options to avoid breaking configure checks. + fix a few build problems with --disable-extensions + split-out x11plain.c, to start work on TrueType font support in xvile + modify configure script to allow clang to support loadable filters, since recent configurations work. + add/fix NetBSD pkgsrc-files for 9.8u + update FreeBSD package-files for 9.8u + update config.guess, config.sub 20200517 (u) > Brendan O'Dea: + add smartcase mode (prompted by suggestion by Marc Simpson). > Michael von der Heide + modify vile-spell-filt to allow for umlauts in UTF-8 > Tom Dickey: + add "install-keywords" and "uninstall-keywords" targets to the top-level and filters makefiles. + prove separate a "nmake" highlighter from "make", to color conditional directives and handle special cases of trailing "\". + modify winvile.iss to make the 64-bit installers more distinct from the 32-bit installers. + enable registry-lookup as getenv fallback for WinVile64 + modify nmakemode: + allow for whitespace after "!" in conditional lines + ignore case when matching keywords + fix some issues found with Coverity. + quiet a few gcc9 warnings + correct size-parameter of ZeroMemory calls in ntwinio.c + resave SVG-files with Inkscape 0.92.4 (5da689c313, 2019-01-14), to accommodate version-creep. + improved configure macros to lessen unused-variable warnings in config.log + workaround in configure checks for ncurses vs xcode's c99 "-W" option + fix - python filter should recognize triple single-quoted string (report/patch by Marc Simpson). + fix typos reported by codespell. + add null-pointer checks for continue-search and reverse-search to handle the case where a pattern string was given, but it failed to compile (report by Marc Simpson). + improve configure script for MacOS port: + check for X11 headers in /usr/X11, reflecting Apple's removal of of /usr/include and /usr/include/X11 + suppress -Winline + cleanup *.dSYM directories + don't add gcc/clang options for c89/c99 wrappers which cannot tell what version of gcc/clang they hide. + add tpumode, separating it from dclmode because the keywords differ. also add tpu syntax filter, since syntax differs. + modified a configure-macro to appease autoheader-252. + switch back to the original buffer after displaying result of the show-marks command in "[Named Marks]" (report/patch by Marc Simpson). + modify message when setting a mark in "[Named Marks]" to show that it is ignored (report by Marc Simpson). + regenerate the doc-files from html, using links2 2.14 in Debian 9. also reformat the html files. + trim some unwanted blanks in vile.hlp, overlooked in converting to html (report by Marc Simpson). + add "go" and "typescript" majormodes. + fix a loop-limit in manfilt.c for ANSI CUP. + clone pl-filt.c as pl6filt.c to support perl6, added corresponding "perl6" mode (discussion with Steve Lembark). + add a limit-check in reallyEditMiniBuffer to handle a case where mini-edits clear the working buffer, including the padding (Savannah #56627). + fix no-return warnings from libXt 1.2.0 headers + updated "rev=made" to "rel=author" in html-files. + add configure check for handling of "const" with X Toolkit library + improved configure macros: CF_GNU_SOURCE, CF_INSTALL_OPTS, CF_INSTALL_OPT_S, CF_LD_RPATH_OPT, CF_POSIX_C_SOURCE, CF_VA_COPY, CF_XOPEN_SOURCE, mainly to solve two problems: + non-POSIX use of predefined symbols on BSD platforms + an install option was needed to preserve timestamps + add html meta tags to atr2html for generator and charset. + update gnreight.h from Debian/testing libc6 2.28-6 + add FreeBSD package-files to help with maintaining (FreeBSD #234527, FreeBSD #234528). Note that because of the distinfo files, those will always be one patch behind. + update config.guess, config.sub 20181112 (t) > Adam Denton: + fix a typo in tcap.h (Savannah #52872). > Jeff Morriss: + use strncpy() rather than memcpy() for copying hashed key from crypt(), to work with Fedora 28 which does not necessarily use a fixed-size buffer. > Wayne Cuddy: + modify x11.c to avoid clearing the window manager flags that control focus behavior, to work with ctwm. > Tom Dickey: + add WinVile64 package script for Inno Setup. + show "win64" for $os symbol if built for 64-bit Windows. + add ifdef in winvile.iss to accommodate changes with Inno Setup 5.6.1 + use GetModuleFileNameEx() in preference to looking for winvile's registry keys or the PATH when finding the executable path for the "-Or" option. + improve coloring of "\f" font markers in the nroff filter. + fix a mis-setting in api.c from 9.8q cleanup. + document winvile registry settings in the help-file. + create symbolic links for the utility program's manual pages, point to the base manpage. + document the utility programs and scripts which normally are packaged in the manual page. + if $VILE_LIBDIR_PATH is set, prefer that in vile-libdir-path + corrected glob expression for vile-libdir-path + several fixes using Visual Studio 2017 code analysis, including + w32cmd.c, correct if-statement for IsDialogMessage call + w32misc.c, correct size of allocation for buffer + ensure no leak on failed realloc + modify casts to avoid truncation Some parts of the analysis are false positives; it appears to have problems in the flow analysis for reporting uninitialized values and dereferencing null pointers. In particular, it does not understand the idiom for reallocating an array of types. + build-fix for Visual Studio 2012 and later: the "FILE" struct is opaque. + use registry value for PaddedBorderWidth in winvile to account for misleading results from GetSystemMetrics introduced by Vista. + modify makefile.wnt to allow build with Visual Studio 2012 and later, which omit the Win32.mak file. + fix a couple of unescaped "?" in suffixes for majormodes, e.g., in mvmnmode. + add vcproj and vcxproj majormodes. + add a "report" target in makefile.wnt to show the symbols used in a build to help troubleshoot upgrades to newer Visual Studio. For instance, it is possible to build using Visual Studio Express 2012 with Windows SDK 7.1 by setting APPVER to "5.01". + reorder a comparison in regmatch() to avoid indexing past limits in some cases of multibyte characters. + add a check in set_vattrs() to ensure loop limit is greater than zero to handle a boundary case with double-width characters. + fix or work around gcc8 warnings. + improve initialization of hashed-key for crypt() using memset() on the buffers rather than assuming the hash is the documented length. Even with this, valgrind warns about buffer mismanagement within libcrypt.so. + check for _nc_free_tinfo() for leak-checking with ncurses' tinfo library. + modify perl/ruby filters to ensure the in-memory file ends with nul. + add filters for yaml, rust-modes to develop for a tutorial. + improve iss-filt.l, handling named constants such as {app}. + update iss.key, e.g., setup-directives and runtime functions. + compiler-warning fixes for gcc 7.2.1 with SuSE. + regenerate doc/*.doc from Debian 7 to Debian 8; the table-width changed from links 2.7 to 2.8 + add dummy "]]" in sh-filt.l to work around breakage with flex 2.6.1, which insists on preprocessing C source using m4. + modify character class assumed for tags, to check for graphic characters. Previously that used qident (cf: 9.7g), which did not allow for dots in filenames which could be present in a ctags file if it were generated using "ctags --extra=+f *" (Savannah #51774). + update ftp site url + improved configure macros: CF_ADD_CFLAGS, CF_ADD_INCDIR, CF_BUILD_CC, CF_CC_ENV_FLAGS, CF_CURSES_CPPFLAGS, CF_CURSES_FUNCS, CF_CURSES_LIBS, CF_FIND_LINKAGE, CF_GCC_WARNINGS, CF_GNU_SOURCE, CF_LARGEFILE, CF_MAKEFLAGS, CF_MKSTEMP, CF_NCURSES_CONFIG, CF_NCURSES_VERSION, CF_POSIX_C_SOURCE, CF_PROG_EXT, CF_PROG_GROFF, CF_SIZECHANGE, CF_STRUCT_TERMIOS, CF_TRY_XOPEN_SOURCE, CF_WITH_ICON_THEME, CF_WITH_MAN2HTML, CF_XOPEN_CURSES, CF_XOPEN_SOURCE, CF_X_ATHENA_CPPFLAGS + modify ti-filt.l to allow hexadecimal, as per X/Open Curses documentation. This is different from termcap, which (like terminfo) supports octal and decimal numbers. + build-fixes for Visual Studio 2015 + build-fixes to allow test-compile with ActiveState Perl 5.24.1, which does not work with winvile because its DLL does not provide COM entrypoints, e.g., CoTaskMemFree and CoRegisterClassObject + update config.guess, config.sub 20161217 (s) > Brendan O'Dea: + add command-line parsing for "--" token, assumed by visudo in the 1.8.12 - 1.8.16 changes (report by Wayne Cuddy). > Tom Dickey: + recompute majormode order when "after", "before" or "qualifiers" is modified for a majormode. + add yamlmode (discussion with Steve Lembark) + modify DSTRING definition in lex-filter to handle continuation lines. + modify cfgmode to reduce false-matches with random ".cfg" files. + improve ps syntax filter + interpret %%BeginData / %%EndData keywords + interpret %%BeginPreview / %%EndPreview keywords + add ".mcrl2" as suffix for mcrlmode. + fixes from test-script: conf, hs, nr, rc, rcs, txt, xq, xml + improved regression test-script to check for places where the syntax filter might have mixed buffered- and unbuffered-calls in the same state, causing tokens in the markup to "move". + remove a statement from flt_putc in the standalone filters that converted a bare ^A to ^A?. + remove escaping from digraphs.rc, since change in 9.7zg made that both unnecessary and incorrect (reports by Marc Simpson, Brendan O'Dea). + improve tcl syntax filter + color backslash-escapes in double-quotes. + add rules to handle regexp and regsub regular expressions. This does not yet handle -regexp switch cases. + add call to flt_bfr_error to flag unbalanced quotes here and in a few other filters. + modify newline patterns to allow for cr/lf endings in continuations + add special case for literals like "{\1}" and "{\\1}". + add special case for html entities such as "{{}" and "{&foo;}" + improve sh syntax filter + allow quoted strings within '${' parameter, a detail that can happen with ksh brace groups (report by j. van den hoff). + handle ksh's "ANSI C quotes", i.e., "$'xxx'" using single quotes after a dollar sign. + use the ksh ("-K") option for bashmode and zshmode syntax. + interpret "$name" within '${' parameter + don't warn for inline-here documents + handle special case where matching tag for a here-document is on the same line as a closing ")" in $(xxx) command. + highlight ksh's "[[", "((", "$((" bracketing like "{". + handle ksh's "((" and "$((" arithmetic expressions. + handle ksh's base#value numbers + improve perl syntax highlighter: + fix state used to guess where a pattern might occur, e.g., after an "if" keyword with no preceding operator to account for line breaks. + correct a check for illegal numbers, which flagged hexadecimal numbers containing "e". + distinguish special case of "format =" vs "format =>". + allow pod to begin without a preceding blank line, but warn. + allow for case where pod mode is turned on/off with only one blank line between the directives. + check for simple patterns that may follow operators such as "map". + allow '$', '+' or '&' as a quote or substitution delimiter + allow angle brackets for quotes after 'q', etc. + fix highlighting when square-brackets are used as delimiters in a perl substitution, e.g., s[foo[bar]xxx][yyy] + quiet some unnecessary compiler warnings with glibc > 2.20 by adding _DEFAULT_SOURCE as needed. + improve version-comparison for "new" flex to allow for 2.6.0, and accept that for built-in filters. Also modify filters/mk-2nd.awk to work with "new" flex ifdef's to ignore yywrap (Debian #832973). + correct long-name for filename-ic mode (report Marc Simpson). 20160727 (r) > Marc Simpson: + correct a typo in skipblanksb() which caused up-paragraph "{{" to get stuck (Savannah #47211). > Tom Dickey: + fix an off-by-one in argument list for wvwrap vs winvile that broke edit-with operation from file explorer. + correct expression for QIDENT in rpm-filt.l, sh-filt.l, which could match multiple tokens rather than a single one and interfere with states for here-document. + use CF_PROG_LINT, which checks for cppcheck. Alternatively, this works, though the "$(LIBS)" used in the lint-rule has to be removed: export LINT=cppcheck export LINT_OPTS="--enable=all" + add error-patterns for cppcheck. + updates for configure macros + CF_CC_ENV_FLAGS - don't limit the check to -I, -U and -D options, since the added options can include various compiler options before and after preprocessor options. + CF_FUNC_DLSYM add braces around calls to CF_ADD_LIB which follow a test "&&" operator since the macro uses multiple statements + CF_LD_RPATH_OPT change FreeBSD to use -Wl,-rpath rather than -rpath option. According to FreeBSD #178732, either works since FreeBSD 4.x; however scons does not accept anything except the -Wl,-rpath form. + CF_LIB_PREFIX build-fixes for OS/2 + CF_WITH_MAN2HTML use configured shell + CF_XOPEN_CURSES improve check, making it define NCURSES_WIDECHAR if we happen to be building on a platform (such as OSX) where we do not define _XOPEN_SOURCE or _XOPEN_SOURCE_EXTENDED + CF_XOPEN_SOURCE build-fixes for OS/2 + modify configuration so that "--no-leaks" does not imply "--with-trace", since that is not necessary when using valgrind. + add null-pointer checks in vile-manfilt for some unusual erasures. + promote $filename-ic to a global mode, using this to allow users to do filename-completion on any system ignoring the case of filenames (discussion on vile mailing list started by Marc Simpson). + modify noautobuffer mode to update the "last" buffer when the user jumps around, e.g., using ":e" or the "historical-buffer" toggle (discussion on vile mailing list started by Hymie). + add examples for which-exec and which-source to vile.hlp to show what the popup-buffer might look like when a numeric parameter precedes these commands. + modify parsing of VILE_STARTUP_PATH to accept colon-separated list (report by Chris Green). + improve formatting of vile.hlp (report by Paul Fox). + add mode "keep-position" to allow changing the behavior after applying a command to a range, to better match the nvi (BSD) and vi (Solaris) flavors (prompted by report by Marc Simpson). + reset "$_" before executing each top-level command (report by Marc Simpson). + improve workarounds for building with "new" flex, in particular the change of return-type for yyget_leng() (report by Martin Ward). + make special case when locating the copy of vile which was run, to not warn and skip because it was found in a group-writable directory (discussion with Steve Lembark). + update config.guess, config.sub 20150907 (q) > Brendan O'Dea: + corrected initialization for Vileserv in vileperl.rc (report by Chris Green). > Tom Dickey: + add command-line options -u and -U to set $system-crlf variable before the "unnamed" buffer is initialized. + add $system-crlf to allow override of compiled-in default for "dos" mode so that winvile can be told to create the "unnamed" buffer with linefeed endings (Savannah #44773). + add variable $system-name to show the name used in version message + add checks after write-hook is run in case the script set $return to anything except true or sortoftrue, or if the script set the buffer to "view". In either case, do not proceed to write the buffer (report by Matthew White). + modify prompts for register name to support name-completion, and recognize "register" as a typed macro-parameter (prompted by discussion with Wayne Cuddy). + modify configure macros to use the configured shell rather than just /bin/sh, to accommodate deprecation of non-POSIX shells such as that used in Solaris. + add configure option --with-man2html, use in generating vile-man.html + modify wvwrap to ensure that it does not pass options to winvile as filenames (Savannah #44774). + update autoconf macros from ongoing work in lynx, ncurses and xterm for testing ncurses6. + fix special case of ^G toggling in minibuffer versus '\' escaping (report by Wayne Cuddy). + cleanup logic which sets DOT.o to the beginning of a line, to ensure that the left-margin is used rather than just the first position on a line. + changes in 9.8p for global substitutions with "^" exposed at least one place, e.g., in oneliner.c where DOT was moved to the next line without ensuring that its offset was reset. Review and amend several other occurrences where DOT moves to next or previous line (report by Jan Wells). 20150201 (p) > from https://github.com/ricksladkey/vile (Rick Sladkey): + check in ntconio.c if running in ConEmu, e.g., ConEmuPID variable is set, and if so, allow its bold/italic extensions. + modify ntconio.c to honor Unicode keyboard input. + amend GetCurrentDirectory() buffer size for Unicode. > Tom Dickey: + add configure check for stricmp, omitted from recent Cygwin. + partial fix for recalling from history this command: 'a,.s/$/;/ With the fix, one can edit the previous command, and issue minor variations. + improve suffix rules for mvn mode by allowing a version number in the filename. + improve ant, mvn modes to highlight user-defined tags, e.g., within "${" and "}". + update mvnmode keywords to maven 3.2.5 + modify vile-xml-filt to color property names according to the new "xmlprops" table. + update antmode keywords to ant 1.9.4, including a representative set of property names. The updated table also attempts to distinguish between tasks and subtasks. + add the more useful types/macros from c99 headers to c.key + repaint all windows on an "unnamed" buffer if told to reread and discard changes (report by Hymie on mailing list). + modify logic used in global substitutions to ensure that "^" for beginning of the line is matched only once (report by Wayne Cuddy). + fix a few build problems with --disable-extensions + modify configure macro CF_WITH_APP_DEFAULTS to check OSX-related pathnames for MacPorts and Apple's variant. + improve configure macro CF_SUBDIR_PATH, changing it to a loop, adding /usr/pkg (NetBSD) and /opt/local (Mac OSX) + update yacc.key for current byacc keywords. + modify yaccfilt.l to handle escaped newlines in quoted strings. + build-fix for xvile without multibyte support. + add error patterns for bison and byacc. + correct workaround in manfilt.c for bullet characters from 9.8g; they were lost when using UTF-8 encoding. + improve tcl-filt.l handling of single character between curly braces, showing that as string-attribute. + modify tcl-filt.l to handle square brackets quoted by curly braces (report by Wayne Cuddy). 20141002 (o) > Tom Dickey: + fix some leaks, etc., reported by valgrind and Coverity. + correct filtername setting for issmode, which used ini-filter. + add ":" and "#" to ini-filter as aliases for "=" and ";" + add desktop-mode, using ini-filter. + revise ldel_chars() function to restore feature of backspacelimit to delete newlines while backspacing. This was lost in 9.5s changes (Savannah #43291). + add case to CF_XOPEN_SOURCE for Unixware, from lynx. + modify configure script to define _NETBSD_SOURCE for Minix, because its header files put the POSIX.1-2001 prototypes, such as isblank, there. + add vile-to-html, vile-libdir-path to uninstall rule + modify configure script to supply default "-o" option for the install program, since MINIX's does not provide a useful default. + other tweaks to work around deficiencies in Ash's parser, e.g., not counting tokens until after dequoting. + modify configure script to avoid using "expr", fixing problem using this with MINIX3.2, which uses Ash - a shell which omits the "<", "<=", etc., comparison operators which POSIX specifies for "expr". + CF_ADD_LIBS workaround in CF_X_TOOLKIT uses pkgconfig, whose files generally are using incomplete dependencies - in turn introducing lots of duplication. filter out the duplicates. + CF_CURSES_FUNCS improve workaround for weak-linkage, seems to fix tests with NetBSD 6.1 + CF_X_ATHENA add --with-Xaw3dxft option + CF_X_TOOLKIT add workaround for breakage in XQuartz upgrades + update config.sub 20140706 (n) > Brendan O'Dea: + use INT2PTR and PTR2IV macros rather than an explicit cast in perl.xs and ptypemap. > Tom Dickey: + improve description of search-list for syntax filter keywords in vile.hlp; add links/anchors to improve navigation in vile-hlp.html, config.html and macros.html + modify error-pattern to work with the GNU make 4.0 change to quotes + modify makemode mode-filename pattern to match BSDMakefile and GNUMakefile + add vile-to-html, vile-libdir-path + modify manfilt.c to recognize aixterm-style SGR 90-97 as colors 8-15. + correct off-by-one count in decoding "meta" markup from 9.8l changes which did not work with external filters. + add note in config.doc recommending ncursesw for screen option over curses/ncurses, for UTF-8 support. + modify DisableHook/EnableHook to let their return-value be usable as the latch condition. + if configure check for gcc -rdynamic option fails, fallback to the built-in filter configuration. + suppress -rdynamic option-check for clang, because its error reporting is unreliable. + correct logic in nextbuffer() when autobuffer mode is unset. Similar fix for prevbuffer() (report by Hymie on mailing list). + modify test for stuttering in vile_op(), to check if a count precedes the final letter in a command. With this change, ^All stutters as before, making the command in terms of lines. However ^Al5l will act on the next 5 characters. Note that ^Al1l will act on a single character (Savannah #42147). + fix a double-free in bclear(), when the buffer is marked noundoable (report by Paul Fox). + update config.guess, config.sub 20140330 (m) > Kevin Buettner: + add missing "break" in DATA() macro in x11.c from 9.8j changes. > Tom Dickey: + fix configure check if curses.h is needed, by suppressing external reference to vl_strncpy. + build-fix for --disable-extensions by providing dummy set_tagsmode() + modify [ShowFormatted] to also handle logmode the same as typescript files + modify makefile.wnt to show version-details in wvwrap.exe + minor fix to make-hlp.pl, to complete underlining of project hierarchy section of vile.hlp + clarify in vile.hlp how to suppress "press any key to continue" message in winvile when running external shell-commands. + build-fix when configuring --with-external-filters when only flex 2.5.35 / 2.5.37 is available (report by Kevin Buettner). + fix crash in winvile in "select-all" command (Savannah #41943). + update gnreight.h from Debian/testing libc6 2.17-97 + update xvile.desktop with improvements from Fedora package. 20140131 (l) > Derek Woolverton: + add new keywords for C++11 > Rick Sladkey: + change initialization in ntconio.c to improve use with ConEmu, e.g., when the window is resized. > Tom Dickey: + add version details to win32 executables. + improve rpm spec-file filter: + add checks for "%" markers in unexpected places, e.g., in comments. + change %package to not begin quoted text; it should be a one-liner + modify ^X-n to filter typescript files like vile-pager. + fill in pod descriptions for undocumented perl modules. + additional change for Savannah #37988 to update screen when removing a newline which was inserted initially by the "o" command. + modify mode-pathname for makemode to work with arbitrary level of directory; it assumed something like "/usr/lib/pkgconfig". + minor fix to tcap.c to restore colors after completing a loop which turns off attributes. The directory.pm script caused the driver to reset reverse-video and bold, but the driver was restoring colors only after the first reset. + minor fixes for perl modules: + correct off-by-one position of highlighting for spell.pm + modify spell.pm to remember the last replacement made for a given word and offer that as the first choice on followup changes. + modify dirlist.pm to reposition the window on completion so that the last lines written to the buffer will always be visible. + modify hgrep.pm to set $search so that for instance, visual-matches works. + modify perl modules to use strict feature. + add ".pp" to pasmode / Pascal and ".shtml" to htmlmode (suggested by Radek Liboska). + add requires/provides for Perl modules in vile.spec (suggested by Radek Liboska). + correct a sign-extension bug in column_sizes(), which caused incorrect cursor-movement for some 8-bit encodings (report by Radek Liboska). + add still more keywords for C++11 + fix for 9.8j change to manfilt.c; reset the overstrike link to null in erase_cell(), to avoid freeing memory twice. + modify internal links of html documentation to fix linklint warnings + fix most issues reported by rpmlint for package/vile.spec: + add configure option "--disable-stripping" + strip executables during install by adding "-s" normally + make the wmconfig files non-executable + update FSF address in several files + modify -F option to ensure that output uses \n consistently for the line-separator verus \r\n. + minor fix to sh-filt.l's stripping of leading blanks in a here- document. + updated ftp-mirror to http://invisible-mirror.net/archives/vile + add a new attribute markup, "M" for "meta" which is ignored by vile. Modified filters to emit their command-line using this markup so that applications can determine which filter was invoked when the -F option is used to provided marked-up files. + build-fixes to allow "new" flex 2.5.35 to be used to build the various filter configurations, noting that the recommended tool is still "reflex" (report by Joran Ahlback). + add convile.nsi and minvile.nsi scripts to use for creating installers from convile and minvile via cross-compiling. NSIS is far less capable than Inno Setup, so the latter still gives the recommended packages. + move ignoresuffix setting from cmode to global settings, i.e., to use for other filetypes. + modify tags logic to set "tagsmode" if it is defined, and assuming that, to test the local check-modtime value, i.e., that managed via the majormode to allow tags files to be selectively reloaded when their content changes (discussion with Wayne Cuddy). + modify sh-filt.l to recognize ksh93/bash here-strings, noting that they are not standardized. + review/improve tcl syntax highlighter (report by Wayne Cuddy): + do not treat single-quote specially + allow newlines in double-quotes + recognize square brackets in double-quotes to denote nested commands. + fix ambiguity between "-option" and "-number". + show sprintf-codes with string color. + highlight "#" prefixing hexadecimal digits as a number. + do not color args for unknown verbs. + update keywords to tcl/tk 8.6.0 + add ".nsh" suffix to nsis mode. + fix for "-F" option when filtered file has no syntax highlighting; the MK variable was not set, causing getregion() to fail. + update config.guess, config.sub 20130707 (k) > Brendan O'Dea: + correct a couple of places in api.c which used characters rather than bytes, which made :%perldo s/^/X/ do the wrong thing for UTF-8 encoding. + change perl.xs to use bullets in a few cases to work with newer Perl's POD parser. Also add a "back" tag (Debian #708027). + improve configure script for perl by locating xsubpp by the same process as the module is loaded, e.g., using @INC (prompted by discussion of Gentoo #380741). > Tom Dickey: + add "®ex-escape" function to allow a literal string to be assigned to "$search" without confusion (discussion with Wayne Cuddy). + add ".tmac" suffix to nrmode + modify ins_anytime() to request a screen update on completion so that temporary changes to the screen such as empty lines for the "o" command will be undone if needed (Savannah #37988). + add powershell mode + convert non-generated html documentation to HTML4-strict; change font-coloring to use css. + amend change for Savannah #37806 to exclude buffers where the file encoding is 8bit, fixing a mispositioning of the cursor, e.g., for ISO-8859-2 encoding (report by Radek Liboska). + add json mode 20130414 (j) > Brendan O'Dea: + correct warnings from pod2text > Tom Dickey: + add configure options --enable-freetype and --enable-fontsets, to support proposed refactoring of x11.c + modify manfilt.c to interpret ANSI erase-line, insert/delete character and inline cursor-movement controls. + modify manfilt.c to improve parsing of SGR sequences, allowing for expansion to simple cursor movement as would be used in line-editing for bash and tcsh (prompted by discussion with Joel Winteregg). + improve/fix ruby syntax highlighter: + add missing logic needed to make binary numbers parse + track curly-brace level in var_embedded(). + improve parsing/highlighting of %r{pattern} + handle special token :` + stop highlighting after __END__ + interpret extended mode for regular expressions, showing comments in different color. + corrected logic for here-document delimiter when it happens to be a quoted string. + recognize ruby 1.8's ?a syntax for ASCII character. + accept floating point constant without decimal point. + handle CR/LF endings for lines with here-document tags. + improve parsing of embedded expressions in strings, e.g., "#{1+2}". + improve parsing of extended-quoting, e.g., %|foo| + add ruby.key as alias for rb.key, to simplify use of the filter as a standalone program. + add mode for special case of embedded-ruby used in Rails, call that "erb" mode, activated by the "-e" option of the filter. + apply consistent stylesheet and website links to html documentation. + add commands to show bound commands ordered by the key to which they are bound: describe-all-keys, describe-all-cmdmode-keys, describe-all-insmode-keys, describe-all-selmode-keys (prompted by discussion with Chris Green). + modify htmlfilt.l to highlight embedded php, improve its parsing of embedded css. + modify definition of istype() to ensure that it returns true only if the character parameter is actually in the range 0..255 (Savannah #38342). + amend change made to alt-tabpos in 9.7u for multibyte characters to make tab and other control characters work as they did before (Savannah #37806). + fixes for issues reported by Coverity: + modify ctype-tables to allow for -1 as a character value, since that may be used in CharAtDot(). + use setjmp/longjmp for recovering from fatal errors in lexers. + undo change to wrap-word from 5.6t, allowing a parameter which is interpreted as a number of spaces to append after the cursor when the line is split. + various minor resource leaks. + start refactoring x11.c, making the current text-drawer x11plain.c + merge/adapt Brendan's current scripts to add perl documentation to the vile-common Debian package for test-builds. This also makes the ".xpm" file consistent with the desktop icons. + add "divert" to m4 preamble to work with sendmail's ".mc" files. + use shape-mask and correct visual depth for window-decoration icon in xvile. + the "-i" option is available in most filters now. Ignore it when checking for unknown options in the wrapper for external filters (report by Wayne Cuddy). + updates for configure script macros: + add 3rd parameter to AC_DEFINE's to allow autoheader to run + remove unused macros + update config.guess, config.sub 20120923 (i) > Tom Dickey: + fix build for minvile, whose icon path was broken in 9.8h + amend fix for Savannah #36801 to make a special case for the calls via "execute-named-command" which limits the quoting to search commands and shell-commands by testing the first character of the command-line (report by Wayne Cuddy). + update configure script to support --datarootdir option. + improve dependencies for rpm package by adding extra patterns for vile's mime.pl and plugins.pl scripts. + improve ToggleMode macro, making it set the local value as ToggleList does (report by Wayne Cuddy). 20120807 (h) > Tom Dickey: + document icon options in config.doc NOTE: the meaning of the --with-icondir option changes with this version; --with-pixmapdir replaces that usage, while --with-icondir is used to support icon themes. + update vile.mini.xpm to add 32x32 and 48x48 sizes. + add configure --with-icon-name option. + add iconName resource, which can override the compiled-in pixmap. + revise xvile configure options with improved versions from xterm. + add .png and .svg icons, for use in icon-themes. + add fences to rpmmode. + restore highlighting of xpmmode, lost in 9.8g changes. + modify vile.spec to conditionally incorporate the perl features. NOTE: this omits dict.pm due to limitations of the rpm program. + improve pattern used for regular expressions in awk-filt.l + improve check in c-filt.c for quoted strings to ensure that a backslash is given for continuation-lines. + modify ecrypt.c to reset seed/salt before each file, so that a set of files can be decrypted with a wildcard. + improved lex-filt.l: + do not treat a line consisting only of whitespace as indented-code. + amend CODE1 state to handle indented comments between patterns. + modify initialization of [vileinit] to quote parameters passed from the command-line, e.g., for the "-s" option so that embedded blanks are retained (report by Greg McFarlane, Savannah #36801). + modify hist_show() to return correct index for "#" buffer when autobuffer mode is turned off (Savannah #36739). + correct logic in special_formatter() for L_CURL case so that expressions such as setv $modeline-format "%{&cat 'ignorecase is ' $ignorecase}" work (patch by Adam Denton, Savannah #35288). + corrected highlighting of continuation-lines for double-quoted strings in awk, tcl filters (prompted by report by Wayne Cuddy). + reduce sh.key to POSIX shell keywords and utilities. + add zshmode and bashmode, for consistency. + add kshmode, to address slight syntax differences between Korn (ksh93) and Bourne shell scripts. + add new command "derive-majormode", which is used to make a new mode initially copying another mode's settings. + improved sh-filt.l: + "<<<" short-form here-document. + add "-K" option to support Korn shell's "vnames", which allows one to define a variable containing "." if there already exists a variable consisting of the part before the ".". + exclude backtic from a pattern in here-documents, which prevented embedded backtic's from being recognized. + extend the list of operators for brace substitution. + use autoconf 2.52.20120310, to work around Intel 12.x compiler. + add configure check for clang, to improve compiler warnings. + build-fix for HP-UX 10.20 lex, which prototyped main() without params 20120309 (g) > Tom Dickey: + relax conditions for displaying saved message just before starting full screen mode, to allow the default help-summary to show (report by Paul Fox). + modify logic for [vileinit] and [vileopts] buffers which are used during startup, to first close their window if possible, eliminating a message that interfered with other startup messages (report by Paul Fox). + improve insert-exec mode by filtering out characters which have special meaning in insert-mode. + add ToggleMode macro (prompted by question by Wayne). + add complete.rc GetCompletion macro as an example of how to do insert-completion. + add "show-user-variables" command. + implement "describe-$variables" command. + add alias "describe-user-functions" for "describe-&functions" + add alias "describe-state-variables" for "describe-$variables" + add variables $get-at-dot, $get-it-all, $get-length and $get-offset to simplify scripting of &get-completion and similar features. + modify vilefilt.l to highlight functions using "-" character. + add aliases &get-key, &get-motion, &get-sequence as more readable names for >key, >motion and >sequence. + add &get-completion function to support macros that can handle name-completion in insert mode (prompted by mailing list discussion). + reset video-attributes for linebreak when computing the left/right scrolling offset, fixing a case from 9.8f which left stray highlights + updated nsis.key + modify conffilt.l to match leading keywords that may begin with a leading punctuation mark, other than the existing comment markers or brackets. + modify nsis mode to ignore case of keywords. + add -i option to most syntax filters to control whether keyword matching is done ignoring case. The exceptions are html, imake and make, which use special logic for deciding which to use. NOTE: this is an incompatible change which can affect user-defined majormodes that use the affected filters. However, presetting the -i option on about a third of the syntax filters would be more confusing than making this explicit in filters.rc + modify configure script to support cross-compiling, tested with cross-compiler to mingw using convile and minvile targets. + add null-pointer checks for "nohl" fix in 9.8f, needed for the case when no majormode is in effect. + modify vile-manfilt to accept 0xb7 bullet character used in some manpages. + updates for configure macros CF_NCURSES_CONFIG, CF_XOPEN_SOURCE 20111127 (f) > Tom Dickey: + trim unneeded loader flags added in Mandriva 2010.2's rpmbuild, since those prevent the loadable filters from linking. + modify symlinking of manpages in vile.spec to avoid using absolute links, since those may be removed in rpmbuild. + change makefile.wnt to add WIDE knob to define UNICODE, and also for the OLE configuration to use comsuppw.lib rather than comsupp.lib + drop -G4 option from makefile.wnt, which was an optimization to favor 486 processors phased out in Visual C++ 5.0, and with 9.0 produces a warning. + change return type of TERM.setpal from void to int, since the return value is used with the win32 platform. + modify special case for "dos" setting in a submode introduced in 8.3q, recognizing "nodos" also. This allows overriding a submode that is previously defined, e.g., in modes.rc, by a user's .vilerc (report by Wayne). + correct "nohl" when used in a submode. As a side-effect, vile frees video attributes for the buffers, but in this special case it did not limit the freeing to buffers using the majormode whose highlight submode was turned off (report by Wayne). + add force-empty-lines operator. + add delete-empty-lines operator (request by Wayne). + change tabstop within [Printable Chars] to keep the result within 80 columns. + improved rpm syntax highlighter: + modify number pattern to add dots and dashes for version numbers. + match keywords in more places by checking for the name in %name and %{name} patterns when the first match fails. + add keywords %exclude, %makeinstall and %run_ldconfig + add vile-pager to dpkg package script for vile. + add ".pod" files to perlmode. + change default in basic.key to Keyword for consistency. + modify xresfilt.l to check for continuation-lines of comments. + add "YI" capability to tc.key, per ncurses fix. + add extra-colors settings for linenumber and linebreak, as well as the normal "<" and ">" markers. + modify makemode to use tabinsert, allowing notabinsert to be a default in other mode (patch by Anthony Shipman). + add erlang syntax highlighter and majormode (patch by Anthony Shipman). + add linebreak mode, like vim (request by Paul Van Tilburg). This does NOT yet work with color highlighting, but does work with wide-characters. + fill in a missing chunk of logic for wrapping double-width characters (report by Sukegawa Shigeyuki). + modify debian/rules to work around a quoting problem in Brendan O'Dea's build environment. + fix a typo in help-file description of modeline (report by Wayne). + adapt/use multi-package feature of Fedora rpm script. + modify dpkg and rpm scripts to install lxvile. + add build-dependency for dpkg test-script against libperl-dev + several configure macro updates, from lynx/ncurses/tctest/xterm: + CF_ANSI_CC_CHECK - do a sanity check on $CC; occasional users add options directly to it rather than follow the standards by setting $CFLAGS and/or $CPPFLAGS. + CF_CURSES_CPPFLAGS - make checks for special libraries on hpux10 and sunos4 optional + CF_CURSES_FUNCS - workaround for bug in gcc 4.2.1 (FreeBSD 8.1) which caused part of test program to be omitted, i.e., when it saw two return-statements in a row it omitted the _first_ one. Also add expression to pointer check to help FreeBSD's linker decide it should be validated. Just an assignment was not enough. + CF_CURSES_LIBS - add check for NetBSD's otermcap + CF_CURSES_HEADER - change order for curses.h / ncurses.h pairs to put ncurses.h first, which will tend to provide the same #define's as in CF_NCURSES_HEADER (report by Dennis Preiser). + CF_CURSES_LIBS - make checks for special libraries on hpux10 and sunos4 optional + CF_CURSES_TERM_H - modify to avoid spurious check for if there is no ncurses version. Look for ncurses's term.h anyway, to work around breakage by packagers who separate ncurses' header files. + CF_DISABLE_RPATH_HACK - fix garbled message + CF_LD_RPATH_OPT - add cases for DragonFlyBSD and MirBSD + CF_MAKEFLAGS - filter out GNU make's entering/leaving messages. This only appeared when using the macro in a dpkg script, though it should have in other cases. + CF_PKG_CONFIG - modify to allow autoconf-2.13 or autoconf-2.52 configurations. + CF_RPATH_HACK - add a check for libraries not found, e.g., from suppressed functionality of gcc in linking from /usr/local/lib, and add a -L option to help work around this. + CF_STRUCT_TERMIOS - relax ncurses-oriented change to make this work as fixup after CF_XOPEN_SOURCE + CF_TERMCAP_LIBS - modify the workaround for old AIX system (e.g., from 1997 or before) to not set $cf_cv_termlib if it succeeds in finding initscr in libcurses. Doing that confused a check in tin's configure.in which looks at that variable to decide if termcap/terminfo library was found. The check for tgoto in libtermcap on the next line is the actual check which is needed, and should fail if there is no termcap library installed. + CF_XOPEN_CURSES - fix typo in the workaround for _XOPEN_SOURCE_EXTENDED + CF_XOPEN_SOURCE - extend aix case to aix 7.x, modify checks to prefer _XOPEN_SOURCE vs _XOPEN_SOURCE_EXTENDED. + CF_X_ATHENA_LIBS - DragonFlyBSD's pkgsrc combines Xaw6 and Xaw7 into a single package, and doesn't provide a plain "libXaw.so" symlink. Work around by testing for the 6/7 versions. + restore delphi keyword file. + amend change from 9.7w to install rule for vileget, making it use the normal INSTALL_SCRIPT symbol. Some platforms' "strip" utility do not error if the file happens to be a shell script. + amend build-fix for cygwin to fix winvile OLE. 20110411 (e) > Tom Dickey: + improve ada syntax highlighter by parsing attributes, adding a list of the predefined attributes to its keyword file. + fix character-type initialization to allow built-in locales in 9.7d to work (report by Ramil Farkhshatov). + amend a change from 9.7zd which lost the repeat-count for single-byte characters in "r" and other uses of lins_chars() (report by Hymie on mailing list). + build-fixes for --disable-extensions + add tables, modify functions, to support name-completion for the ":g" global commands. Previously, name-completion used the entire table, which is about 7 times longer. + add "describe-globals" command. + add the "pp" operator to documentation of :g in help-file (report by Wayne on mailing list) + change backup-style from universal to buffer-mode (request by Wayne on mailing list). + add a check in bytes_at0() to ensure that the offset is positive. + modify logic used when cursor-tokens is set, to extract the token from the screen. It was only searching for the first token which began on or after the current position. Now it searches for tokens which may begin before the current position (report by Ian Watson). + build-fix for xvile with cygwin, broken in 9.8a changes to consolidate w32vile.h includes. 20101228 (d) > Tom Dickey: + modify expression used for "path" type in regexp.c to avoid matching non-ASCII punctuation characters. + merge changes from Debian package script for 9.8c + add preamble patterns for Emacs "text" and "Autotest" modes. + minor improvements to performance by inlining as macros some frequently used functions. + apply the same improvement for line-deletion to these functions: attributereqion(), find_release_attr(), update_window_attrs(). + improve performance of line-deletion by eliminating a search for region-pointer, using data already collected (report by Gary Jennejohn). + modify CAPNAME expression in tc-filt.l to accept "#2", etc. + extend generate set of single-byte encodings to include those listed by iconv for which there is no predefined locale, e.g., the Windows codepages. + modify several places which check for special characters, e.g., when parsing repeat-counts in normal mode, to also exclude multibyte characters (report by Ramil Farkhshatov). + use the generated single-byte encodings from 9.8c to improve UTF-8 support for platforms without iconv, i.e., by relating the narrow and wide encodings. + add $kbd-encoding variable, to control whether the keyboard uses the same encoding as the display and/or locale. 20101206 (c) > Rick Sladkey + add Unicode support to the vile Win32 console driver. > Tom Dickey: + add generated set of single-byte encodings, to replace the ASCII and ISO-8859-1 fallbacks used when no suitable 8-bit "narrow" locale can be setup. The tables also have the corresponding set of locale names, which provides a fallback for cases when the locale support is incomplete (prompted by report by Ramil Farkhshatov). + modify CF_WITH_CURSES_DIR and related macros so the --with-curses-dir option applies to both ncurses and curses. + modify CF_X_ATHENA and CF_X_TOOLKIT autoconf macros to accommodate changes in xorg package scripts. + modify several autoconf macros to lessen use of legacy "${name-value}" feature in favor of standard "${name:-value}", since it is broken in recent version of bash. + remove a spurious '\' in backreference for sed in CF_LEX_VERSION macro (report by Mark McKinstry) + add ".yy" suffix to yaccmode. + add ".gperf" and ".ll" suffixes to lexmode. + ncu-indent is now provided by "cindent" at http://invisible-island.net/cindent/ + set pointsize in output from atr2html. + use cindent to format the ".c"-files. + use cindent to format the lex-files. + correct description of "copy-to-clipboard" in cmdtbl. + update config.guess, config.sub 20100915 (b) > Tom Dickey: + correct a check in the combination of showchar mode with the :show-printable command when the global file-encoding mode is set to locale. Also make this combination apply whether or not the ruler mode is set. + correct setting of reg_utf8flag when the global file-encoding mode is set to locale, e.g., for UTF-8 encoding. + add "%" to syntax highlighting of makefile target patterns. + add configure --enable-link-prefix, which is used to trim unneeded libraries from link-commands, to reduce package dependencies. + build-fix for Ubuntu package, which must ensure that -lcrypt is added when building vile-crypt due to weak-linkage issues. 20100908 (a) > Tom Dickey: + modify configure check for gcc's -r dynamic option to include the message from QNX's gcc 2.95.2, which simply ignores the "dynamic". + modify RPM spec-file to remove the doc-directories' scripts at build time, since rpmbuild 4.4.2.3 on Centos 5.5 automatically adds unwanted dependencies on the Perl scripts found there as part of the package's requirements for installing. + fix many strict gcc compiler warnings. + remove support for OpenLook. + add configure --enable-colored-menus option (discussion with Chris Green). + modify makefiles for winvile so that it supports unix-style encryption. + modify vile-crypt to accept a "-u" option for unix-style encryption. + add Jochen Obalek's unix-style crypt function for platforms without that, e.g., win32 and OS/2. + modify perl.xs to build/work with perl 5.004 (cf: 9.7e). + add configure workaround for perl 5.004's prototype for main(). + drop two symbols from embedded-Perl configure check, since they did not appear in 5.004, and are not used by perl.xs + build-fix for OS/2 EMX: + remove a '/' after $(DESTDIR), to work with DOS devices. + suppress unsupported "inline" definition for icc compiler. + build/runtime fixes for DJGPP: + provide fallback for intptr_t type. + amend a change from 9.7h which assigned a non-malloc'd pointer to context where it was later freed. Changes for vile 9.8 (released Sun Aug 08 2010) 20100808 > Tom Dickey: + mark 9.8 release + move rpm spec-file to package directory. 20100725 (zg) > Tom Dickey: + correct scripting for map/map! commands to allow ^V to escape any character, as well as ignoring single/double quotes and backslashes (report by Larry Gensch). 20100713 (zf) > Rick Sladkey: + add support for C# verbatim string literals to c-filter.c + correct a sign-extension problem with xml-filt.l, for 64-bit platforms > Tom Dickey: + add Debian build-scripts, for test-builds. + improve awk filter: + correct DSTRING expression, to handle "\\\\" value. + accept literal spaces in patterns. + improve rpm filter: + recognize keywords ending with digits, such as "Source0". + distinguish one-liner tags from multi-line sections. + ignore case of keywords. + add keywords for %XXX variants of %{XXX} names. + highlight %XXX words in single-quotes. + improve sh filter: + handle escape character in here-document. + several changes to configure macros: + quote params of ifelse(). + add/use CF_ADD_LIB/CF_ADD_LIBS for consistency. + add --verbose messages to a few macros. + use CF_TRY_PKG_CONFIG in CF_X_ATHENA, for extra checks, etc. + modify CF_X_TOOLKIT, adding check to ensure that -lICE is added, to work around broken ".pc" files. 20100612 (ze) > Tom Dickey: + add lxvile wrapper for xvile, which chooses a font based on locale setting (suggested by Radek Liboska): + add ".gpr" files to adamode + add ".xmodmap" files to xresmode + add ".la" files to confmode + add "changelog" to txtmode + update yacc.key to bison 2.4.1 and byacc 20100610. + improve configure macros: + improve CF_RPATH_HACK by using ldd to obtain a list of directories to ignore. + use pkg-config for X libraries, if available. + correct a test of cache variable in CF_MKSTEMP + modify CF_GCC_WARNINGS to work with c89 wrapper for gcc. + ignore stderr in CF_GCC_VERSION + add/use CF_ADD_LIB and CF_ADD_LIBS macros to force consistency in updating the $LIBS variable. + add assignments in CF_FIND_LINKAGE to address a case where the function is found in predefined libraries. + add quoting for ifelse() parameters + build-fixes for configure --without-locale (report by Michael Finken). 20100520 (zd) > Brendan O'Dea: + add configure option --disable-rpath-hack, since Debian guidelines do not allow rpath. > Tom Dickey: + two fixes for handling compose sequences with UTF-8 encoding (report by Radek Liboska): + restore the wide-character locale setting while opening the input method. + check in x_key_press() for resolved strings that can be interpreted as UTF-8 encoding. + add CFLAGS to link-commands in makefile.in, so that --with-cflags=-g works with linkers that require this. + implement stacked here-documents in ruby syntax highlighter. + several fixes for redefining a built-in command via a procedure. + add a parameter to delete_namebst() to suppress reinsertion of the data when we know we're redefining an entry. This fixes a bug where reinserting silently failed to update the flags, e.g., when overloading a built-in name. + btree_delete() did not walk back through the correct set of nodes for rebalancing the AVL tree. Fix, using Julienne Walker's tutorial as a guide. + fix warnings from "clang --analyze". + remove a check that prevented inserting non-UTF-8/non-Latin1 8bit codes. + correct setting of reg_utf8flag in regexp.c; the error was preventing matches of non-ASCII text in Latin-1 encoding. + add $cmd-encoding variable to allow control of minibuffer's encoding + disable rpath in rpm spec-file. 20100405 (zc) > Rick Sladkey: + add missing "close" for terminal for win32 console version. Lacking the close, vile could hang if it was run from a subshell. + do not check X_OK in ffaccess() for win32. > Tom Dickey: + add configure check for exctags vs ctags, to work with pkgsrc. + use Xutf8LookupString for input of UTF-8 key-events, if available. + add configure check for rpath linkage options, use this for libraries in unusual places. + improve CF_FIND_LINKAGE configure macro, avoid adding to CPPFLAGS and LDFLAGS if the check only needs to add a library name. + improve configure check for gcc -rdynamic option. + incorporate "reflex" into AC_PROG_LEX check for working version of flex. + change resource file's forkOnStartup to false, matching compiled-in default (discussion on mailing list). + add "Application" to desktop files. + improve .spec file, to install uxvile as well as configure xvile using Xaw to obtain menu support. + remove mkdirs.sh; use mkdir -p + minor cleanup of .spec file, change the terminal configuration to use the default termcap/terminfo driver rather than ncursesw (discussion with Radek Liboska). + fix makefile.in so that rpm build works; the changes for the --with-symlink configure option had broken the way the TARGET symbol was used by the .spec file. + add configure check for va_copy, which may not be a macro. + change type in vl_setup_encrypt() to "int", to make this 32-bits for 32- and 64-bit platforms, needed to make the algorithm work with 64-bits. The original "long" was needed for 16-bit systems. + when processing modelines, ensure that settings for a source'd file are not applied to the current file. + modify xvile to use \uXXXX format when the font does not contain a glyph for a given character. + change "install-xvile" makefile target to "install-bin" in RPM spec-file to work with UTF-8 (report by Radek Liboska). + add/revise sections in config.html / config.doc summarizing the differences between related text- and X11-drivers and their support of UTF-8 (report by Radek Liboska). + change "ncurses" to "ncursesw" in RPM spec-file to work with UTF-8 (report by Radek Liboska). + correct order of ifdef/include's for USE_MULTIBYTE symbol in curses.c, which broke wide-character support for curses-driver in 9.7zb (report by Radek Liboska). + add preamble to makemode to work with lines such as #!/usr/bin/make -f + add environment variable VILE_LOCALE_MAPPING to help with special cases of associating wide/narrow locales, e.g., where the narrow locale is only available under a non-empty suffix. + improve reverse-index used for associating wide/narrow encoding. + add mode "reuse-position" to allow users to specify that vile should restore the current line/column position when (re)displaying a scratch buffer built with liststuff. The motivation is to allow switching between the displays for show-printable and show-wide-printable, which use the same buffer. + add show-wide-printable command, to provide a way to see details for other "pages" than the ASCII/Latin-1 0-255 code. + reopen terminal in CleanAfterPipe() so that multibyte-output still works after reading into a buffer from a shell command. + make kill_response() work with wide-characters (report by Ramil Farkhshatov). + revert a change in word.c from 9.7zb which broke wide-character use of format-til (report by Ramil Farkhshatov). 20100211 (zb) > Tom Dickey: + modify curses driver to support color-schemes. + modify vl_ctype2tbuff() to handle wide-characters. + add $title-encoding, to control whether vile 8-bit or UTF-8 encoding when setting xterm title. + improve special_formatter(), used in modeline formatting, to display UTF-8 filenames. + make ifdef'ing of gettimeofday() in random.c consistent with estruct.h (report by Chris Green). + in UTF-8 locales, limit buffer names to ASCII, to simplify name management in wide/narrow encodings. + modify regexp.c to handle wide-characters for \< and \> markers. + change makefile.in to use "install-bin" rule rather than "install-vile" or "install-xvile", according to the target, since that interferes with building both versions before installing (report by Radek Liboska). + extend :show-printable to show detail for the character in the current buffer if showchar mode is set. + modify lins_chars() so that pasting UTF-8 text into a non-UTF-8 buffer automatically converts it into the non-UTF-8 locale. This is not the same as other methods such as yank/put, which copy bytes. + remove iconv() logic in vl_mb_getch() which does not work for non-UTF-8/non-ISO-8859-1 encodings (report by Radek Liboska). + correct return-value for vl_mb_is_8bit(), to correctly display non-UTF-8/non-ISO-8859-1 codes (report by Radek Liboska). + modify :show-printable to show results from system locale settings if a parameter is given. + minor formatting fix to output of :show-printable to show the "sh" on the end of each row. + modify vtputc() to correctly display non-UTF-8/non-ISO-8859-1 codes when running in a UTF-8 locale (prompted by report by Radek Liboska). + add $latin1-expr variable, which can be used to specify whether a derived narrow locale really has Latin1 (ISO-8859-1) encoding. This is used to provide a default encoding for the case where the user's locale uses UTF-8 encoding, and the system has no corresponding narrow locale installed (report by Chris Green). 20100128 (za) > Tom Dickey: + improve nroff filter by allowing for macro-names to be used for fonts + add "always" setting for check-access mode, to distinguish between scripts and datafiles, e.g., tags. Use "always" to check permissions for data. + add to diffmode's preamble pattern to allow it to detect diff's in a piped input. + add configure option --with-symlink which augments --program-suffix to make it simple(r) to install versioned binaries (request by Steven Lembark). + add configure options for transforming program name upon install: --program-prefix, --program-suffix, --program-transform-name + updates/fixes to ".spec" file (report/patch by Radek Liboska). + improve configure-check for term.h header, to eliminate compiler warnings for cygwin. + improve CF_IMAKE_CFLAGS and CF_XOPEN_SOURCE by using CF_ADD_CFLAGS to add (and remove duplicates) consistently in CPPFLAGS. 20100107 (z) > Tom Dickey: + modify format for CF_DISABLE_ECHO, from mawk. + add special case for darwin extensions in CF_XOPEN_SOURCE macro, from tin. + add makefile install-html rule + add doc/vile-man.html, generated from vile.1 + add check in x11.c get_color_gc in case index falls out of bounds (report by Gary Jennejohn). + finish colorizing examples in html files. + completed doc/menus.html + cleanup some debris from working files (report by Brendan O'Dea). + update config.guess, config.sub 20091228 (y) > Brendan O'Dea: + modify ".desktop" files to use freedesktop category names as in http://standards.freedesktop.org/menu-spec/1.0/apa.html + briefly describe uxvile in the manpage. + modify configure check for lex/flex to ensure it does not use ":", if the program is not found since that would cause an unexpected build-failure. > Tom Dickey: + change Inno Setup script to install html files rather than doc files for documentation; added a shortcut to the table of contents. + convert all ".doc" files to html, generate ".doc" from those files. + improve xterm-fkeys implementation: + check for existence of shifted cursor- and editing-keys when the unshifted keys do not use CSI format. + recognize either form of CSI + modify xresmode to include shell-output from appres, e.g., ^X!appres XTerm + improve vile-sh-filt for these cases: + "${number}" + "$(commands)" + "$((expression))" + "${name#value}", etc. + make $font always available, but readonly for non-GUI configurations. + use -F option to highlight the code-examples in vile's help-file. + add -F command-line option, to only run the syntax filters for the given files, writing the attributed text to the standard output. + modify vl_ctype_init() to save/restore LC_CTYPE setting, in case some library, such as vile's perl binding, has reset the locale based on environment settings, etc. + add built sources/headers to makefile tags-rule. + improve configuration/initialization of curses-driver to ensure that no attempt is made to display UTF-8 using 8-bit curses (report by Chris Green). 20091114 (x) > Tom Dickey: + add a special case in canonpath(), and add SYS_CYGWIN to OPT_UNC_PATH definition so that UNC-paths are recognized with Cygwin. + add doc/vile-toc.html, a table of contents for vile-hlp.html + generate vile.hlp from doc/vile-hlp.html + correct check for flags on sql keywords from 9.7b, which was using the class definition rather than the instance. + use xterm patch #251 feature for saving/restoring title in termcap and curses drivers. + add doc/vile-hlp.html, which is a marked-up version of vile.hlp + change atr2html to not use
, since  inside 
 is
	  nonstandard.
	+ add logic for case in vtlistc() when vtcol is negative because the
	  screen is shifted-right, but the text is nonprinting or
	  wide-characters.  vtcol was not updated, and the region should be
	  filled with blanks.
	+ minor fixes/improvements to ldel_bytes(), based on reports of an
	  infinite loop for amd64 platforms (reports by Gary Jennejohn, Joran
	  Ahlback, Ramil Farkhshatov, Clem Taylor, Joachim Schimpf)
	+ strict compiler-warning fixes.

 20091027 (w)
	> Tom Dickey:
	+ fix makefile substitution so AIX make program does not attempt to
	  use desktop-utils when it is not available.
	+ add configure check to suppress IRIX64 compiler warning about the
	  conversion of pointers to same-sized integers, which is used in
	  vile's mode structure definitions.
	+ prefer include of inttypes.h, since stdint.h is c99, and on some
	  platforms such as IRIX64, including it generates an error.
	+ implement Unicode select/paste in winvile.
	+ build-fix in mktbls.c for Visual Studio.Net 2003, apparent compiler
	  bug.
	+ add detailed example of extra-colors to vile.hlp
	+ change spaces-after-sentence to a buffer mode, to allow it to be part
	  of a majormode.
	+ correct logic in filter's parse_keyword() function, which could
	  index past string limits when handling quotes.  This is an old
	  bug exposed by gcc warnings fixes in 9.7v
	+ modify default values for --with-app-defaults and --with-icondir to
	  use the make-specific $(name) form rather than the sh/make compatible
	  ${name} form, since the shell construct used for filling in the
	  default value by autoconf does not work with some shells, e.g.,
	  Tru64, which may be confused by nested curly-braces in that
	  expression.
	+ correct inconsistent use of INSTALL_SCRIPT symbol in makefile, which
	  caused app-defaults and uxvile scripts to not install unless vile
	  was configured with perl (report by David Rolfe).

 20091013 (v)
	> Tom Dickey:
	+ override highlightThickness resource in xvile to eliminate screen
	  trash (report by Jim Crigler).
	+ update XVile.ad to match Debian package.
	+ some code-cleanup for x11.c and filters.
	+ work around defective gcc implementation of warn_unused_result
	  attribute with new IGNORE_RC() macro.
	+ add configure-script and makefile rules for app-defaults, icons and
	  desktop files for xvile, adapted from xterm.
	+ use "fixed" rather than XtDefaultFont as default font for xvile.
	+ improve TYPECAST macro using intptr_t type.
	+ document VILE_MENU environment variable in vile.hlp
	+ modify vilemenu.rc to implement a default-font entry, to restore
	  the font to whatever was given in a -fn option, or resource setting.
	+ add $font to the state variables that &default can work with.
	+ add uxvile script, based on uxterm.
	+ modify vilemenu.rc to provide fonts used in uxterm for the set of
	  ordinary fonts if the $term-encoding is utf-8.
	+ bypass symbols for XA_COMPOUND_TEXT() and XA_UTF8_STRING() in xvile,
	  to resolve portability issues with older X headers/libraries (report
	  by David Rolfe).
	+ correct handling of retries for different selection types in xvile
	  broken in 9.7u (report by Steven Lembark).
	+ update configure check for lex version to work with reflex 20090902's
	  inclusion of patch-date.
	+ fix objc.key to reset symbol table (i.e., from "cpre" to "objc")
	  before merging in "c" keywords (overlooked in 9.7q).
	+ correct list of options for c-filter, to make objcmode work with
	  external syntax filter.
	+ update config.guess, config.sub

 20090824 (u)
	> Mike Mackovitch:
	+ use temporary bp variable in calls to writeout() to ensure that the
	  buffer marked as unchanged will be the same.  This works around the
	  Perl api's use of fake windows, setting curbp to match the current
	  window, e.g., when redisplaying [Buffer List].
	> Tom Dickey:
	+ rename install.sh to install-sh, to avoid suffix-rules
	+ move definitions for GCC_PRINTFLIKE and GCC_SCANFLIKE into configure
	  macro.
	+ add configure check for HPUX 11 _XOPEN_SOURCE definition.
	+ modify configure check for lex states to show the number of states
	  the lex implementation supports.  The html filter currently uses 16.
	+ modify genmake.mak to require flex for html syntax filter; some less
	  capable lex's have a too-low limit on states.
	+ improve awk syntax highlighter:
	  + highlight inline comments.
	  + highlight regular expression used as parameter, e.g., in sub().
	  + change $0, etc., to Ident2 class for consistency with other filters.
	  + highlight some cases of unbalanced right-parenthesis or
	    curly-braces.
	+ handle XA_COMPOUND_TEXT and XA_UTF8_STRING selection types in xvile.
	+ allow ^VUddddd input for Unicode in decimal (base ten).
	+ modify logic for complex fences to avoid setting pre_op_dot, which
	  would result in selecting only the innermost level of complex fences
	  on a reverse-direction, rather than the outermost level.
	+ prevent run_a_hook() from running while an operator command is
	  running, to lessen the chance of autocolor modifying variables used
	  in the interactive operations, e.g., "d%" (report by Paul Fox).
	+ add xq (XQuery) majormode and syntax filter.
	+ restore xterm title string after running subprocess (report by Paul
	  Van Tilburg).
	+ reduce scope of curbp in file.c and region.c, prompted by Perl fix.
	+ fix mark/column translation for multibyte characters in a case where
	  the working column value was decremented past a multibyte character
	  boundary.
	+ build-fix for configure --disable-extensions
	+ build-fix for OS/2 EMX; the ksh implementation did not handle the
	  genmake.sh script.

 20090628 (t)
	> Joachim Schimpf
	+ fix typo in STARTQUERY pattern in ecl-filt.l (ECLiPSe/Prolog)
	+ improve ecl-filt.l parsing of based-numbers.
	> Tom Dickey:
	+ correct initialization ordering in filterio.c and builtflt.c, which
	  broke m4- and cweb-filters in 9.7r.
	+ various improvements to ecl-filt.l, to highlight strings and numbers.
	+ add prolog majormode.

 20090605 (s)
	> Tom Dickey:
	+ improve css syntax filter (and matching filter embedded in html
	  syntax filter):
	  + recognize comma for state transitions
	  + color non-keyword identifiers with Ident class.
	+ fixes for building filters with lex (not flex).
	+ check for majormodes which have a "before" property referring to each
	  other, and exit from resulting infinite loop.
	+ revert a performance fix from 9.7o in regexp.c to search-limits,
	  which broke the report of "Only one occurrence of pattern".
	+ fixes to make -v option for internal/external filters work from the
	  beginning of loading keyword files.
	+ add show-local-modes, as an easier-to-remember variation for the
	  count+show-modes flavor implemented in 970619 7.1f
	+ modify listmodes() to save its last parameters, so callers such as
	  for the animated feature can redisplay local-mode displays.
	+ modify filter keyword-processing to save/restore the default settings
	  for table- and attribute-values so that merging one keyword file into
	  another will not override the parent file's settings.
	+ suppress "Press return to continue" when running a shell command
	  which is modified by "~hidden" or "~quiet".
	+ improve checks for insecure file permissions (adapted from Steven
	  Lembark):
	  + modify check for insecure file permissions to exclude absolute
	    paths which are given by the user in scripts.
	  + write details on the reason why permissions failed to [Trace].
	  + only check ownership of files in current or home directory.
	+ change default color for Ident2 class to C3.  It was C6, which was
	  the same as Number.

 20090525 (r)
	> Tom Dickey:
	+ fix an old bug which prevented show-filtercolors from working more
	  than once on a buffer unless the buffer was re-read.
	+ correct color-initialization for filters which happen to use a "-k"
	  option to load the same symbol table as the filter's default table.
	+ make filters/genmake.mak auto-generated on Unix platforms, to ensure
	  that builtin/loadable/external filters all use the same filter-names.
	+ modify hs-filt.l to use the same filter-name "hs" as genmake.mak
	  (report by Brendan MacDonell).
	+ modify show-filtercolors to work with external filters.
	+ improve bat-filt.l, highlighting labels after a "goto" keyword.
	+ minor fix to sh-filt.l to show a pattern in a case statement which
	  includes a "#" mark.
	+ add "ant" and "mvn" (maven) modes.
	+ fix overlooked change from filter_name to default_table in buildflt.c,
	  needed to show proper colors with builtin filters from 9.7q for some
	  of the modes which override the default table, e.g,.  "csh".
	+ improve error-checking in show-filtermsgs and show-filtercolors
	  macros.

 20090518 (q)
	> Tom Dickey:
	+ improve which-source and which-exec commands (prompted by Paul Fox):
	  + use the same check for file-ownership as was done in 9.5m, showing
	    files which fail this check with "?" rather than "*".
	  + add a trace message showing filenames which fail the check.
	  + add check-access mode, to make this configurable.
	+ add show-filtercolors macro, using the "-Q" option of syntax filters.
	+ add "-Q" option to syntax filters, which makes the filter write a
	  ".keyword" table to stderr to show the effect of the "-k" option.
	+ as part of improvements for xml filter, modify the way keyword tables
	  are loaded.  Before, symbols were implicitly loaded into the default
	  tablename defined by the filter.  Now, they are loaded into the
	  table named by the "k" option to the filter.  Adjusted ".key" files
	  to use ".merge" rather than ".include" for the case where they used
	  the old behavior.
	+ improve xml filter (used for xsl mode) by using the prefixes defined
	  by xmlns properties to select different symbol tables.
	+ add xsl mode
	+ make format-til, lower-til, upper-til and flip-til work for UTF-8
	  (anon report on Savannah).
	+ correct allocation of temporary filename in spellflt.l for tmpnam(),
	  from 9.7f changes.

 20090430 (p)
	> Brendan MacDonell:
	+ improve scheme mode:
	  + fix/hack to properly handle combinations of quotation literals.
	  + highlight the unquote/unquote-splicing keywords.
	  + handle the optional scheme parentheses extension ('[' and ']').
	> Tom Dickey:
	+ minor tweak to manfilt.c to allow space to overstrike text.
	+ minor tweak to vbmode fences.
	+ correct some limit-checks in vl_regexec().
	+ correct a reallocation in html syntax filter html_quotes() function
	  that grew too rapidly.

 20090426 (o)
	> Tom Dickey:
	+ add DEFAULT_XSHELL, DEFAULT_XSHELLFLAGS symbols to statevar.c which
	  can be overridden by compiler flags to select something other than
	  "xterm" for $xshell variable, etc. (request by Brendan O'Dea).
	+ improve html syntax filter:
	  + check for "src" property in script tag before deciding whether to
	    use JavaScript keywords.
	  + create separate table "htmlprop" for HTML properties.
	  + highlight CSS embedded in HTML.

 20090405 (n)
	> Ingmar Ellenberger:
	+ reorder part of sql-filt.l to work with a non-flex parser.
	> Mark Robinson:
	+ build-fixes for mingw configuration when built using cygwin.
	> Tom Dickey:
	+ more fixes for lex-based filters:
	  + make builtin/loadable syntax highlighters work better with files
	    using recordseparator=cr by sending blanks instead of unexpected
	    line-feeds, as well as changing the used recordseparator to
	    newlines.  Make a similar workaround for recordseparator=lf by
	    filtering unexpected carriage returns.
	  + (jfg) change the error-exit when building with "new" flex to
	    warnings.  Report problems to "new" flex's "maintainer".
	  + add configure check for lex "%o" options.
	  + fix typo in noclass.sh for [[:blank:]].
	  + modify noclass.sh string for [[:print:]] to ensure there's no
	    embedded '-'.
	  + filter out "%pointer" options in noclass.sh (this could be a
	    separate configure check from character classes).
	  + modify fltstack.h to use it included twice - once in the declares,
	    and once in the code section, e.g., for the non-flex parser
	    encountered by Ellenberger.
	+ modify handling of recordseparator mode to let explicit rs=cr work
	  to read cr-delimited files, provided that dos mode is not set.
	+ add variable $modeline-limit to limit the offset into each line that
	  vile scans for modelines.  Use default 256.
	+ fixes/improvements for regexp.c:
	  + make vl_toupper() a macro, also use the buffer encoding to decide
	    whether to use system ctypes.
	  + change one of the limits for calling regexec from lregexec to
	    ensure that the string-end is not past the end-offset.
	+ improve performance for displaying syntax highlighting of very long
	  lines by using a fast check on the left/right limits of single-line
	  regions that could be displayed, and ignoring attributed regions past
	  those bounds.
	+ improve html filter by ensuring that "server" is the tag, not one
	  of the named values, e.g., "" vs "".

 20090322 (m)
	> Tom Dickey:
	+ improve performance for show-variables and describe-bindings.
	+ add un-filter (atr2ansi, atr2html and atr2text) executables to win32
	  makefile.
	+ implement quick-launch rule in winvile.iss script.
	+ add winvile-wide.iss installer script
	+ add limit-check in execkreg() in case a wide-character is passed as
	  the mark-identifier.
	+ add $kill-size and $kill-limit variables to improve scripting with
	  the $kill variable.
	+ add extra-colors "warning", for show-variables command.
	+ apply extra-colors to show-variables command.
	+ add new functions &bchanged, &fchanged and state variables $bchanged
	  (same as $modified) and $fchanged to make it simpler for scripts to
	  check if buffer/file timestamps differ (prompted by Paul Van Tilburg).
	+ add ".clw" and ".dsw" files to inimode and confmode, respectively.
	+ modify preamble settings for majormodes of the form "#!path" to make
	  them more distinct.

 20090228 (l)
	> Brendan MacDonell
	+ improve lisp and scheme modes:
	  + adds highlighting support for quasiquote/backtick (`), quote ('),
	    unquote (,) and unquote-splice (,@), including unquoted
	    sub-expressions.
	  + highlights the parentheses of quoted expressions in a different
	    color (glancing at the code, this appears to have been the initial
	    intent, except the 'quoted' stack variable was never initialized to
	    zero).
	+ improve scheme mode:
	  + uses a derived filter, 'rnrs' (I tried naming the filter 'scheme',
	    but apparently define_scheme is already defined by vile itself).
	  + highlights vector literals '#( ..  )' properly depending on their
	    context.
	  + removes the tokens from scheme.key which are now handled by the
	    filter.
	  + cleans up the keywords file by disabling the unnecessary .brief and
	    ..abbrev declarations.  This also allows some forgotten let*-style
	    keywords to be properly recognized.
	> Mark Robinson:
	+ fix configure.in to add icon for minvile target.
	> Tom Dickey:
	+ amend 9.7g change to use extra-colors for hyperlinks, to do this only
	  when the link starts with "view ", which is used in which-source
	  and similar macros.
	+ highlight pkg-config ".pc" files as "make" syntax.
	+ fix winvile "-i" option, which did not save the original command
	  string, so filenames with embedded blanks required quotes.
	+ fix read of file containing only a UTF-8 BOM; that confused the
	  empty-file logic.
	+ modify configure --with-perl to give a warning but not exit if the
	  configure script cannot link with perl.  This works around a recent
	  mismatch between gcc and perl on some platforms where perl declares
	  a prototype for main() which causes gcc to reject the parameterless
	  main()'s in the configure script.
	+ build-fixes for win32 (Visual C++ 7) and MinGW.
	+ renamed define_scheme to define_color_scm, rename rnrs filter to
	  "scheme".
	+ increase lex tables in htmlfilt.l and mc-filt.l for AIX.
	+ add "with" and "select" complex fences to vbmode and vb6mode.
	+ correct comparison used for continuation marker in vbmode comments.
	+ ensure that  is included in termio.c if it is needed for
	  SIGWINCH handling, e.g., with Mac OS X (finishes bug report by Daniel
	  L Ashbrook).
	+ update configure script macros:
	  + consistently append rather than prepend to $CFLAGS
	  + use $PATH_SEPARATOR variable rather than $PATHSEP
	  + minor fixes for Intel compiler warnings
	  + add case for "mint" to CF_XOPEN_SOURCE
	+ improve performance of on-the-fly UTF-8 regular expressions by
	  inlining and making checks to see if a byte is ASCII before doing
	  conversions.

 20090218 (k)
	> Tom Dickey:
	+ allow for continuation marker in vbmode comments.
	+ add static/shared/enum keywords to vbmode fences.
	+ add ".r" files to rexxmode
	+ add $term-cols, $term-lines and $term-resizes variables.
	+ correct comparison in set-char-class and unset-char-class that
	  prevented setting "upr" class.
	+ modify side-effects of setting global file-encoding to reset the
	  locale-based character set tables so that "ascii" will display 8-bit
	  characters in printable form, and setting to "8bit", "utf-8", etc.,
	  will restore the default character set tables.
	+ amend change to insertion from 9.7i, which broke compose sequences
	  (report by Paul Van Tilburg).
	+ add configure check for SIGWINCH, to fix resizing on OS X (report by
	  Daniel L Ashbrook)
	+ implement on-the-fly character classes for regular expressions in
	  UTF-8 buffers.
	+ add configure check for -Wno-unknown-pragmas, to help older versions
	  of gcc not warn about the pragmas in perl.xs

 20081204 (j)
	> Tom Dickey:
	+ add to $cfgopts some drivers (ansi, borland, ntcons, ntwin, os2vio,
	  vmsvt) and useful settings (iconv, multibyte).
	+ make ansi driver support color syntax highlighting.
	+ make xvile-pager work by adding a "+fork" option to ensure inputs
	  are captured before the script exits.
	+ fix a regression in "R" command from 9.7i; the check for quoting now
	  checks for UTF-8 continuation bytes but did not ensure that only
	  UTF-8 codes were tested before deciding whether to delete old bytes
	  during a replace.

 20081130 (i)
	> Tom Dickey:
	+ modify vilemenu.rc to work with --disable-shell configuration, by
	  making it scriptable, and using the scripting feature to omit menu
	  entries which use shell features.
	+ add "define-menu-entry" command.
	+ eliminate fixed limit of xvile's menu size.
	+ modify vileinit.rc to work with --disable-shell configuration.
	+ modify assert() in main.c to allow assert-checking with xvile.
	+ modify keyword ".merge" directive to make it distinct from ".source".
	  The former reads without modifying the table name, the latter builds
	  a new table.  Use this feature in the yacc syntax filter to keep the
	  terminal names and C keywords separate.
	+ improve yacc syntax filter, highlighting all of the terminal symbols
	  with "Terminal" class.
	+ improve lex keywords, from flex manpage.
	+ improve lex syntax filter to work with files having no "%{" section.
	+ correct treatment of "R" command for quoted characters, e.g,. ^V^G;
	  it was not deleting the characters which were replaced.
	+ correct one place where inserted bytes were interpreted as
	  characters, which caused the map-command to insert UTF-8 bytes as
	  characters (report by Christopher Illies).
	+ fix sign-extension in map.c, which caused a command like this
		:map! ^Ks, ^Vu0219
	  corresponding to UTF8 0xc8,0x99 to insert 0xffc8,0xffc9 (report by
	  Christopher Illies).
	+ modify end_named_cmd() and more_named_cmd() to check clexec
	  independently of isnamedcmd, since the latter is for interactive use,
	  and the former is for scripts.  This allows a .vilerc file to contain
	  a "map!" line which will be shown at startup.
	+ build-fixes for MinGW.
	+ experimented with flex's "-+" C++ option (but decided that cannot be
	  used in vile, since it changes the scope of yy_start).
	+ mods to compile with g++
	+ improve highlighting of vile macros by displaying numeric codes
	  following a control/V as in a map-command as numbers or errors if
	  fewer digits were found than expected (prompted by report by
	  Christopher Illies).
	+ modify make-filter to show tokens marked with @'s as preprocessor,
	  e.g., as used for autoconf.
	+ set file-encoding in digraph.rc to make comments (which are
	  in ISO-8859-1) display properly in UTF-8.

 20081110 (h)
	> J Chris Coppick:
	+ updated CaptHook.pm
	> Mark Robinson
	+ fix compiler-name for MinGW in version.c
	+ build-fix for MinGW
	> Tom Dickey:
	+ add "auto" value for recordseparator mode, which tells vile that if
	  all of the line-endings are CR/LF to use "crlf", and if all are
	  LF, to use "lf".  This overrides the dos mode which provides a
	  platform bias of the recordseparator mode.
	+ add a few overlooked mode initializations in init_mode_value().
	+ add percent-autocolor mode, which can be used to override the
	  autocolor mode for very large files.
	+ modify makefile.djg and borland.c to allow building
	  syntax-highlighting version for DJGPP, using builtin-filters.
	+ modify $startup-path for DOS/Windows where VILE_STARTUP_PATH is not
	  #define'd to add $exec-path to allow vile to find startup scripts in
	  the same directory as the executable (request by Rugxulo).
	+ fixes for which.rc in case vile is running in view or readonly mode.
	+ modify check for language value in html filter to accept anything
	  beginning "javascript", e.g., "javascript1.1".
	+ modify sql filter to highlight hexadecimal constants, which may be
	  used in T-SQL.
	+ correct parsing of C-style comments in sql filter, which did not
	  handle trailing blanks after the "*/" marker.

 20081027 (g)
	> Tom Dickey:
	+ extend vile-html-filt to use language value in script tag, e.g., to
	  handle C# scripts.
	+ modify mac_tokval() to set end-string value when processing the last
	  token on a line in script mode.  This lets a "set" command work by
	  itself in a ".vilerc".
	+ fix special case of killing buffers from [Buffer List], broken in
	  9.7f by increasing the number of digits available for buffer number.
	+ extend vile-html-filt to support asp/jsp files.
	+ add aspmode
	+ improve parsing of "<%" "%>" markers in htmlfilt.l, which must be
	  recognized anywhere - not just outside tags.
	+ implement extra-colors for hypertext commands, e.g., as used in the
	  which-keywords macro.
	+ improve loading of UTF-16 and UTF-32 when no byteorder-mark is
	  specified (report by Rugxulo).
	+ modify as-filt.l to disallow quoted strings from extending past the
	  end of a line (report by Paul Fox).

 20081019 (f)
	> Tom Dickey:
	+ add ".aspx" suffix to htmlmode.
	+ improve keyword parsing by switching back to the original table if
	  no parameter is given for ".table" directive.
	+ catch invalid-handle exception for winvile to fix problem with
	  spell-check.
	+ improve incremental search by highlighting match if the extra-color
	  isearch is set.
	+ improve manipulation of line-attributes in lnewline(), needed for
	  some cases in "show-extra-colors".
	+ add "show-extra-colors" command.
	+ add several "list-XXX" aliases to match "show-XXX" commands, for
	  consistency.
	+ correct amount of characters to replay after getting a backspace in
	  incremental search (report by David Rolfe).
	+ new "set-extra-colors modeline" provides better color+attributes
	  combinations than the mcolor mode.
	+ add "set-extra-colors" command, which will allow setting extra
	  colors for special buffers such as [Settings].
	+ correct ifdef in main.c for platforms which have 'environ', but do
	  not declare it.
	+ add configure check for utf8 library, needed for some platforms to
	  use iconv library.
	+ update config.guess, config.sub

 20080928 (e)
	> Tom Dickey:
	+ add checks to two places where a empty buffer would be reused when
	  loading a new buffer, to disallow that if the first buffer was one
	  specified on the command-line. This case is addressed:
		mkdir foo bar
		vile foo/file bar/file
	  as well as toggling the current/alternate buffers with "_" (report
	  by Decklin Foster).
	+ add Haskell (haskell) mode.
	+ add objective-c (objc) mode.
	+ use PERL_SYS_INIT3() and PERL_SYS_TERM() in perl.xs (Debian #495068).
	+ fixes to resume UTF-8 after suspend (^Z) or subshell (report by Janis
	  Rucis).

 20080817 (d)
	> Tom Dickey:
	+ add "show-undo-stack" command.
	+ fixes for passing macro parameters which contain a leading quote,
	  to avoid reinterpreting that as a string to de-quote (report by Janis
	  Rucis).
	+ improve vilefilt.l:
	  + remain in NORMAL state when an operator is found, since a motion
	    should follow.
	  + correct SSTRING pattern, which should not allow escaped
	    single-quotes.
	+ disable autocolor while processing any &function (report by Janis
	  Rucis).
	+ implement user-definable operators (prompted by discussion with Janis
	  Rucis):
	  + store-operator command
	  + $cmd-motion variable
	  Caveat: the "undo" applies to individual commands within the macro,
	  rather than to the whole macro.
	+ add a null-pointer check to kcod2fnc(), to handle case where parameter
	  of >motion is incorrect (report by Janis Rucis).
	+ modify leak-checking to include forked processes, e.g., for npopen.
	+ add link-test to the configure --with-perl option, in case Perl is
	  only partly installed (report by Janis Rucis).
	+ add case for dragonfly to CF_XOPEN_SOURCE configure macro.
	+ extend vile-lex-filt to handle some of flex's scanner skeleton:
	  + treat lines beginning with "%%" as a comment if they contain text.
	  + recognize copy-directives "%+", "%-" and "%*".

 20080727 (c)
	> Tom Dickey:
	+ modify winvile installer to optionally refrain from putting the
	  newly installed directories first in $VILE_STARTUP_PATH, etc.,
	  if they already exist in the given path.  That allows one to
	  have vile.rc in the first path, e.g.,
	  	c:\vile;c:\program files\vi like emacs
	+ add append-number, insert-number, overwrite-number commands to
	  work with character-numbers.
	+ highlight matches in which-keywords, etc., and put a hyperlink on
	  the highlighted text to view the corresponding file.
	+ fix initialization of XIM in xvile; compose sequences did not work.
	  Also make xvile build XIM code for configurations other than Athena,
	  by supplying fallback for resource definitions.
	  (report/analysis by Fabien Coutant).
	+ parse preprocessor-style directives for basic syntax highlighter.
	+ add complex fences to vbmode for try-blocks, with-blocks and classes.
	+ correct pattern for vbmode used for sub- and function-blocks to
	  ignore leading blanks.

 20080714 (b)
	> Mark Robinson
	+ modify configure script, etc., to build "minvile" and "convile"
	  flavors using MinGW.
	> Tom Dickey:
	+ add dtd majormode.
	+ move most of the ".XXXrc" files to confmode, except ".XXXshrc".
	+ minor fix for vile-sh-filt to allow filenames with embedded "-"'s.
	+ tabulate in borland.c the shift/control/alt flavors of cursor- and
	  function-keys, defining function keys up to 48 to reflect this.
	+ modify makefile.djg to make it simpler to build locale configuration.
	+ fill in some DTD-related keywords in xml.key
	+ add a brief mode format "%M" for modeline-format
	+ improve basic syntax filter by accepting a "." at the beginning of
	  identifiers to distinguish methods and properties from other names.
	+ split-out vb6 majormode from vbmode, leaving the latter for .Net
	+ modify vile-conf-filt to disallow quoted strings to extend to
	  multiple lines without escaping the newline.
	+ add mailcap mode.
	+ add "-c" option to vile-key-filt, which tells it to display tokens
	  in their final color rather than based on syntax.
	+ extend syntax keyword parsing to allow flags to be set for each
	  keyword, e.g., to mark keywords that are used to delimit comments.
	  Use this in vile-sql-filt to treat "prompt" and similar keywords
	  specially.

 20080624 (a)
	> Decklin Foster:
	+ modify spell filter to use $TMPDIR rather putting its temporary
	  files in the current directory.
	> Tom Dickey:
	+ improved sql highlighting:
	  + allow host variables in LEAD state.
	  + reset state to LEAD after "then" or "else".
	  + improve parsing of "@" character.
	  + fix a couple of state-transitions for numbers and strings.
	  + correct a misspelled color class "ident2" to "Ident2".
	  + allow newlines inside quoted strings.
	+ improved php highlighting:
	  + identifiers may begin with "_".
	  + color heredocs and nowdocs
	  + color comments beginning with "#".
	  + add preamble pattern for phpmode.
	+ improve locale initialization in vl_init_8bit() by merging the
	  with/without iconv chunks, except for the parts that explicitly
	  rely on iconv.  That fixes an unintended call to vl_mb_getch()
	  for some non-UTF-8 locales.
	+ correct initialization of table_8bit_utf8[] when iconv is not used.
	  If the locale did not use ISO-8859-1, the table was not initialized,
	  causing input to be ignored (report by Gary Jennejohn).

Changes for vile 9.7 (released Sat Jun 14 2008)

 20080601 (o)
	> Tom Dickey:
	+ simplify wvlwrap.exe by disabling globbing temporarily.  This allows
	  opening files whose names contain square brackets.
	+ improve checks in SetVarValue() and PromptAndSet() to ensure that a
	  mode is actually found, and checking whether a '$' prefix is used.
	+ modify fsm_complete() to lowercase the test-string, making it
	  simpler to save a boolean mode-value in a variable and restore it by
	  assignment.  This works because all of the enumerations use
	  lowercase names.
	+ suppress part of wildcard expansion in call to expand_wild_args(),
	  e.g., for command-line of winvile, since that interferes with
	  reading file whose names contain square brackets.
	+ modify wrapmargin mode to use negative values as a count from the
	  left of the screen (discussion by Chris Green, Paul Fox).
	+ make perlpod sections more readable by highlighting the control
	  lines (request by Steven Lembark).
	+ improve here-document parsing in sh-filt.l to work with "words"
	  which contain blanks.
	+ expand description of command-line history in vile.hlp
	+ document change to ".abbrev" and ".brief" in doc/filters.doc

 20080525 (n)
	> Brendan MacDonell:
	+ improve ruby syntax filter:
	  + match keywords containing '!' '?' and '=' depending on the context
	    (based on my best guesses as to the most common uses, which work
	    99% of the time - otherwise the entire ruby parser would need to be
	    integrated to correctly mimic these syntax quirks).
	  + remove unmatchable characters from the list of those matched
	    following $.
	  + change the instance variable matching to @@?{KEYWORD} instead of
	    @+{KEYWORD}.
	  + matching symbols as literals.
	  + constants (keywords beginning with a capital) are highlighted with
            the Type attribute.
	> Tom Dickey:
	+ modify ruby syntax filter to highlight binary integers (such as
	  0b10101).
	+ disable "*" and "?" abbreviation feature in ruby.key
	+ modify parsing of keyword files to accept an empty parameter for
	  "abbrev" and "brief", to disable the "*" and "?" feature.
	  Note: this syntax breaks earlier versions of vile.
	+ revise 9.6c fix for offs2col0(), restores selection highlighting
	  of newline (report by Eric Krohn).

 20080508 (m)
	> Mark Robinson:
	+ build-fix for eightbit.c without iconv functions.
	> Tom Dickey:
	+ update input-method code, from xterm.
	+ add xvile resource setting "openIm" to control whether it tries to
	  open input-method.
	+ change order of tests for iconv availability and configure option
	  "--with-iconv" to avoid adding iconv library to build unnecessarily
	  (report by Mark Robinson).
	+ modify prompt for new mode value to consistently show the mode's full
	  name.
	+ add "fk" alias for file-encoding mode.
	+ modify mktbls to allow special-case alias for modes which have no
	  convenient abbreviation.
	+ update config.guess, config.sub

 20080426 (l)
	> Tom Dickey:
	+ minor fixes to perl syntax highlighter:
	  + add double-quote to quote-delimitors.
	  + show interpreted symbols in double-quoted regular expressions.
	  + if "/e" modifier is set for regular expression, show interpreted
	    symbols for that.
	  + show regular expression modifiers in keyword-attribute, not string
	+ correct a loop expression in wrapword (report by Chris Green).
	+ correct a byte- versus character-count in wrapword() (report by
	  Chris Green).
	+ add $buf-encoding symbol, to show the actual encoding used by the
	  current buffer vs the file-encoding which is one of vile's internal
	  names such as "8bit" or "locale".
	+ add a "locale" value for file-encoding, use that as the default
	  (discussion with Paul Van Tilburg and Chris Green).

 20080410 (k)
	> Tom Dickey:
	+ remove obsolete lex-filters for perl and ruby (only the C versions
	  have been supported).
	+ update list of filters in doc/config.doc
	+ improve locale initialization, checking if there is no installed
	  narrow locale corresponding to the given (wide) locale.  In that
	  case, default to either ISO-8859-1 or ASCII, depending on whether
	  there was actually a wide locale whose encoding is UTF-8 or
	  ISO-8859-1, or neither (report by Paul Van Tilburg).
	+ force the [Printable Chars] buffer to use file-encoding=8bit,
	  makes it display consistently legal codes in the second column.
	+ modify xvile to use imdying() to handle runtime X errors, which
	  will attempt to save buffers (prompted by discussion with Steven
	  Lembark).
	+ flush the standard output before writing version message using the
	  standard error, in case there was some output pending (report by
	  Chris Green).
	+ improve bytes_before() behavior on illegal bytes; it was returning
	  the length of all illegal bytes adjacent to the current position
	  rather than just one.
	+ modify vl_conv_to_utf32() to use consistent error-return code when
	  continuation byte of UTF-8 fails check.  This is needed in some
	  cases to make ISO-8859-1 data display consistently in UTF-8 buffer
	  as "\?xx".
	+ fix display of ISO-8859-1 encoded file when file-encoding is set
	  to utf-8 (report by Chris Green).

 20080325 (j)
	> Tom Dickey:
	+ modify curses-driver to avoid a curses-refresh (repainting the
	  whole screen) between a shell command and the "Press return to
	  continue" message.
	+ make transpose-characters work for wide-characters.
	+ make "~" (flip-character) and related case-conversion work for
	  Unicode in 0..255 range.
	+ modify behavior of ":ww!" to act like ":w!", allowing it to write
	  all files.
	+ modify the vl_init_8bit() to use vile's built-in UTF-8 decoder for
	  cases where iconv() sees that the result will not fit into the narrow
	  encoding.
	+ correct bytes versus characters for inserting/replacing text in
	  utf-8 buffers (reports by Chris Green, Paul Van Tilburg).
	+ amend fix for recomputing list of modes used for name-completion
	  from 9.6e, to also force reallocation of an associated index.
	+ fix a missing #define in trace.h for GCC_PRINTFLIKE.

 20080313 (i)
	> Tom Dickey:
	+ change class color of parentheses in lisp syntax filter to "Action"
	  to make them easier to distinguish from "String".
	+ improve lisp syntax filter by coloring binary, octal and hexadecimal
	  constants, as well as parsing the "#\" patterns.
	+ remove ".scm" from c-suffixes pattern (report by Brendan MacDonell).
	> Brendan MacDonell
	+ add schememode and keywords based on
	  http://community.schemewiki.org/?scheme-keywords

 20080311 (h)
	> Tom Dickey:
	+ minor fix to configure --with-iconv to handle failure to find iconv.
	+ compiler warnings for DJGPP 2.04 with gcc 4.2.3 (report by
	  Rugxulo).

 20080224 (g)
	> Tom Dickey:
	+ correct conversion of facename for wide-character winvile's $font
	  symbol (report by George Eccles).

 20080217 (f)
	> Tom Dickey:
	+ minor improvement to vbmode's fence-if to ignore lines with
	  continuations.
	+ correct a pattern in latexflt.l, making it parse this pattern:
		\foo{$\{a, b\}$}.
	  (report by Paul van Tilburg).
	+ modify perl syntax filter to color &foo as a variable.
	+ modify perl syntax filter to color both class and member in variables
	  such as $foo::bar (request by Steven Lembark).

 20080207 (e)
	> Tom Dickey:
	+ reinitialize, rather than free the TBUFF result in run_func(), in
	  case some caller reuses that value.
	+ correct limit-check in xvile's really_draw() function (noted by
	  valgrind).
	+ recompute a list of modes used for name-completion after removing
	  a submode definition (from test data by Steven Lembark).
	+ modify getcol() to compensate for 9.6b change to next_column().
	  That fix prevents increasing the next-column computation past the
	  end of the line; while getcol()'s alttabpos computation assumes it
	  can get the column value of the next character.
	+ fix an incorrect reference in chgd_fences() which was exposed by
	  changing fence-pairs more than once in .vilerc, dating from 5.3l
	  (report by Steven Lembark).

 20080124 (d)
	> Tom Dickey:
	+ documentation improvements (suggested by Steven Lembark).
	+ add ".t" to perlmode, using $mode-pathname, noting that while perl
	  uses it, other programs do also (request by Steven Lembark).
	+ strip redundant "mode" from majormode names, avoiding the potential
	  for creating foomodemode when the script says
		  define-majormode foomode
	  (prompted by report by Steven Lembark).
	+ make vile's symbol-tables accessible to vilemode in winvile.  This
	  required some renaming to avoid symbol conflicts:
	  + rename TEXT and PATTERN states in filters to sTEXT and sPATTERN
	  + rename RECTANGLE to rgn_RECTANGLE, and the other region-shapes
	    to match.
	+ add stub for vl_check_cmd() to filterio.c, to work when the some
	  filters are external, and the selected built-in or loadable filters
	  did not include vilefilt.l (reports by Adam Denton, Steven Lembark).

 20080113 (c)
	> Tom Dickey:
	+ another fix for offs2col0(), to reduce an off-by-one limit check.
	+ workaround for HPUX lex, whose YYSTATE variable is unusable.
	+ cleanup/reduce g++ warnings.
	+ improve configure check for iconv.
	+ add workaround in eightbit.c for systems without
	  nl_langinfo(CODESET)), e.g., OpenBSD.
	+ make memory leak-checking work for filters.

 20080106 (b)
	> Tom Dickey:
	+ fix an out-of-bounds error reported by valgrind in next_column().
	+ modify treatment of ":setl dos" to behave the same as ":set-dos".
	  That makes it possible to put a "vile:dos" in a modeline and make
	  vile convert the line-endings.
	+ trim trailing blanks from text handled in modelines in case there
	  was a ^M.

 20071231 (a)
	> Tom Dickey:
	+ add a null-pointer check in offs2col0().
	+ fix an arithmetic overflow on HPUX which caused mis-encoding of
	  files read via slowreadf(), e.g., in [Output].

Changes for vile 9.6 (released Thu Dec 27 2007)

	> Tom Dickey:
	+ update makefile.blc, adding charsets.c, eightbit.c and wcwidth.c
	+ build-fix for OS/2 IBM CSet (define a delay function for catnap).
	+ minor build-fixes for VMS:
	  + modify vmsbuild.com to simplify workaround for broken MMS 3.8
	  + provide dummy variables for xvile to reflect modularization changes
	    with respect to vmsvt.c
	+ documentation updates.
	+ minor fix to manfilt.c to pass-through UTF-8 codes by testing with
	  both iswprint() and isprint().

 20071224 (u)
	> Tom Dickey:
	+ separate vile's ttputc from termcap prototype to pass integer param
	  rather than just a char on Solaris.
	+ fix computation of columns needed to show UTF-8 codes in POSIX
	  locale.
	+ modify manfilt.c to provide UTF-8 output in a UTF-8 locale.
	+ minor fix to CF_FUNC_ICONV to link iconv on cygwin (noting that
	  cygwin has no useful locale support, it may someday).

 20071202 (t)
	> Tom Dickey:
	+ modify filters makefile "clean" rule to accommodate OSF/1 4.0D
	  whose make program leaves intermediate ".c" files for each lexer.
	+ change order of restore-flags and switch-buffer in
	  restore_buffer_state, avoiding an unnecessary prompt to discard
	  changes when attempting to read a buffer that cannot be read.
	+ increase a few table sizes to work with AIX 5.1 lex.
	+ modify check for lex version to avoid hanging on older platforms
	  where it would try to read from standard input even if it does not
	  recognize the option.

 20071125 (s)
	> Tom Dickey:
	+ several changes to provide usable Unicode support:
	  + add mode percent-utf8 to set a threshold for file-encoding mode
	    "auto" detection of UTF-16/UTF-32 files.
	  + file-encoding mode can be set to "auto", to detect UTF-16 files,
	    which are loaded as UTF-8.
	  + UTF-8 files are detected based on the file-encoding mode as well.
	  + Unicode values are displayed (where no locale controls) as "\uXXXX"
	    in 4 hexadecimal digits.
	  + add unicode-as-hex mode to override locale, forcing Unicode values
	    to display as "\uXXXX".
	  + for buffers with UTF-8 encoding, show illegal bytes as "\?XX".
	  + Unicode values can be inserted into buffers using ^VuXXXX form.
	  Limitations:
	  + terminal drivers support Unicode display in varying degrees:
	    + winvile - multicolumn characters, depends on font selection
	    + termcap/terminfo - relies on terminal emulator, knows about
	      multicolumn characters
	    + xvile - displays only single-column characters
	    + curses - depends on the curses library, e.g., ncursesw
	    + win32 console - not yet implemented
	  + combining characters are not combined.
	  + registers hold byte data, will show the UTF-8 encoding for data
	    rather than a \uXXXX (unless the file-encoding for [Registers]
	    is changed).
	  + some "characters" such as the report for yanked text is still
	    really a byte-count.
	  + inserting a \uXXXX into the minibuffer will display the UTF-8
	    encoding.
	  + regular expressions are not wide-character aware.
	  + UTF-16 and UTF-32 files are detected based on BOM and/or the
	    contents of the first line of the file.
	  + external syntax filters do not handle BOM or UTF-16, UTF-32.
	+ improve name-completion by saving/restoring the original window and
	  buffer when [Completions] closes, rather than the closest window.
	+ add output from rcshist to diffmode.
	+ add ".vbp" files to inimode.
	+ modify configure script to omit lex-filt.l from build if lex is not
	  really flex, since the tables are too large for the older program.
	+ modify spell.pm to use a temporary file to work with newer Perl's
	  that do not handle tied variables exactly as filehandles.
	+ update Kevin Buettner's email address.
	+ add -class option to xvile.
	+ remove a redundant XtDestroyWidget() from x_close() to quiet a
	  warning from XtRemoveGrab() when doing a ":q" from Xm-vile
	  (report by Chris Green).
	+ use va_copy() in dofmt() to work with Linux on powerpc
	  (report by Paul van Tilburg).
	+ add docbookmode
	+ improve 9.5m/9.5q check for file ownership, adding a warning message
	  for files which are ignored (report by Chris Green).
	+ change default for --with-locale configure option to mesh with
	  --disable-extensions.
	+ improve paste-performance in winvile by passing whole-line chunks
	  to the insert-function.
	+ improved cppmode's identifier-expr (report by Gerry Fredette).
	+ correct order of evaluation from 9.4w when setting record-separator,
	  which was setting "crlf" ending temporarily when computing the buffer
	  size, even when "lf" was intended.  That would cause an immediate
	  write from winvile (without change) for a buffer to write too many
	  characters.
	+ add syntax filter conffilt.l, for "ordinary" config-files.
	+ add "rectangle-insert-mode".
	+ fill in several omitted items in init_mode_value().
	+ add "describe-&functions" and "describe-$variables" commands.
	  (The latter is a stub for later).
	+ improve repainting in winvile while processing external command.
	  also modify keyboard handling to provide type-ahead while processing
	  external command.
	+ remove obsolete $tpause variable.
	+ modify majormode inferencing to check preamble for [Standard Input]
	  and [Output] buffers.
	+ add ">motion" function for scripts.
	+ improve handling of enumerated values by forcing all to lowercase,
	  e.g., to eliminate the need for the special case in 9.1x to handle
	  "TRUE" and "true".
	+ revise lstrinsert() and associated logic which implements changes
	  to rectangles, e.g., with c^Aq, to ensure that it pads the change
	  with blanks rather than nulls (report by Paul van Tilburg).
	+ improve modeline support by ignoring strict "vi" modeline options
	  that are not recognized by vile, rather than reporting an error.
	+ use new module blist (binary search of lists) to reduce linear
	  searches in the places where btree is not already used.
	+ change rename-other-buffer command to other-buffer-rename, to avoid
	  name-completion conflict with rename-command (feedback from Steven
	  Lembark).
	+ remove obsolete check for ANSI qsort.
	+ improve vilefilt.l, highlighting mode names and displaying error
	  for unknown mode, function and state variables.
	+ fix typo in manpage.rc which broke use of pod2man in 9.5m
	+ add &pquote in manpage.rc, to allow it to format html output when
	  vile-manfilt, etc., reside in directories containing spaces in their
	  name.
	+ add ".reg" filetypes to inimode.
	+ add several package-related suffixes to sqlmode.
	+ add xpmmode

 20070603 (r)
	> Tom Dickey:
	+ amend makefile.in change for $(SRC) to use a translation rule that
	  works with IRIX64 (and some broken BSD) make programs.
	+ correct parsing/removal of "-i" option in winvile, taking into
	  account double-quoting of parameters and also options which have
	  parameters.
	+ make configure --with-no-leaks work for external filters, e.g., using
	  valgrind.
	+ add configure script check for tdelete(), provide a replacement if
	  not found (report by Gary Jennejohn).

 20070528 (q)
	> Tom Dickey:
	+ change configure script to check for ispell before aspell; Fedora 5's
	  problem with aspell was eventually fixed.
	+ make cursor-adjustment after paste in xvile dependent on whether the
	  pasted text ended with a newline (request by Eric Krohn).
	+ cleanup the bottom line on the screen when exiting the curses driver,
	  to match the termcap/terminfo driver (report by Chris Green).
	+ fixes for pl-filt.c, the perl highlighter:
	  + allow blanks before tag for here-document, e.g.,
		cat << 'TAG'
	  + allow '~' as a quote-delimiter (this is used by linklint).
	+ modify CF_IMAKE_CFLAGS to work with Solaris sed, which (unlike a
	  standard UNIX implementation) does not honor nested subexpressions.
	+ add rename-other-buffer command, use that to modify spell.rc so it
	  can work with scratch buffers which otherwise would be lost, e.g.,
	  "[Help]".
	+ add modelines for winvile.rc and w32ole.rc to set the majormode to
	  rcmode, and modify a special case in main.c to make "vile winvile.rc"
	  get the corresponding majormode.
	+ add some null-pointer checks in filters for result from flt_alloc().
	+ add a check in flt_alloc() in case the pointer has not been
	  allocated.
	+ derive $(SRC) from $(OBJ) in makefile.in, to avoid losing trace.c
	  in tags rule.
	+ check for empty/default "put" in line.c's PutChar() to avoid
	  attempting to remove a trailing newline from that, since the
	  corresponding line has already been freed as part of the undo process
	  (report by Paul Fox).
	+ use O_NONBLOCK if O_NDELAY is undefined, needed for a few platforms
	  which have the POSIX definition but not the legacy, e.g., Minix and
	  OS X.
	+ make autocolor work for curses-driver, e.g., --with-screen=ncurses
	  (report by Chris Green).
	+ widen the check for "winvile" in vileinit's initialization for win32
	  shifted cursor bind-key's.
	+ modify spell filter so that it can get VILE_SPELL_FILT from the
	  registry on win32.
	+ improve spell filter camelcasing that when parsing things like
	  "UXTerm" it splits off the "Term" as a possible word.
	+ amend 9.5m change to check for file ownership to ensure this is
	  only done for files that might be source'd.  It was checking files
	  for read/write too.
	+ correct syntax highlighting for end of JavaScript embedded in HTML,
	  which did not allow for the marker in an inline comment.
	+ modify "filename" shown in :show-filtermsgs to use the buffer name
	  if no filename is available.
	+ modify preamble patterns for shell modes such as awk, etc., to allow
	  for programs without an absolute pathname, e.g., "#! awk".
	+ modify the symbol-table lookup in filters.c to use tsearch() when
	  available.  For an 8Mb rtf file this improved performance by about
	  a factor of two (on Linux - Visual C++ has no tsearch).
	+ add configure check for getc_unlocked(), putc_unlocked() and
	  tsearch() to use in performance improvements for syntax filters.
	+ add syntax filter for RTF files.
	+ improve autocolor on win32 by not allowing the cursor to be repainted
	  while autocoloring is in progress.
	+ modify winvile's command-line parsing, adding "-i" option to perform
	  the case used for "Send To": use the part of the command line after
	  options as the filename and change working directory to match
	  (request by Larry Gensch).

 20070425 (p)
	> Tom Dickey:
	+ modify spell- and txt-filters to allow users to add words to their
	  respective ".keywords" files to override the builtin highlighting.
	+ correct check of return of ffread() in spellflt.l's workaround for
	  platforms such as win32 which have no usable popen().  That made
	  spelling checks require two ^X-i presses.
	+ modify spellflt.l to chop words according to Camel-case, so
	  tokens such as "ChopWords" are treated by the spell checker as
	  multiple words.
	+ fix a limit check in argc/argv[] parsing for winvile (report by
	  Larry Gensch).
	+ modify wvwrap.exe to work with pathnames containing "$", "&" and "'".
	+ change OPT_MULTIBYTE definition to depend on OPT_LOCALE.

 20070115 (o)
	> Tom Dickey:
	+ change Inno Setup script to not put version numbers on the SendTo
	  and context-menu entries.
	+ start adding support for UTF-8 (modes "byteorder-mark" and
	  "file-encoding").  The byteorder-mark is workable, but the
	  file-encoding is a stub.  This works to strip the BOM from files
	  as they are loaded, making syntax highlighting work for XML files.
	+ correct two places in exec.c which used skip_blanks() rather than
	  skip_space_tab() from 9.5l changes.  This caused the command
	  parser to treat ^K as a blank, breaking digraph.rc which uses
	  that character (report by Gary Jennejohn).

 20070108 (n)
	> Tom Dickey:
	+ add a character-class check to find_b_file() to prevent names such
	  as "" from being canonicalized into "vile.1" on win32 via
	  FindFirstFile().  This fixes a problem where ^X-n would sometimes
	  display the wrong buffer.
	+ add shifted-cursor-key bindings for winvile, like xterm.
	+ amend cursor-tokens mode so that ^X-e in a directory-buffer always
	  uses the whole line (no regular expressions).
	+ fix a null-pointer dereference in the cursor-tokens mode.
	+ minor fix to sh-filt.l to handle lines like
		: ${BUILD_CC:='${CC}'}
	+ improve iss-flt.l to highlight preprocessor lines.
	+ improve winvile.iss (Inno Setup):
	  + use values in patchlev.h to set the package version information.
	  + add context menu and Send To shortcuts
	  + install the keyword files
	+ add configure --with-valgrind option.

 20061212 (m)
	> Tom Dickey:
	+ add showvariables mode, for testing expressions used in [Variables].
	+ correct comparisons used for handling bounds in regular expressions,
	  e.g., the "2" in "\(this\|[l-m]\)\{2\}".
	+ change behavior of regular expression OR'd alternatives - only the
	  first match was used rather than the longest one.
	+ fix configure script macros which omitted X_EXTRA_LIBS in one case,
	  and repeated libs in another.
	+ fill in complete list of event names for xres.key from Xt/TMParse.c
	+ make ShowFormatted macro more configurable by allowing environment
	  variables $VILE_NROFF_FILT and $VILE_TABLE_FILT to override the
	  choice of programs therein.
	+ disallow source'ing from the current directory if the source'd file
	  might be writable by other users.
	+ improve fences in vbs- and vbmode.
	+ fix xresfilt.l; X resource files do not have embedded comments.
	+ minor improvements/fixes to &default, to allow it to assume that
	  '$' is implied for modes.
	+ modify locale initialization to work with koi8rxterm.
	+ add character classes [:ident:], [:octal:] and [:path:], and change
	  the association of \w and \W to [:ident:], making [:alnum:] no longer
	  include "_".
	+ add cursor-tokens mode to control whether vile uses regular
	  expressions, character classes or a combination to obtain tokens
	  from the screen.
	+ add $buf-fname-expr to show the combined bufname-expr, pathname-expr
	  used to interpret ^X-e.
	+ add bufname-expr, identifier-expr and pathname-expr buffer modes to
	  provide regular expression parsing of $bufname, $identifier and
	  $pathname in the show-variables command as well as for the related
	  expansion of tokens from the cursor position.  If the expressions are
	  empty, the code falls through to use the corresponding older
	  character-class parsing.  Default values are provided for each *-expr
	  mode.
	+ fix a case where set-window might remove the only window before
	  attempting to put a file in it.
	+ quote "$HOME" in CF_SUBDIR_PATH, for cygwin users.

 20061107 (l)
	> Tom Dickey:
	+ modify ":describe-bindings" to show whether the command accepts a
	  range, and whether it is undoable.
	+ add ":goto-percent" function.
	+ add (nvi/vim) ex-commands: a!, c!, i!
	+ add ":c" as alias for ":change-til" (nvi/vim).
	+ change unimplemented ":c" to ":co" (reference O'Reilly vi-book)
	+ fix makefile dependency for tags
	+ review/update use of "CNT" in describe-bindings
	+ revised command-line option parsing to use scripting more effectively:
	  + multiple startup files are allowed.
	  + most command-line options are translated to their equivalent script
	    and executed, rather than saving state for the most recent of each
	    option.  This makes the -s, -S, -g, -G options obsolete (but still
	    accepted).
	  + add "-c" option (the POSIX form of "+").
	+ modify configure script to use ncurses5-config, etc., if found when
	  handling the --with-screen=ncurses or --with-screen=ncursesw options.
	  It also is checked when handling the --with-ncurses option for the
	  termcap/terminfo driver.
	+ add suffix/name rules for "Jam" files.
	+ fix preamble pattern for pymode so it does not match a ":" line
	  which should be shmode.
	+ implement patterns as line-specifiers in ex-mode.
	  (this does not work with history-scrolling yet).
	+ remove incorrect check for empty parameter from which-menu from 9.4m
	  changes.
	+ check xvile menu to ensure that "C" header is given, adding a
	  dummy one if not (report by Chris Green).
	+ add checks to ensure that neither modelines nor majormodes can alter
	  these modes: all, crypt, readonly, viewonly.
	+ implement vi-style modeline, limited to setting buffer- and window-
	  modes, or majormodes.
	+ add "#" as an alias for number-lines-til
	+ improve highlighting of comment-lines (denoted by "--") in txtmode.
	+ fixes for termcap syntax highlighter, i.e., tcmode:
	  + allow description field to be empty
	  + color the "|" between aliases.
	  + improve string- and escape-parsing
	+ fixes for terminfo syntax highlighter, i.e., timode:
	  + allow description field to be empty
	  + color the "|" between aliases.
	  + allow aliases to contain blanks.

 20060924 (k)
	> Paul van Tilburg
	+ add syntax filter (mcrl) for mCRL/mCRL2 modeling language.
	> Tom Dickey:
	+ modify fileread() to ensure that the error-buffer is reset after
	  reading (or re-reading) a shell/pipe command, e.g., using ":e!".
	+ fix configure --disable-largefile option, from ncurses.
	+ minor fixes for nroff filter to improve rendition of groff's macros.
	+ add configure check for ncurses 5.2(sic) on FreeBSD, which was broken
	  by an incomplete set of changes to wchar.h (report by Chris Green).
	+ add configure check for aspell, whose attempt at a compatibility
	  script for ispell does not recognize ispell's options.
	+ workaround for breakage in FreeBSD's header files: updates to wchar.h
	  were not reflected in updates to curses.h (report by Chris Green).
	+ remove reference to obsolete http://www.vile.cx from README (report
	  by Paul Fox).
	+ update config.guess, config.sub

 20060625 (j)
	> Tom Dickey:
	+ fix expression for shmode $mode-filename to match ".profile".
	+ various small build-fixes (prompted by reports by Paul Fox, Clark
	  Morgan).
	+ amend 20050214 change to set_files_to_edit(), which caused partly-
	  read buffer to be discarded if ffgetline() was interrupted, e.g.,
	  by a ^C during a slow pipe read.  Now the buffer contents are
	  retained.
	+ update config.guess, config.sub

 20060531 (i)
	> Tom Dickey:
	+ fix error-reporting for a "~break" without a preceding "~while"
	  (report by Clark Morgan).
	+ minor fixes for tc-filt.l (termcap mode).
	+ fix x11.c for Motif broken in 9.5f cleanup (reported by Paul Fox).
	+ improve bas-filt.l by not highlighting incidental matches in the
	  attribute section of a Visual Basic form-file.
	+ correct parsing of hexadecimal constants in bas-filt.l
	+ add .ctl suffix for vbmode
	+ fix a case in bsizes() which subtracted line-ending from zero-sized
	  buffer when nonewline mode was set (Debian #368007).

 20060521 (h)
	> Clark Morgan:
	+ document write-all-buffers command.
	+ add echo-to-clipboard mode for Win32 hosts:
	  all text selected with the mouse is automatically
	  copied to the Windows clipboard. (U)
	> Paul Fox:
	+ updated contact information in README, vile.1 and vile.hlp
	> Tom Dickey:
	+ allow a version number in rbmode (ruby) preamble.
	+ add check in m4-filt.c for unbalanced quote, show the affected area
	  as an error.
	+ add ".ddl" suffix to sqlmode.
	+ add ".dsr" suffix to vbmode.
	+ fix makefile.blc, broken in 9.5f cleanup.
	+ fixes for 64-bit warnings of Visual Studio .NET 2003:
	  + modify Member_Offset() macro to cast the difference between
	    addresses to a long rather than casting a pointer to a long.
	    Use this flavor for Visual C++.
	  + size_t is not necessarily the same size as unsigned - modify code
	    to use size_t where it is consistent, otherwise cast as needed.
	+ updated for python keywords
	+ modify some lex filters, e.g., sql, to exclude \r in the places that
	  exclude \n, since \r should not be colored.
	+ fix for tb_enquote(); a value pointed to memory that had been
	  reallocated.
	+ make OBJEXT configure feature work for optional objects such as api.o
	+ updated configure macros CF_CURSES_CPPFLAGS, CF_CURSES_LIBS,
	  CF_NCURSES_CPPFLAGS, CF_PATH_SYNTAX, CF_WITH_IMAKE_CFLAGS,
	  CF_XOPEN_SOURCE.
	+ update config.guess, config.sub

 20060402 (g)
	> Tom Dickey:
	+ minor fixes to make most of the lex filters build with "old" lex,
	  e.g.,
		http://heirloom.sourceforge.net/devtools.html
	  Note: the lex-filt.l file is too complex for some older lex's.
	+ add lua mode
	+ save/restore curgoal variable in b2vprintf() to avoid side effects
	  when invoking "backward-row" or "forward-row" commands (report
	  by Chris Green).
	+ add delphi mode
	+ add "*.cs" files to grep macros on win32 platform
	+ improve csmode by making the section macros look for function
	  headers.

 20060219 (f)
	> Clark Morgan:
	+ update vile.hlp for %n and %N title format changes.
	> Tom Dickey:
	+ fix sh-filt.l for parameter substitutions containing an escaped
	  quote, e.g.,
		VERSION=${VERSION#*VERSION \"}
		VERSION=${VERSION%\"*}
	+ add csmode (for C# ".cs" files) and cs.key, using vile-c-filter for
	  parsing.
	+ modify ntwinio.c to invoke build_recent_file_and_folder_menus() in
	  the WM_INITMENUPOPUP event rather than WM_SYSCOMMAND.  This makes
	  winvile initialize the recent-folders and recent-files if one uses a
	  right-click on the title of the window.
	+ change winvile's registry subkey for recent-folders and recent-files
	  to match environment variable settings from 9.4r, e.g., change
		"Software\winvile\MRUFiles"
	  to
		"Software\VI Like Emacs\MRUFiles"
	+ add new symbols $return and $_ which can be used to implement simple
	  functions (request by William James).
	+ fix filters/makefile.2nd to allow build for gcov
	+ improve majormodes for complex fences by initializing the (non-string)
	  buffer mode values for submode groups according to the values in
	  the submode.  This makes ignorecase work as expected in the complex
	  fence matching for vbmode.
	+ add complex fences to vbmode.
	+ minor fix to bat-filt.l to avoid highlighting ".bat" as a string in
		call foo.bat
	+ change htmlfilt.l to highlight character- and URI-references as
	  numbers to make them distinct from strings with ordinary text.
	+ add makefile rules for installing/uninstalling files from doc
	  directory:
		install-doc
		uninstall-doc
	  as well as installing/uninstalling macros
		install-macros
		uninstall-macros
		uninstall-perl
	+ correct logic for goto-char, broken in 9.4za (report by William
	  James).
	+ fix change to cpp.key in 9.5e, which put the C keywords in the wrong
	  table.
	+ add spell.rc to makefile.wnt install rule.
	+ add test_io.exe rule to vmsbuild.com
	+ add TERM.clean(), TERM.unclean(), TERM.openup() to help move diverse
	  code out of termio.c
	+ modify var_TITLEFORMAT() only call set_editor_title() when setting
	  $title-format, and modify get_statevar_val() to handle some limited
	  recursion just in case there are other cases where it could be called
	  from the statevar.c module while retrieving a value.  This fixes a
	  bug introduced in 9.5e (report by Clark Morgan).
	+ update title when doing a "cd", in case it uses %r substitution.
	+ change %n in modeline substitutions to use file name (pathleaf)
	  rather than relative path (shorten_path).  Use %r for the latter.
	  (request by Clark Morgan).
	+ move VMS-specific code from termio.c to vmsvt.c
	+ remove unused start_debug_log() and mallocdbg() from main.c
	+ correct typo in ifdef for Visual Studio C++ 6.0 ifdef in w32ole.cpp
	  from 9.5e changes.
	+ move 9.5c check for stdout not a tty on startup to allow "vile -V"
	  to pipe to other programs.
	+ split-out nullterm.c
	+ add test_io stub, to help isolate dependencies of the I/O drivers.

 20060109 (e)
	> Clark Morgan:
	+ improved winvile's "flash".
	+ several changes to w32reg.c:
	  + if at all possible, don't register ole-enabled winvile using the
	    path ".\winvile.exe" (obscure cygwin corner case).
	  + remove use of toUpper(), which is not legit for winvile in this
	    context because the underlying mapping array is apparently _not_
	    initialized.  With this fix, "winvile -Ou" now displays the
	    editor's name in MessageBox text (rather than "").
	  + fixed lots of misuses of registry APIs (not properly testing return
	    code).  With fixes in place, winvile -Ou/-Or now properly reports
	    an error when registration/unregistration is attempted by an
	    account with insufficient privileges.
	+ add section definitions to vbmode.
	+ fix:  wvwrap caused winvile to show an 8.3 folder name in Recent
	  Folders list.
	+ fix:  when CD'ing to a directory stored in winvile's "recent folders"
	  list, the cursor stayed in the mini-buffer following a call to pwd().
	> Tom Dickey:
	+ adjust makefile dependencies to allow "make -j4" when building the
	  loadable filter configuration (report by Ciaran McCreesh).
	+ add "+", ",", "&", "@" and ";" to URL patterns in filters.
	+ modify nr-filt.l to allow for optional blanks between the leading
	  "." and the command.  This is common in nroff library macros, not
	  in manpages, etc.
	+ improve lex-filt.l, allowing for some flex extensions:
	  + allow code in action rules to not have curly braces
	  + allow curly-braces to surround chunks of flex actions
	  + "*" as a state name.
	+ add named marks for decimal digits (request by George Eccles).
	+ fix stray ^@'s on the winvile popup menu resulting from changes to
	  kcod2prc() for xterm-fkeys mode (report by Clark Morgan).
	+ add a call to set_editor_title() at the end of swbuffer_lfl() to
	  make title updates work properly with termcap configuration.
	+ add %n and %N substitutions for $title-format (prompted by Clark
	  Morgan comments).
	+ modify FreeBuffer() to clear window's buffer-pointers that point to
	  the freed buffer, e.g., to prevent reference to free memory in title
	  updates (report by Clark Morgan).
	+ check file descriptors in stdin_data_available() to avoid doing a
	  fdopen() on an invalid descriptor.
	+ add "#import" in cpp.key
	+ modify preamble for xml- and html-modes to ensure that the first
	  tag determines the type.
	+ fixes to makefile.wnt and mkprlenv.wnt to work with Visual C++ 7.
	+ correct padding of subtitle line for "Temporary variables" in
	  [Variables] buffer, which was applied to all temporary variable
	  lines.

 20051129 (d)
	> Tom Dickey:
	+ fix vl_ctype.h to avoid redefinition of UCHAR (reports by Clark
	  Morgan, Mark Robinson).
	+ fix lex-filt.l to build with lex (report by Dave Rolfe).
	+ fix include-path in makefile.wnt, makefile.djg makefile.icc to work
	  with split-out headers for regexp.c
	+ remove code for DISP_IBMPC
	+ remove makefile.emx and config.emx (obsolete).
	+ remove makefile.wat and makefile.tbc, since they used ibmpc.c

 20051123 (c)
	> Clark Morgan:
	+ remove an obsolete comment in macros.doc regarding underscore in
	  macro names.
	> Paul Fox:
	+ correct logic for check_percent_crlf(), ensuring that empty buffers
	  are not counted as having CRLF endings.
	> Tom Dickey:
	+ fix to_tabstop() function used for :describe-bindings to ensure that
	  a binding that happens to be 8 columns will still have a tab after
	  it.
	+ add a fflush() to ensure that the control string to reset xterm mouse
	  mode is written during ^Z handling (report by Fabien Coutant).
	+ add a call to term.kopen() in rtfrmshell(), making ^Z/resume work
	  properly with the curses driver (report by Fabien Coutant).
	+ make mouse work for curses driver just like the termcap/terminfo
	  driver.
	+ split xterm-specific code out of tcap.c as xterm.c, to share with
	  curses.c
	+ indent'd borland.c
	+ remove ibmpc.c (obsolete)
	+ check if stdout is not a tty on startup, print error message and
	  exit (request by Paul Fox).
	+ add mode xterm-fkeys, to allow termcap driver to generate
	  shift/control/alt modifiers for function keys.
	+ modify regexp.c so tab is not matched by \p or [[:print:]] for
	  consistency with POSIX regular expressions.
	+ modified regexp.c, add headers vl_regex.h, vl_alloc.h and vl_ctype.h
	  to allow it to be easily built outside vile (request by Adrian Kole).
	+ add KEY_BackTab to the output of show-key-names
	+ fix kcod2prc() so that a shifted-tab is converted to "Shift+^I"
	  rather than emitting a literal tab in the result.
	+ update vilemenu.rc fonts to work on Debian/testing.
	+ improve scrollbar/cursor tracking in winvile by calling
	  gui_update_scrollbar() when WFMOVE flag is set (report by Deraj
	  Puma).
	+ add a simple csvmode for ".csv" files.
	+ add ".ebuild" suffix for shmode.
	+ improve mode-pathname for xresmode to handle things like KOI8Term.

 20051002 (b)
	> Tom Dickey:
	+ update config.guess, config.sub
	+ improve os2vio.c, adding a check to distinguish between fullscreen
	  and VIO to allow using bright background colors in the latter (report
	  by George Eccles).
	+ add KEY_xxx definitions to OS/2 and Win32 drivers, defining up to
	  KEY_F35 for the former and KEY_F24 for the latter (report by George
	  Eccles).
	+ several improvements and fixes to lex-filt.l
	  + expressions for regular expression parsing are more complete, which
	    allows separating patterns from state lists.  That allows some
	    error-checking in the rules section to flag spurious whitespace
	    after a regular expression.  The more-complete regular expressions
	    make the parser much larger (about 5 times the original size).
	    A rewrite in C might be shorter.
	  + ignore case of "%s" vs "%S" or "%state", etc.
	  + parse the pattern names, applying highlighting to the names where
	    they are embedded in regular expressions.
	  + parse the "%s" (state) lists, applying highlighting to the states.
	  + handle flex's <> token.
	  + handle character classes in the RANGE pattern.
	+ remove an update() call from the logic in input.c which decodes
	  hex/octal input after a ^V.  That caused the screen to move the view
	  according to the address in the command, e.g.,
		:%s/^Vx12
	  would scroll to the bottom on entry of the "x" (report by Daniel L
	  Ashbrook).
	+ correct behavior of set-dos command, which did not recompute the
	  buffer-size.
	+ make end-of-token test for store-proc consistent with bind-key,
	  i.e., alphanumerics and hyphen.  Amend that test to allow underscore
	  (report by George Eccles).

 20050905 (a)
	> Tom Dickey:
	+ review/improve vl-filt.l based on Verilog LRM draft
	+ add configure check for lex's which support character classes, and
	  add filters/noclass.sh to work around those which do not.
	+ improvements to configure script from ncurses:
	  + improve check for Intel compiler warnings
	  + improve check for gcc version
	  + define _QNX_SOURCE for QNX
	+ revert part of 9.4n, which caused readin() to return false if there
	  was no filename associated with the buffer.  Doing this broke some
	  macros such as which-keywords (using buffer constructed by the
	  macro).  Previously it returned true, indicating success.
	+ improve parsing of range expressions in lex-filt.l, fixes a case
	  exposed by css-filt.l
	+ correct a case where slowread() in dosmode would compute an incorrect
	  buffer size.
	+ modify bat-filt.l to highlight "echo." consistently with M$ usage.
	+ modify bat-filt.l to highlight "%*".
	+ add syntax filters for bnf, css, midl, php and wbt, for WinBatch.
	+ modify syntax filters to use flex's character classes.

Changes for vile 9.5 (released Mon Jul 25 2005)

 20050717 (zb)
	> Clark Morgan:
	+ if winvile is minimized, don't resize client rectangle.  This fixes
	  a case where minimizing the editor with more than one window, then
	  restoring it, only one window was shown.
	+ amend change from 9.4p which changes the pointer symbol; fixes a case
	  where the pointer is not restored when moving along a mode line onto
	  the scrollbar.
	> Tom Dickey:
	+ rename spawn() to vl_spawn(), since QNX has a conflicting symbol.
	  Doing this makes shell and pipe commands work for QNX.
	+ amend change made in 9.4za to check if the compiler can support
	  the -U/-D combination.
	+ fix sign-extension problem in ldelete() caused by B_COUNT change
	  in 9.4u (report/analysis by Clark Morgan).
	+ remove a chunk in tcap.c which assumed that all xterms implement
	  scrolling.  Since the test-variable could be set when the terminal
	  implements xterm-mouse (termcap Km or terminfo kmous), then this
	  could cause misbehavior.
	+ fix an ifdef for O_NDELAY in termio.c that broke BeOS build in 9.3e
	+ amend test for struct dirent64 to ensure it is used only when it is
	  part of the prototype for readdir().
	+ apply change used in 9.4x for built-in filters to fix redefinition
	  to use this in loadable and external filters.
	+ compiler-warning fixes for various platforms.

 20050710 (za)
	> Peter Prymmer:
	+ fixes for building on VMS
	> Tom Dickey:
	+ suppress a check for VMS from changes to quickreadf() in 9.4u which
	  made vile unable to read VFC files.
	+ improve configure checks for _XOPEN_SOURCE and _POSIX_C_SOURCE by
	  not adding a -U option to cancel conflicting -D's, but by stripping
	  the conflicting option from $CFLAGS and $CPPFLAGS.  This addresses
	  compilers that do not process options left-to-right (report by Urs
	  Jansen).
	+ update list of warning options for Intel C compiler for 9.0 running
	  on 64-bit platform.
	+ modify configure script to allow it to define _GNU_SOURCE for Intel
	  compiler (report by Urs Jansen).
	+ deprecate TYPECAST() macro by using it only for gcc
	+ add ".asp" to jspmode suffixes

 20050626 (z)
	> Tom Dickey:
	+ add ".dcl" filetype for dclmode.
	+ add ".cls" filetype for vbmode, add symbols for Visual Basic class
	  modules to vb.key
	+ fix to ntwinio.c change from 9.4y which broke parsing of multiple
	  filenames on the command-line.

 20050618 (y)
	> Tom Dickey:
	+ revert 9.4p change to vilefilt.l
	+ add ".mm" to nroff mode.
	+ modify ShowFormatted macro to support "-mm" macros.
	+ modify dequoting of winvile's command-line in ntwinio.c to allow for
	  quoting to be within parameters, e.g.,
	  	winvile +"100" makefile
	+ fix a pointer for tgetstr() result which was not initialized for the
	  termcap driver.  The corresponding terminfo call does not use the
	  pointer (since 9.3d).

 20050612 (x)
	> Tom Dickey:
	+ fix a problem with curses driver where doing
		:r !date
	  would result in garbage screen display.
	+ workaround for redefinition via includes generated by flex before
	  filters.h was included, by prepending that include to flex's output.

 20050608 (w)
	> Tom Dickey:
	+ eliminate some strlen() calls to improve performance by caching the
	  record separator value and its length in BUFFER.
	+ fix inconsistent use of dummy value for DIRECTIVE in filterio.c
	  (report by Clark Morgan).
	+ change TILDE to CH_TILDE to avoid symbol conflict on AIX.
	+ improve largefile support by ensuring that _LARGE_FILES and/or
	  _LARGEFILE_SOURCE are defined before including any header file.

 20050530 (v)
	> Tom Dickey:
	+ add reader-policy mode, which allows one to control whether vile will
	  fall-back to slowreadf() if it encounters an error.  The case where
	  quickreadf() would fail that slowreadf() might succeed is for reading
	  a very large file when memory was also fragmented.  But using
	  slowreadf() would (besides being much slower), also use even more
	  memory in this case, making it unlikely that it would succeed in any
	  case (discussion with Dave Kristol).
	+ fixes to build clean(er) with Intel compiler:
	  + adjust ifdef's for fallback prototype for open() in case it is
	    really open64().
	  + add a "%u" format type to dofmt(), use it to display file-sizes.
	  + define DIRENT to struct dirent64 for the case where
	    _FILE_OFFSET_BITS is 64 and _LP64 is not defined.  Use a configure
	    script check to ensure the type exists.
	  + add/use function bpadc() to replace "%P" and "%Q" formats in
	    dofmt().
	  + add/use function format_int() to replace "%r" format in dofmt().
	+ modify name-completion to allow completion of filenames containing
	  a '$':
	  + modify shell_complete() to only try to expand $variables if the
	    '$' is not escaped.
	  + modify glob's expansion of $variables to ignore a trailing '$' or a
	    '$' not followed by a name-character, as well as a '$' preceded by
	    a backslash.
	  + split string_has_wildcards() into two parts; the new part (called
	    from the old) string_has_globs() checks only for wildcards that are
	    processed after expanding tilde and environment variables.
	  + escape backslashes and $'s in expand_wild_args() to account for the
	    checks for backslashes added in this change.
	+ restore default search for buffer by number omitted in changes to
	  use for-buffer mode, e.g., ":ki 1".

 20050522 (u)
	> Paul Fox:
	+ relax a check in ":w" by checking if the given name differs from
	  the current filename.  If so, do not require ":w!" to write a
	  readonly file to a different location.  This allows one to reuse
	  the filename history for ":w".
	> Tom Dickey:
	+ add mode for-buffers, which specifies whether kill-buffer (and
	  for-buffers) command use globbing or regular expressions (request
	  by Clark Morgan).
	+ fix ifdef's in filters.h to allow configuring --with-no-leaks when
	  no built-in filters are used.
	+ add configure script option for largefile support.
	+ modify computed percentages in ruler and ^G command to avoid overflow
	  (report by Dave Kristol)
	+ modify interfaces of ffread() and ffsize() to allow results to be
	  returned as ULONG.
	+ change B_COUNT to an unsigned type (ULONG), to allow for reading
	  files larger than a signed value would allow (report by Dave
	  Kristol).
	+ add command for-buffers, which performs the same command for the
	  specified buffers.

 20050515 (t)
	> Tom Dickey:
	+ add --disable-imake option to configure script, from xterm.
	+ skip some unnecessary checks in configure script if imake is not
	  found.
	+ add ".ph" and ".pph" to esqlmode suffixes.
	+ add parsing in perl filter for range operator ".." (reported by
	  H C Dickey).
	+ correct definition of nmakemode, which left fence operations out
	  since they were assigned to makemode.
	+ add syntax filters for iss- and ini-modes.
	+ add iss-, nsis- and ini-modes
	+ improved the winvile.iss script, allowing installer to set system-
	  or user-environment variables, or to put the corresponding paths
	  in the system- or user-registry settings.
	+ correct parameters of "~local" in pictmode.rc, which omitted the
	  "%" designating local variables.

 20050324 (s)
	> Tom Dickey:
	+ improve rubyfilt.c
	  + check for token beginning here-document cannot begin with a digit.
	  + improve operator-parsing, use that to fix a case where "<<"
	    operator was confused with the beginning of a here-document.
	  + treat newline as a statement terminator (report by Paul van
	    Tilburg).
	+ correct a loop limit in on_double_click(), used by winvile.  Double
	  clicking on the first line of a file would (depending on content and
	  the build configuration) set the beginning of the region before the
	  line.
	+ add VILE_HELP_FILE to the list of environment variables managed by the
	  Inno Setup script.
	+ fix a missing include for w32vile.h needed to compile filters on
	  win32 (also reported by Larry Gensch).
	+ correct extent of highlighting in update_line_attrs() when number
	  mode is active.

 20050313 (r)
	> Tom Dickey:
	+ modify environment variable lookup for win32 to look in the registry
	  for the VILE* environment variables:
		VILEINIT
		VILE_HELP_FILE
		VILE_LIBDIR_PATH
		VILE_STARTUP_PATH
		VILE_ERROR_ABORT
	  This change is made to make it more easily installable; Windows
	  changes to environment variables apparently do not take effect until
	  the machine is rebooted.  Registry changes take effect immediately.
	+ improve checks for _XOPEN_SOURCE, _POSIX_C_SOURCE in configure script.
	+ improve sql-filt.l's parsing of SQL*PLUS
	+ modify spellflt.l to allow it to be used in winvile, using npopen,
	  etc.
	+ add package script for winvile using Inno Setup.
	+ rename PATCHLEVEL to VILE_PATCHLEVEL to avoid conflict with Perl's
	  symbol.
	+ move the version definition from edef.h to patchlev.h to reduce the
	  number of places to change.
	+ modify manpage.rc to check if txtmode exists before attempting to use
	  it.
	+ add parsing in rubyfilt.c for %x, like %Q.  Change parsing for
	  backtic to match %x (report by Paul van Tilburg).
	+ correct quoting for here-document beginning in rb-filt.l (report by
	  Paul van Tilburg).
	+ modify interpretation of ~local, ~with, ~elsewith and ~endwith so
	  they are within the normal ~if/~endif hierarchy.  This makes the
	  9.4q change for SpellFilter work as intended.
	+ fixes for tbuff.c to ensure TBUFF is updated properly when cancelling
	  a macro prompt, e.g., with ESC (report by Paul Fox).
	+ add configure check for popen(), use corresponding ifdef's to enable
	  console version of vile-spell-filt.exe on win32.

 20050213 (q)
	> Tom Dickey:
	+ several improvements to rubyfilt.c:
	  + show variable-expansion within generalized double-quote %Q.
	  + implement [] ranges in regular expressions.
	  + fix handling of escaped characters, which were not always ignored.
	  + correct logic for regular expression options, which used the wrong
	    location (noticeable if there was a newline nearby).
	  + add check to distinguish '/' operator from regular expression.
	  + add parsing for alias statements.
	  + add parsing for def statements.
	  + add parsing for class definitions to avoid conflict with
	    here-documents.
	  + add parsing for "$1" and similar symbols
	  + add parsing for "1.upto(n)" and similar operators applied to
	    constants.
	+ add vbsmode using ".vbs" suffix based on basmode.
	+ fix two issues related to rbmode (Debian #292652):
	  + correct order in flt_lookup(), which tested filtername value after
	    checking against built-in modes.  Since rbmode should use
	    vile-ruby-filt, that caused it to use vile-rb-filt instead.
	  + rb-filt.l (vile-rb-filt) had a "?" in the expression which begins
	    here-document that applied to the "<<-" string.  It should have
	    applied to optional whitespace after that.
	  With the combination of the two, files containing a quoted name were
	  treated as a here-document.  This bug was exposed by a difference in
	  order of evaluation that came from quoting the "<<-" to work with an
	  old version of flex.
	+ change highlighting for misspelled words to Error class.
	+ remove "-x" option from fallback definition of SPELL_PIPE, since that
	  is only useful if ispell happened to be installed as "spell".  For
	  Solaris, "-x" means something entirely different.
	+ add environment variable VILE_SPELL_FILT to vile-spell-filt, to allow
	  overriding the compiled-in program and options used for performing
	  the lookup.
	+ move ~local declaration for SpellFilter inside ~if statement where
	  they are used; otherwise using external filter does not work.
	+ add limit-check for kcod2escape_seq().
	+ correct mode-filename for vilemode, which needs an optional "." to
	  match ".vilerc".
	+ correct sql-filt.l, which did not restore default symbol table after
	  processing an token with the sqlplus symbol table.

 20050202 (p)
	> Clark Morgan:
	+ make ":w! cygwin_rdonly_ntfs-based_file" work.  Tested as follows:
	     win98 -- fat32
	     win2k -- fat32 and ntfs
	     winxp -- fat32 and ntfs (with administrator privs and no privs)
	+ when selecting text, show I-beam cursor (winvile only).
	+ when selecting a movable mode line, show a double-headed, north-south
	  cursor (winvile only).
	+ when moving the mouse over a movable mode line, show a double-headed,
	  north-south cursor (winvile only).
	+ don't allow mouse capture if LMB is pressed in the area encompassing
	  the editor's last two lines (message line and nonmovable mode line).
	  Don't allow mouse capture if LMB is pressed on movable mode line.
	  Corrects long-standing winvile bugs.
	+ add graphical CD to [win]vile via new command "wincd".  The graphical
	  CD is also accessible via winvile's system menu and right mouse popup
	  menu.
	+ ensure that files created via winvile's "Save As" and vile's ":f"
	  commands are remembered in winvile's "Recent Files" list.
	+ winvile uses status return of edit_recent_file()/cd_recent_folder()
	  as negated argument to update(), which subsequently moves cursor out
	  of message line if either function reports an error.
	General comments:
	- the editor's bottom mode line is not movable.
	- I tried making similar cursor shape changes for console vile (when
	  LMB is clicked) but Windows XP would not allow the vile process to
	  change the cursor of the parent window, as returned by
	  GetForegroundWindow().
	> Tom Dickey:
	+ correct state-switching in sh-filt.l for backtic's; it was not
	  flushing the buffer used to build up quoted text (since 9.3e).
	+ add a null-pointer check in write_states() of lex-filt.l which did
	  not appear to be needed (since 9.3q).
	+ ".jsp" files are really (close to) a variety of HTML files.  Add
	  simple support for JSP in htmlfilt.l
	+ fix pl.filt.c to check for arrows inside parenthesis, e.g.,
		if ($a->y != $b->y) {return $a->y <=> $b->y}
	+ modify vilefilt.l to disallow escaped single-quote in single-quoted
	  strings, and to flag unterminated strings as an error.
	+ modify tb_enquote() and tb_dequote(), eliminating feature that
	  allowed single-quotes to be escaped in a single-quoted string.  That
	  led to inconsistent results when a string contained a trailing
	  backslash.  Noticed this when using shifts.rc on an X app-defaults
	  file, this also appears to fix a related report by Clark Morgan.
	+ correct mode-filename for RCSmode from 9.4o changes.
	+ review/update some beginDisplay/endofDisplay checks, making these
	  use assert's whenever tracing is compiled-in.
	+ add check in vl_restore_modes() to ensure that it does nothing if
	  vl_save_modes() was not called.  For some platforms, that would cause
	  screen or script to die if the output of "vile -V" were redirected.

 20050124 (o)
	> Tom Dickey:
	+ correct change to tb_error() which freed data buffer without also
	  resetting the corresponding size recorded for the buffer.

 20050124 (n)
	> Clark Morgan:
	+ remove deprecated SHGetMalloc() from w32oo.cpp, tested on WinXP, 2K,
	  98.
	+ fix a case where spawned winvile console would sometimes be missing
	  error message.  For example, if winvile is invoked from a cygwin
	  shell command line and a command is spawned like so:
		:!command_that_generates_error
	  Then _no_ error text appeared in the spawned console window.
		:!mkdir name_of_existing_dir
	  Tested on win2K, xp, win98.
	+ several changes to allow winvile to remember recent files and folders
	  + winvile remembers up to 20 of the files it has recently
	    opened/created (feature disabled by default).
	  + winvile remembers up to 20 of the folders it has recently visited
	    via an implicit or explicit cd (feature disabled by default).
	  + Remembered files/folders are accessible and "replayable" from
	    winvile's system menu.
	  + Two new modes:  recent-folders and recent-files specify maximum
	    number of folders/files that may appear in winvile's system menu.
	    Range is 0-20; a value of 0 disables feature.  (U)
	  + Two new commands:  purge-recent-folders and purge-recent-files
	    clear the list of folders/files that appear in winvile's system
	    menu.
	  + modes and commands work in console mode (minimizes conflicts when
	    sharing a single vile.rc), but the files/folders that console vile
	    accesses are _not_ remembered.
	  + tested on win98, win2k, XP.  Changes test-compiled on linux.
	  + tested with multiple users on XP, as well as in the context of an
	    unprivileged user.
	+ improve the winvile resize/status window:
	  + make resize window wide enough to show geometries that exceed 99
	    columns
	  + make resize window continually center itself over the editor's
	    frame (NT and XP only).
	  + Tested on a variety of screen geometries on NT and XP using both
	    large and small fonts. Cross-checked on win98.
	+ amend oleauto.doc to tell how to make wvwrap work with XP service
	  pack 2.
	+ update vile.hlp to describe new modes.rc file.
	> Tom Dickey:
	+ review/correct places where result of malloc is not checked for null.
	  Test using small memory limit (addresses report by Emil Rojas for
	  processing very large tags files, and earlier report by George
	  Eccles).
	+ change gutter width for line-numbers from 2 to 1.
	+ work around for Borland C++ 5.5 to ignore EPIPE on an end-of-file.
	+ work around in mlwarn() to report system errors with Borland C++ 5.5,
	  whose strerror() values have trailing newlines.
	+ indent'd btree.c
	+ change return-value of readin() to false if the given filename is
	  empty (report by Clark Morgan).
	+ ensure that all mode-filename values are anchored to avoid confusing
	  them with piped commands.
	+ modify diffmode to use pipe output as a mode-filename value, and
	  modify mode inference to allow this special case.  Pipe output is
	  not checked for suffixes, since its filename value may contain
	  many filenames.

 20041215 (m)
	> Tom Dickey:
	+ modify x11.c, ntconio.c and ntwinio.c to make modifiers work with tab
	  key, e.g., to add shift-key as a back-tab key.
	+ add macro show-each-buffer (file showeach.rc), which splits up the
	  screen into equal chunks to display as many of the non-scratch
	  buffers as possible.
	+ modify macro parameter evaluation so it does not attempt to compute
	  a value for function tokens or goto-labels.  Otherwise pathnames such
	  as "~\foo" look like macro directives and produce an error.
	+ correct slash/backslash translation (win32, etc) for some of the
	  built-in functions; the translated result was not actually the return
	  value:  &path and &pcat.
	+ correct flags in modetbl used to annotate trace of &seq and a few
	  other operators.
	+ correct length computed for $bflags variable; an empty string was
	  returned.
	+ add a section on command-line options to doc/filters.doc
	+ add macro which-filter to show which locations would be checked for
	  an external filter.  If the filter happens to be built-in, this is
	  also noted, in the message line.
	+ improve 'eval' command, provide for mixture of functions and other
	  tokens which are passed to the script interpreter.
	+ modify SpellFilter macro to use the results from [Filter Messages]
	  with the error-finder to step through the misspellings.
	+ add macro show-filtermsgs to show syntax filter messages, setting the
	  list to the error-buffer to provide simple stepping through the
	  errors which are found.
	+ add commands popup-buffer and popdown-buffer, which open/close
	  windows for the given buffer rather than changing the current window
	  to show a different buffer.  The popup-buffer command is a wrapper
	  for the existing logic used for help and similar commands.  The
	  popdown-buffer command differs from delete-window by closing all
	  windows for the given buffer.
	+ remove the pre-9.4e workarounds for set-highlighting and
	  which-keywords macros.
	+ modify kdb_reply() to shift the minibuffer left/right as needed after
	  doing the initial tab of a name-completion, in case that left the
	  cursor position past the end of the line (report by Paul Fox).
	+ add new operators to make it simpler for macros to check for
	  features: &isa, &classof and &mclass.
	+ modify historical-buffer to allow tab/back-tab to cycle through the
	  first 9 buffers, solves the problem of seeing more than the first
	  few possibilities on the message line.  Toggling with the repeated
	  '_' selects the first buffer shown.
	+ add back-tab to termcap/terminfo driver as a bindable key.
	+ modify configure script to make builtflt.h part of $(BUILTHDRS) to
	  simplify "make sources" rule.
	+ modify htmlfilt.l to match  in the middle of a line to
	  accommodate pages where the script is given by a "src=".
	+ add filtermsgs mode, for built-in filters to report syntax errors
	  into [Filter Messages] buffer so that one may use the error finder to
	  locate these (motivated by a 200,000 line xml file).
	+ correct state manipulation in xml-filt.l, which was confused by
	  CDATA pattern.
	+ correct $CPPFLAGS for linting configurations with built-in filters.
	+ correct typo in configure script from 9.4k fixes for iconv_open().

 20041207 (l)
	> Clark Morgan:
	+ modify special treatment of "#" which prevents it from being shifted
	  with ">>" by disabling that when cindent is unset.
	+ reenable SHIFT+INSERT in the win32 mini-buffer (for both vile.exe and
	  winvile.exe).  Unfortunately, the cygwin shell eats SHIFT+INSERT for
	  console vile (mini-buffer input only), but I don't think I can do
	  much about that.  So, now, it's once again possible to:
		$ vile somefile
		/     <- search for string sitting on clipboard
	> Tom Dickey:
	+ correct computation for 0-based versus 1-based column/line values in
	  the error-finder; the values were computed but not saved in the
	  compiled error expression's state.
	+ improve complex fences for adamode.
	+ add ".termcap" and ".terminfo" suffixes for respective majormodes.
	+ add ".jad" suffix for javamode for Java Disassembler.
	+ add a few ex-commands: nu, j!, wq!
	+ change kbd_reply() to check if the current value is the ERROR token,
	  and to clear it in that case.  This fixes a bug which would show the
	  trailing null (since the computed length for ERROR ignores the TBUFF
	  length), e.g.,
	  	setv $title=ERROR\^@
	+ modify statevars.c to make read/write of $title consistent, i.e.,
	  will warn that it cannot be set in the termcap configuration.
	+ correct logic for changing the xterm-mouse via the termcap driver.
	  It was not opening or closing the keyboard, not both, which would
	  leave xterm switched from the alternate screen.
	+ modify [Messages] buffer so that it is only invisible, not a scratch
	  buffer.  The latter makes it be automatically removed after viewing
	  and closing the window.
	+ fix search scanner to know about left-margin property.
	+ review/repair logic for OPT_CACHE_VCOL in dot_to_vcol(), in
	  particular making it work properly with [Registers] and similar
	  buffers having a left-margin property (reported by Paul Fox).
	+ fixes to build with Intel 8.0 compiler on Linux:
	  + add check for _XOPEN_SOURCE, _POSIX_C_SOURCE in configure script.
	  + add macros DECL_EXTERN_CONST() and DECL_EXTERN().
	  + turn off its so-called default gcc-compatibility and set compiler
	    warnings specially.
	+ fixes to build with Borland C++BuilderX 1.0.  It requires a rename
	  of regexec/regcomp to avoid calling like-named functions in a DLL.
	+ fixes to build with lcc-win32 (though its makefile-generator is
	  limited and requires one to edit the makefile).
	+ correct configure script macro CF_FUNC_ICONV so the script does not
	  exit with an error if the system does not happen to have iconv.
	+ some fixes to compile filters with Tru64 4.0g's lex/flex:
	  + ensure angle brackets in patterns are quoted
	  + put whitespace between command/value in options such as "%o3000".
	+ add pattern for "ant" (Java make-program) to a few of the patterns
	  in finderr.c
	+ modify ".table" command in filters parsing to read the user's color
	  definitions, e.g., from .vile.keywords, as is done in a ".source"
	  command.
	+ add a ".brief" to filters parsing, which uses "?" to match zero or
	  all of the following characters, in contrast to ".abbrev" which uses
	  "*" to match zero or more of the following characters.
	+ modify sql-filt.l to distinguish between SQL*PLUS and SQL, PL/SQL.
	  The latter delimit statements with semicolons, while the former makes
	  that optional, using newlines.
	+ modify call on insert_keyword() to use the given name, e.g., a class
	  rather than its attribute.  This fixes a bug exposed in sql-filt.l
	  by changing sql.key to use ".default" to simplify it.
	+ add check for setlocale() returning null.

 20041107 (k)
	> Tom Dickey:
	+ modify glob_match_leaf() to work with 8-bit characters.
	+ correct loop in glob_match_leaf(), which did not handle strings such
	  as "[!strings xyz-]".
	+ correct expression in filters.rc for %filters-modes (report by
	  Duncan Sargeant).
	+ fix conflict between DECWindows Motif/Xt libraries and the non-Motif
	  Xt library in vmsbuild.com
	+ make xvile compile properly on VMS by defining XTSTRINGDEFINES.
	+ modify catnap() function to use IEEE floating point on IA64, since
	  that platform does not support F-floats.
	+ modify vmsbuild.com and descrip.mms to work with IA64.
	+ add $goal-column variable for debugging.
	+ fix quoting and parameter list for iconv_open() in configure macro
	  CF_ICONV_FUNC.

 20041031 (j)
	> Clark Morgan:
	+ add "explicit" and "typename" to cpp.key
	+ correct parameter lists for chgd_icursor() and chgd_popupmenu()
	  in ntconio.c and ntwinio.c which were not updated in 9.4b, which
	  added a BUFFER* parameter.
	> Tom Dickey:
	+ add parameter to hst_append() to control logic which is used to build
	  up shell commands for replay.  Use this parameter to suppress shell
	  command construction when prompting for regular expressions and other
	  strings that cannot be shell commands (report by Daniel L Ashbrook).
	+ save/restore MK in kbd_reply() to work around lost value of MK when
	  swbuffer() is called as a side-effect of name-completion.  This
	  caused commands such as
	  	!Gls /tmp/
	  to report a "BUG: no mark" (report by Daniel L Ashbrook).
	+ modify PromptAndSet() to allow a cancelled prompt for variable's
	  value to store an ERROR token, which can be tested in scripts with
	  &error (request by Clark Morgan).
	+ modify filters.rc, modes.rc and vileinit.rc as follows (reports by
	  Clark Morgan and J Chris Coppick):
	  + filters.rc turns on automatic syntax highlighting only if both
	    builtin-filters and colors are available.  Before 9.4i, vileinit.rc
	    turned on automatic syntax highlighting.
	    NOTE: if you are using external syntax filters, vileinit.rc no
	    longer automatically enables highlighting for this case.  The
	    builtin or loadable filters perform better for most systems.
	  + add a variable %filters-modes, set in modes.rc to be tested by
	    filters.rc to ensure that modes.rc is source'd if needed.  Both of
	    these files are sourced by vileinit.rc in 9.4i, but not everyone
	    uses vileinit.rc
	  + update vile.hlp to reflect these changes.
	+ ensure values for $bchars and $blines are up-to-date, e.g., if
	  which-keywords is called twice in succession in the same macro the
	  values were not, causing the [Which Keywords] content to be repeated.
	+ indent'd vmsvt.c, vms2unix.c
	+ add VMS mode record-attrs, modify logic in vms_creat() to use this
	  information to make the default VFC files written from DCL editable.
	  Those use PRN (print file format) record attributes (report by
	  Jordan Henderson).
	+ modify terminal settings for VMS to improve type-ahead.
	+ add xterm-style bindings for F1-F5 to vmsvt.c
	+ modify which.rc to use &pcat rather than $pathname-separator, since
	  the latter is ambiguous on VMS.
	+ modify infer_majormode() to work with VMS pathnames.
	+ correct logic for VMS pathnames so that a directory buffer will,
	  as on Unix, give the same buffer name as the directory leaf.
	+ improve fakevms test-driver and related OPT_VMS_PATH code for VMS
	  pathnames, making name-completion work for VMS pathnames on Unix.
	+ fix a memory leak in old_namebst().
	+ modify tb_bappend() to avoid memcpy() with the same source/target
	  address (valgrind warning).
	+ add/use CAN_TRACE symbol to allow configure --with-no-leaks, since
	  the unfilter program otherwise fails to link in that configuration.
	+ add some discussion of character classes to vile.hlp
	+ fixes for vile-9.4.spec, adds vile-pager to list of installed files
	  and installs manpage in the normal man-directory (patch by Radek
	  Liboska).
	+ add configure option --with-iconv, use that to extend termcap driver
	  to allow it to handle encodings other than Latin-1, e.g., Latin-2
	  (request by Radek Liboska).
	+ extend workaround for UTF-8 locale in termcap driver to translate
	  UTF-8 input to Latin-1.
	+ improve/extend checks for locales which correspond to 8-bit character
	  encoding, resetting to POSIX locale (ASCII) if the nl_langinfo()
	  function returns a value that does not look like ASCII or ISO-8859-x.
	  This change applies to the termcap/terminfo and X11 drivers.
	+ show locale and encoding values in header of [Printable Chars].
	+ add $encoding and $locale variables to show what vile's internal
	  8-bit encoding and locale are set to.
	+ turn on locale feature on win32
	+ workaround for broken locale table on Solaris8 and Windows2000, etc.,
	  which shows tab as both as printable and a control character.  The
	  ISO C standard states that control characters are not printable.
	+ add nmakemode, for special cases such as M$'s ".dsp" files.
	+ add syntax filter for AutoIt version 3 and majormode au3mode.
	+ correct pattern for HEX in bas-filt.l

 20040808 (i)
	> Mark Robinson:
	+ split-out modes.rc from filters.rc to make configuration more
	  flexible, e.g., for --disable-filters.
	> Tom Dickey:
	+ add named operators (eq, ge, gt, le, lt, ne, or, and, cmp, not, xor)
	  to perl syntax highlighter check for tokens that may precede a
	  pattern (report by Daniel L Ashbrook).
	+ fix escaping within strings for tcmode; it was looking only for ":"
	  or newline, but any character could be escaped.
	+ fix highlighting of aliases without description in tcmode and timode.
	+ add ".tic" as a suffix for timode.

 20040620 (h)
	> Tom Dickey:
	+ correct which-keywords to work with 9.4e change that appends "mode"
	  to majormode parameters of procedures.
	+ rename utility macro which-filename to WhichFilename, to avoid
	  conflict with which-filter.
	+ add/use tb_setlen() in run_func() to update the lengths of TBUFF's
	  which are built by unusual methods, e.g., allocating a large TBUFF
	  and using lengthen_path() to rewrite its contents.  This was not
	  a noticeable problem until run_func() called tb_enquote(), which
	  assumed the TBUFF length was correct.
	+ modify FindMode() in perl.xs to dequote results from evaluating
	  a function, since 9.4f changes cause string results of functions to
	  always be quoted.

 20040617 (g)
	> Clark Morgan:
	+ modify manpage.rc and color-ls.rc to avoid showing their guts if
	  aborted.
	+ vile.hlp changes:
	  + add discussion of mode-pathname and mode-filename to the section
	    on Majormodes.
	  + add notes about optimizing suffixes for C versus C++ editing.
	> Fabien Coutant:
	+ add experimental plugin support and example.
	> Tom Dickey:
	+ indent'd ansi.c
	+ configure-script fixes:
	  + change prerequisite to autoconf 2.13.20030927 patch, mainly for
	    OS/2 EMX. Other systems use the 2.52-generated configure script.
	  + modify --with-Xaw3d, --with-neXtaw and --with-XawPlus options to
	    avoid being confused by options such as --without-Xaw3d.
	  + several fixes to accommodate quoted string definitions introduced
	    in some imake configurations, which did not work with the
	    CF_ADD_CFLAGS macro's parsing.
	  + modify CF_X_TOOLKIT to remove the checks for clix (obsolete) and
	    move the call to AC_PATH_XTRA to the beginning - which it
	    essentially was anyway.  Now it simply calls AC_PATH_XTRA and
	    ensures that I can get -lXt and -lX11.  Reading the code, it seems
	    that the IRIX6/IRIX5 issue was taken care of in autoconf 2.13.
	  + modify CF_NCURSES_LIBS to only look for -lmytinfo when building
	    with ncurses.  This works around FreeBSD's broken linker semantics
	    when configuring for ncursesw.
	+ add $error-tabstop variable, to allow changing the tabstop value
	  used when interpreting %C results in the error finder.  Most programs
	  assume 8, and that does not work well when editing buffers with other
	  tabstops such as 4.
	+ correct perl highlighting of subscripts which happen to be the same
	  as quote-operator names, e.g.,
		$foo{y}
	  (report by Daniel L Ashbrook).
	+ correct perl highlighting of variables within double quotes, ignoring
	  single-quotes which may happen to follow, e.g.,
		"foo = '$foo'"
	  (report by Daniel L Ashbrook).
	+ correct logic in vl_lookup_func(), which did not allow match on
	  ">", since that appeared to conflict with ">seq" (report by
	  Clark Morgan).
	+ change TPRINTF() macro so that if debugging trace is turned on, the
	  same text that would be written to [Trace] is also written to the
	  Trace.out file.
	+ modify dofmt() to handle "%*.*s" and "%.*s" formats, removed "%*S"
	  format.
	+ replace doc/indent.pro with ncu-indent, a script which allows preview
	  of the indent changes.  Note that preview relies on bug-fixes which
	  are not in "official" indent.  See the indent section in
		http://invisible-island.net/gnu-patches/gnu-patches.html
	+ modify needQuotes() to return true only if both conditions apply
	  (the token needs quoting and it is not the first token) rather than either.
	  This makes [History] show things like
		set tags=foo
		set tags="foo bar"
	  rather than
		set "tags"="foo"
		set "tags"="foo bar"
	+ revise quoting of strings returned by run_func(), using new
	  functions tb_enquote() and tb_dequote(). This fixes case such as
		set tags=''
		write-message &cat "tags: " $tags
	  which lost one of the single-quotes when the "set" command was
	  interactive (report by Clark Morgan).
	+ modify cppmode's suffixes to look for .C, .H and .CC only on systems
	  where filenames are case-sensitive.
	+ call attrib_matches() at the end of attribute_directly() to restore
	  highlighting due to visual-matches.  This fixes a bug where autocolor
	  might wipe that highlighting away (report by Clark Morgan).
	+ modify pattern for logmode to allow filenames such as gmake.out
	+ modify latexflt.l to not color "|" in TEXT state.
	+ add map's for newer XFree86 xterm shifted cursor-keys (see
	+ improve label-expression in dcl-filt.l
	+ modify dcl-filt.l to recognize $DECK / $EOD literal lines.
	+ modify c-filt.c to recognize Java double suffix, e.g., 1.0e1d
	+ revise/extend js.key based on ECMA-262 and other online information.
	+ add a mode-pathname setting for cppmode, so files under (for example)
	  /usr/include/g++ will be treated as C++.  Newer C++ headers have
	  no suffixes.
	+ add ".hpp" to suffixes for cppmode.
	+ add ".el" to suffixes for lispmode.
	+ add an "-s" option to c-filt.c, for JavaScript (to support jsmode).
	  Use this to control whether to allow regular expressions in certain
	  cases.

 20040411 (f)
	> Clark Morgan:
	+ modify vilemode, adding "sections" expression.
	+ vile.hlp changes:
	  + modify syntax coloring topic to remove prerequisites that refer to
	    features from long, long ago ("nocmode" and old copies of c syntax
	    coloring files) that most users won't remember or encounter.
	  + revamped "Editor modes" section, in particular, moving discussion
	    of majormodes to a point in the help file that directly follows
	    syntax coloring.
	  + added mode flavor tags (B, U, W, M) to modes that lacked same.
	  + documented that "suffixes" is tested against a filename's complete
	    path.
	  + stripped c-tabstop from vile startup example.
	  + explicitly emphasized ignoresuffix's behavior.
	  + for cindent, tabstop and shiftwidth modes, documented cmode's
	    default local mode values.
	  + added a "Majormodes" section. Added a subsection entitled
	    "cmode: the original vile builtin majormode"
	> Tom Dickey:
	+ indent'd csrch.c, globals.c, map.c, wordmov.c
	+ modify logic for RS_AUTO to treat it consistently as the "default"
	  keyword for record separator (report by Clark Morgan).
	+ remove an unnecessary message from makelist.sh (report by Clark
	  Morgan).
	+ modify mac_tokval() to avoid calling tb_scopy() if the result from
	  tokval() is the original pointer plus one (for stripping a leading
	  quote), fixes an overlapping memcpy warning from valgrind.
	+ correct logic in test_by_suffix(), which was not obtaining the
	  submode value for "ignoresuffix" as intended (discussion with Clark
	  Morgan).
	+ modify comparison for maplength to use at least 25.  Very small
	  values make vile unusable (report by Clark Morgan).
	+ revert part of the initialization in substreg1() so the replacement
	  pattern is reset rather than copied (report by Brendan O'Dea, 9.3n).
	+ make "TODO" a txtmode file.
	+ add ".shar" to shmode suffixes.
	+ add "&match" and "&cmatch" functions for checking if a given regular
	  expression matches a string (request by Clark Morgan).
	+ split up the majormode "suffixes" into suffixes, mode-filename and
	  mode-pathname to make it clearer how to associated regular
	  expressions with the filename for majormodes (discussion with Clark
	  Morgan).
	+ remove explicit assignment to DESTDIR in makefile.in's, since newer
	  GNU make program does not allow command-line to override it (it
	  apparently did work with some version of GNU make in 1999 for 8.3i).
	+ correct logic in perl.xs from 9.4d which parses $VILE_LIBDIR_PATH;
	  it used the wrong variable for storing an intermediate result.

 20040321 (e)
	> Clark Morgan:
	+ document set-highlighting macro in vile.hlp
	+ update/revise some details in doc/modes.doc relating to cmode:
	  + remove any mention of "set cmode" as a (presently) useful command.
	  + list "setl [no]{majormode}" as essential majormode features [as
	    near as I can tell, "setl {majormode}" is the only mechanism
	    available for a user to explicitly attach a majormode to a buffer]
	  + update the history of majormodes to reflect the way things were in
	    the past, but not now.  This is done primarily by changing the
	    grammatical tense of various sentences.
	> Tom Dickey:
	+ add mode "ignoresuffix", which tells vile to strip the given pattern
	  from a filename before matching majormode suffixes against it.
	+ add mode "showchar", which turns on a field in the modeline that
	  tells what the character value is at the current editing position.
	+ modify pregion() to reset the "counted" state on the buffer, to work
	  around a case on win32, where CRLF_LINES is set, the "p" command's
	  output did not count the extra byte per line for ^M's.  When saving
	  [p-lines] to a file, it was truncated.
	+ modify isMiniEdit() to always return true if miniedit mode is set.
	  That allows one to use ^Ga to toggle miniedit mode and append to
	  the buffer shown from a previous command rather than having it
	  erased (discussion with George Eccles).
	+ modify mac_tokval() to avoid calling tb_scopy() if the result from
	  tokval() is the original pointer, fixes an overlapping memcpy warning
	  from valgrind.
	+ fix incremental-search's initialization, broken in 9.3l (report by
	  Richard Mitchell).
	+ improve COMMENT expression in txt-filt.l to include the lines of
	  dashes in vile.hlp (report by Clark Morgan).
	+ fix to avoid putting dummy entries into the list of all modes when
	  a corresponding short modename does not exist for a given submode of
	  a majormode.  That was making ":set " show names such as
	  "RCSX" and "cppX".
	+ fix a couple of places reported by gcc -Wundef on OS/2, e.g., the
	  OPT_WORKING macro.
	+ modify htmlfilt.l to use caseless comparison for HTML keywords.
	+ improve configure-script checks for dbmalloc and dmalloc.
	+ modify preamble pattern for pymode to work with
		"#!/usr/bin/python2.3 -S"
	+ modified [a-z] expression to [\a] in preamble for awkmode, cshmode,
	  sedmode, shmode, tclmode to allow uppercase options.
	+ add ".jsp" to jsmode suffixes.
	+ fix imake filter to handle a case where XCOMM comment contained a
	  colon; it was highlighted as if it were a makefile target.
	+ modify name-completion for majormode names used as macro parameters
	  to use the long name (with "mode" ending) rather than the short
	  name, for consistency (suggested by Clark Morgan).
	+ modify filters/*.awk to ensure that space-separated lists for the
	  --with-builtin-filters, etc., options are handled properly.  Both
	  comma-separated and space-separated lists are permitted now (report
	  by Clark Morgan).
	+ fix missing assignments from 9.4b changes to $builtins and $loadable
	  variables in configure script, which caused build to fail if explicit
	  list was given for --with-builtin-filters or --with-loadable-filters
	  (report by Clark Morgan).

 20031220 (d)
	> Tom Dickey:
	+ modify pl-filt.c to handle
		sub y { }
	  i.e., not treat the "y" as the beginning of a pattern.
	+ modify perl.xs to allow for $VILE_LIBDIR_PATH to be a list of paths.
	  Only add the corresponding xxx/perl names to @INC if they correspond
	  to a real directory.
	+ rewrote pascal syntax filter in lex, adding highlighting for numbers,
	  and TurboC, Delphi comments.
	+ improve pascal keywords.
	+ relax check for dlopen() by assuming that at least RTLD_LAZY is
	  defined.  This works for SunOS 4.1.4.
	+ add a check in de_extend_lines() for a null wp->w_line.l, recover
	  by resetting to the buffer-head (report by George Eccles).
	+ add some more debugging code, calls to valid_buffer(), valid_window()
	  and new functions valid_line_bp(), valid_line_wp().
	+ change minimum/maximum repeat counts for regular expressions from a
	  byte to an integer (report by George Eccles).
	+ modify "dist" rule in makefile.wnt to make it set the name of the
	  zip-file based on the executable.  Add a ".map" file to the zip file.

 20031105 (c)
	> Tom Dickey:
	+ improved check for dlsym to make loadable filters work on Solaris and
	  IRIX64 (tested with gcc).
	+ make "--disable-echo" apply to making the loadable filters.
	+ use EXEEXT and OBJEXT in generated makefiles.
	+ corrected parameter to lookup_filter(); it did not account for the
	  $filtername symbol, e.g., as used for cshmode to invoke vile-sh-filt.
	+ corrected ifdef's in cfgopts() used to build xvile's $cfgopts values.
	  The ifdef's used "#ifdef" rather than "#if", causing all possible
	  values to be shown (problem introduced in 9.3e).

 20031102 (b)
	> Brendan O'Dea:
	+ add code to support dynamic loading of syntax filters which are
	  compiled as a shared object.
	> Tom Dickey:
	+ modify is_ESCAPED() in pl-filt.c to not treat backslash before
	  double-quote specially.  This fixes man2html, which contains a line
		  *bs = \"\b";
	+ modify latexflt.l to recognize strings such as "\def$", which begin
	  a redefinition of "$".
	+ remove suffix conflict between latex and tex modes.
	+ modify check in set_vilemode() so that buffers other than the current
	  one can be set, provided that they are not scratch buffers.  A
	  change in 20030630 had suppressed set_vilemode() for buffers other
	  than the current one, from noting odd error messages when the current
	  buffer was [Buffer List], which is a scratch buffer and therefore
	  cannot have a majormode assigned to it.
	+ add "--with-loadable-filters" option to configure script and modified
	  related files to integrate Brendan O'Dea's patch for dynamic loading.
	  Timed filtering of vile's larger source-files to compare the three
	  schemes.  Loadable filters ran about 50% slower than the builtin
	  filters, while external filters ran about 5 times slower (ymmv).
	+ use AC_EXEEXT in configure script.
	+ modify configure script check for imake's $CFLAGS to ensure that
	  imake or xmkmf was found.

 20031008 (a)
	> Daniel L Ashbrook:
	+ add lispmode, to use vile-lisp-filt.
	> Mark Robinson:
	+ add cygwin to OPT_CASELESS
	+ modify xvile's wheelScrollAmount resource to scroll by pages if the
	  resource value is negative.
	> Tom Dickey:
	+ correct suffix pattern for xresmode, which did not match ".Xdefaults"
	  (see 9.2p).
	+ add macro "which-menu" to which.rc, which shows the locations that
	  xvile checks for a menu-file.
	+ revise lookup for xvile's menu file to look for dotnames in the
	  current and home-directories, while non-dotnames may be found there
	  and in $HOME/.vile and on $startup-path.  Combine this with changing
	  the default for $menu-file back to ".vilemenu" as documented rather
	  than "vilemenu.rc".  The latter name is used in the non-dotname
	  locations if $menu-file is a dot-name (report by Alf Pearce noted
	  that the default for $menu-file no longer matched the documented
	  ".vilemenu").
	+ change order of charinit() and global_val_init() so that mkupper()
	  works, e.g., for use in computing the value of $XVILE_MENU (report by
	  Alf Pearce  noted that the environment variable
	  did not work).
	+ improve lisp syntax highlighting (reports by Daniel L Ashbrook,
	  used the HyperSpec for reference):
	  + recognize "#|"..."|#" comments.
	  + revise patterns for numbers.
	  + allow decimal digits embedded in identifiers
	+ change makefile.djg to use zip rather than pkzip, and go32-v2.exe
	  rather than go32.exe
	+ improve configure check for , which may be .
	+ correct highlighting of sh construct
		${#variable}
	  (report by Michael Finken).

Changes for vile 9.4 (released Mon Aug 04 2003)

 20030727 (v)
	> Kevin Buettner, Paul Fox:
	+ fix include-path in filters/makefile.in to allow compiling with
	  separate src/build trees.
	> Tom Dickey:
	+ set regionshape to EXACT in editMiniBuffer() before executing
	  editing commands.
	+ review/fix several places where a negative value could be converted
	  to unsigned, or a zero value might be used as a malloc-size (report
	  by Paul Fox dealt with a negative length passed to tb_bappend).
	+ add "profile$" and "\.bash_[a-z]\+$" to shmode suffixes.
	+ modify print_usage() to exit with non-error status if only the usage
	  message was requested.

 20030708 (u)
	> Tom Dickey:
	+ modify parsing of here-document tags in sh-filt.l to allow '-', '<'
	  and '>' characters if the tag is quoted.  This is used in some recent
	  shar-files, e.g., cone.shar
	+ modify filters.h to allow HP's lex program to be used:
	  + put declarations for yylex() and yywrap() in gcc-specific ifdef
	  + add definition of YYCHAR_ARRAY to prevent redefinition of yytext[]
	    which caused failure to compile because HP's compiler refused to
	    compare char* and unsigned char* pointers.
	+ correct a missing dependency for neproto.h in descrip.mms

 20030630 (t)
	> Tom Dickey:
	+ add VMS to the OPT_CASELESS ifdef's, allowing majormodes to be
	  recognized.
	+ reorganized vmsbuild.com to allow the first parameter to be used as
	  a goto-target (which it was originally).  VMS DCL does not allow a
	  goto target to match when within an if-then-else block.
	+ restore selection-highlighting at the end of attribute-directly.
	+ add a check in update() to avoid calling newscreensize() when it
	  would not really be able to adjust the screensize.  Otherwise,
	  update's while-loop would not terminate.
	+ guard vtinit() against interrupt to ensure that a SIGWINCH does not
	  cause newscreensize() to recur into it.
	+ set "vilemode" for [History] buffer.
	+ modify vilefilt.l to highlight shell commands.
	+ fix an ifdef in main.c so valid_buffer() and valid_window() compile
	  with Visual C++.

 20030618 (s)
	> Tom Dickey:
	+ modify detach_attrib() to ensure that its parameter is still a valid
	  buffer pointer.
	+ add debug functions valid_buffer() and valid_window() and non-debug
	  macros to replace null-pointer checks on BUFFER* and WINDOW* pointers
	  with more extensive sanity checking.

 20030611 (r)
	> Tom Dickey:
	+ add a dummy entry to table in siginit() for VMS, which has no signal
	  handlers.
	+ correct a sign-extension problem with SAME() macro in regexp.c, which
	  made searches for upper-128 characters fail.

 20030526 (q)
	> Danny Zerkel:
	+ revert part of regexp.c changes in regmatch(), which caused pattern
		"^ *case"
	  to not match lines with more than one blank.
	> Paul Fox:
	+ modify ansi.c to get screensize from system.
	+ modify display.c to ensure default $modeline-format is interpreted
	  when building with SMALLER.
	> Tom Dickey:
	+ correct logic in hst_display(), which did not check for the case
	  where a shell command was being appended to an empty result.  The
	  code only checked if the result was not a shell command before
	  splitting the source into tokens.  This would happen for a sequence
	  of commands such as
		:!ls foo
		:!mv bar foo
		:e!
		:!
	  Then scrolling back through history would show only "!mv" and "!ls"
	  rather than the complete command.
	+ indent'd termio.c
	+ removed ifdef's for SYS_APOLLO.
	+ minor fix to imdying(), shows the list of files only if 'wrote' was
	  set, just in case none could be written.
	+ modify imdying() so email is always sent on a failure if
	  VILE_ERROR_ABORT is defined.  This helps distinguish accidentally
	  typing 'Q' versus a failure.
	+ modify ExitProgram() to reset fatal-error signals back to default,
	  so abort() will work properly, i.e., make a core dump.  Modify
	  imdying() so that if VILE_ERROR_ABORT is defined, ExitProgram()
	  is called rather than abort().  The latter calls abort() if the
	  environment variable $VILE_ERROR_ABORT is set.
	+ add cases for 'u', 'U', 'x' and 'X' to RegStrChr2(), making the
	  [:upper:] and [:xdigit:] regular expression character classes work.
	+ modify configure script to suppress -Winline if using gcc 3.3, since
	  that feature is broken.
	+ tested with gcc 3.3 and g++ 3.3, modifying several interfaces to use
	  'const'.  gcc 3.x also introduces more nonstandard name-pollution.
	+ add configure check/warning for flex 2.5.31, which has broken support
	  for the "-P" option used for built-in filters.
	+ reorder lex-based filters to allow building with flex 2.5.31, which
	  introduces several incompatibilities with respect to flex 2.5.4
	  and lex (report by Brendan O'Dea).
	+ add makefile rules to generate test-programs for btree.c, regexp.c

 20030510 (p)
	> Danny Zerkel:
	+ revert 9.3o change for pl-filt.c, since "!" should be allowed as
	  a pattern delimiter.
	+ add a limit check in pl-filt.c
	> Tom Dickey:
	+ modify manpage.rc to check if the current buffer is perl, and if so,
	  to render contents using pod2man or pod2text.
	+ several fixes for pl-filt.c, i.e., vile-perl-filt:
	  + check for a leading POD area, i.e., the first line is "=head",
	    with no preceding blank lines.
	  + allow floating-point numbers without a decimal point.
	  + add "@", ";", "=" to QUOTE_DELIMS
	  + add preprocessor keywords such as __END__ to perl.key
	  + check for __DATA__ keyword, which ends the script like __END__.
	  + add "grep", "unless", "until", "while" to the keywords which may
	    have a pattern following not in parenthesis.
	  + improve logic in is_QIDENT, testing for a quoted string in addition
	    to an identifier for here-document marker.
	  + check for identifier after "$#".
	  + check for typeglob, i.e, a "*" preceding an identifier, e.g,. "*x".
	  + add check in add_to_PATTERN() for nested parenthesis, e.g., when
	    parenthesis are the pattern delimiters.
	  + modify add_to_PATTERN() to accommodate multiple delimiters in a
	    substitute command, e.g., "s{a}(b)".
	  + check for pattern immediately after a left curly-brace.
	  + modify check for operators to allow "||", etc., not within
	    parentheses.
	  + make buffer-checks more readable with macros MORE() and ATLEAST().
	  + check for "..." in pattern, which makes a range of expressions.
	  + parse backtic expressions.
	  + parse file glob expressions.
	  + parse format-statements.
	  + suppress highlighting of variables inside single-quotes.
	  + show variables highlighted inside double-quoted here-documents.
	  + correct count returned from is_ESCAPED(), which did not count the
	    character after the backslash if it was a quote character.
	+ correct logic in encode_attributes(), which did not recompute region
	  size for a buffer attribute that started on the current line, but did
	  not end there.
	+ add un-filters (atr2ansi, atr2html, atr2text) which convert encoded
	  control/A text to different forms.
	+ modify "decode-attributes-til" to allow multiple regions to start
	  at the same point.
	+ modify "encode-attributes-til" to set local nohighlight mode on the
	  modified buffer (was global).
	+ modify a limit-check in add_line_attrib(), in case an external
	  filter provides a region that extends beyond the line.  In that
	  case, it continued to set attributes beyond the allocated space.
	+ modify "encode-attributes-til" to render selected text with "R"
	  attribute.  It would be more consistent to use "S", but there would
	  be no proper way to read the attribute back into vile.
	+ rename a 'lvalue' variable in display.c to avoid conflict with macro
	  preventing compile with unproto on SunOS 4.1.

 20030504 (o)
	> Danny Zerkel:
	+ modify perl filters to disallow a blank between "<<" and the
	  identifier for a here-document.
	> Tom Dickey:
	+ fix for pl-filt.c, make it treat "!" as an operator rather than a
	  pattern delimiter.
	+ modify support for ^X-e to make it use the whole line if the current
	  buffer is a directory.
	+ use realpath() rather than resolve_directory() if it is available,
	  and "$VILE_PWD" environment variable rather than "." as parameter to
	  getcwd() if it is valid, to speed up operation on quasi-filesystems
	  such as ClearCase (adapted from patch by Danny Zerkel).
	+ add ".PL" to suffixes for perl mode, e.g., for Makefile.PL
	+ add no_minimsgs variable, check in mlmsg() to allow editMiniBuffer()
	  to keep editing commands from overwriting the minibuffer with a
	  message.
	+ improved editMiniBuffer(), correcting treatment of commands which
	  would modify the result.  Overlooked in 9.3k, this copies the result
	  from calls on execute() back to the TBUFF passed to editMiniBuffer().
	+ use insert-mode bindings in editMiniBuffer() when mini-edit mode is
	  active.  Use insert-key to toggle, rather than set mini-edit mode
	  (adapted from patch by Mark Robinson).
	+ modify latexflt.l to suppress treatment of "|" as a quoting character
	  when within curly braces (report by Paul van Tilburg).
	+ correct highlighting of "+=" in makefilt.l
	+ move a comment out of the pattern section of latexflt.l to work
	  around bug in HPUX lex (report by Adam Denton).
	+ increase output- and state transitions-limits for latexflt.l,
	  rpm-filt.l, sh-filt.l and vilefilt.l to compile with Solaris and HPUX
	  lex programs (report by Adam Denton).
	+ make configure check for flex's version contingent on ensuring that
	  it is really flex (report by Adam Denton indicates that HPUX lex
	  is confused by "--version", and requires further input).
	+ modify vile-manfilt to decode UTF-8 emitted by groff 1.18

 20030318 (n)
	> Tom Dickey:
	+ fix typo in CF_WCTYPE macro, needed to add "-lw" to $LIBS.
	+ workaround for bug in autoconf 2.52 which made it not show help
	  text for "--with-locale" option, since it was quoted to pass it as
	  a parameter to CF_LOCALE.
	+ modify delins() to work with text that contains nulls.
	+ fixes to make replacepat (the variable that holds the value supplied
	  as a replacement pattern, e.g., when "~" is typed) work with embedded
	  nulls.
	+ move upper/lower case-conversion into tables vl_uppercase[] and
	  vl_lowercase[], so that locale support can replace the DIFCASE
	  variable.
	+ fix an infinite loop in c-filt.c, from 9.3k changes (-j option).

 20030310 (m)
	> Tom Dickey:
	+ revise lgettext() and screen_string() to use TBUFF's directly, fixing
	  the ^X-, macro broken in 9.3k.
	+ fixes to avoid adding a trailing null to the "$search" variable.
	+ correct parenthesis in dfputf(), which truncated "%f" format used to
	  display "count-words" result.
	+ implement logic for hypertext commands in "encode-attributes-til".
	+ fix misplaced ":" appended in "encode-attributes-til".
	+ add mode overlap-matches, to control whether highlighting for the
	  visual-matches mode should skip to the next character, or past the
	  current match when checking.
	+ correct comparison in EXACTLY case of regrepeat(), which broke logic
	  for "  *$" pattern - two blanks (reported by Danny Zerkel).
	+ correct limit check in regrepeat(), which must account for the
	  operand size directly since it is no longer null-terminated.
	  Fixes match for patterns such as "X*$" (reported by Danny Zerkel).

 20030226 (l)
	> Tom Dickey:
	+ remove special check in kbd_putc() to advance the cursor, since fix
	  in 9.3k using after_linsert() function duplicated this, making the
	  cursor move twice for each character inserted in the minibuffer.
	+ fix a sign-extension in hash_function() (filters.c), which could make
	  a negative hash code.
	+ modify regexp.c and callers to pass length into regcomp(), making
	  its interface not rely upon whether the pattern is a null-terminated
	  string (prompted by recent change for KBD_0CHAR, which dated from
	  980312).
	+ add more keywords for js.key
	+ correct handling of backtic in here-document by sh-filt.l when
	  command-substitution happens to be disabled.
	+ modify imdying() to always exit with an error status.
	+ amend changes to editMiniBuffer(), which did not allow arrow-key
	  movement unless the ^G toggle was used.

 20030217 (k)
	> Clark Morgan:
	+ make ^X-s reflect the documentation in vile.hlp by implementing a
	  new command substitute-all-til.
	> Paul van Tilburg
	+ add Ruby syntax filter (rb-filt.l, rb.key).
	> Tom Dickey:
	+ add -j option to c-filt.c, to implement some java-specific features
	  such as "$" as part of an identifier, and \u escapes.
	+ fix: java has no 'operator' keyword.
	+ suppress KBD_0CHAR flag in kbd_string() function, since it is only
	  designed to handle null-terminated strings.  This plugs a hole which
	  would allow
		:%s/^@/!/g
	  to have unexpected results (report by Clark Morgan).
	+ correct return from kbd_reply() used in scripts; sometimes it would
	  add an extra null to the result.
	+ correct an overlap between bits used to denote NOMINI (now MINIBUF)
	  and FROM (part of RANGE) which caused some commands to be incorrectly
	  treated as minibuffer editing commands when logic was changed to
	  allow MINIBUF to be treated this way.
	+ implement a few new editing commands in the minibuffer:  r, ~, x, X.
	  Other editing commands such as R would require special handling;
	  these are implemented by setting the appropriate flag in cmdtbl.
	+ change cmdtbl to use MINIBUF rather than NOMINI, to implement
	  encoding of editing commands which are limited to the minibuffer.
	+ modify buffer- and filename-completion on Unix to escape backslashes
	  which are stored in the [Completions] buffer.  Doing this allows one
	  to complete a buffer or filename containing a backslash (Debian
	  #164593).
	+ add configure check for -lw library, needed for Solaris 
	  functions.
	+ correct logic of CF_X_ATHENA_LIBS, which did not really add extra X
	  libraries.
	+ use CF_LOCALE, CF_WITH_DBMALLOC and CF_DMALLOC macros to simplify
	  configure.in
	+ use fltstack.h in sccs filter.
	+ highlight expanded and unexpanded sccs keywords in sccs files.
	+ add texmode, as a variation of latexmode.
	+ add .ltx, .sty suffixes for latexmode.
	+ review/revise latex filter (reports by Daniel L Ashbrook
	  ).  It still does not implement \[ \] and \( \)
	  toggles for math mode, but is improved.
	+ cleanup display of whitespace in key-filt.c using new functions
	  chop_newline() and flt_put_blanks() (report by Clark Morgan).
	+ add case for "abbrev" to key-filt.c
	+ improve state stacking in yacc highlighting filter, correcting some
	  problems introduced by fltstack.h changes.
	+ modify lex syntax filter to accept C-style comments in the RULES
	  state; apparently flex allows this.
	+ add a C version of Ruby syntax filter.
	+ add new commands encode-attributes-til and write-encoded-til to
	  convert the syntax highlighting in a region back to control/A
	  sequences, or to write the corresponding data to a file.  Added a
	  corresponding alias decode-attributes-til for
	  attribute-cntl_a-sequences-til.
	+ change lrepltext() to use a given length rather than assume its
	  parameter is null-terminated.

 20030102 (j)
	> Clark Morgan:
	+ fix a couple of compile-problems.
	> Tom Dickey:
	+ correct operation of chgreg() when no text is present in the buffer
	  before inserting the replacement.  This makes a command such as
	  	1GcG
	  work properly (report by Paul Fox).
	+ modify tracing code to show names of CMDFUNC's.
	+ modify ifile() to mark a buffer changed only if data were read from
	  the inserted file.  Otherwise an error was reported when trying to
	  undo the modified state.
	+ modify getregion() to check if the buffer is empty, and in that case
	  return an empty region with status indicating there is a region.
	  That allows filtering of empty buffers (report by Paul Fox).
	+ trim a leading quote from internal arguments in run_func(), to make
	  this type of construct work properly:
		setv %w='*.[Cchis] llib-l*'
		use-reg f load-reg &cat "^X!grep -n -w : " &cat %w "^M"
	+ modify sh-filt.l to handle escaped newlines within quotes.
	+ change some quoted includes in filters to bracketed form (report by
	  Paul Fox).
	+ more fixes to ncurses configure-script check.
	+ add a configure option for XawPlus (see homepage
	  http://people.freenet.de/kra/XawPlus/)

 20021223 (i)
	> Adam Denton:
	+ implement xml-filter based on html-filter.
	> Clark Morgan:
	+ fix: if winvile is in insert mode when wvwrap opens a new file, the
	  "remote" editing commands used to open said file were inserted into
	  curbuf.  This is a bug in the original implementation.
	+ update doc/filters.doc for 9.3h
	> Mark Robinson:
	+ modify perform_dobuf() to allow multiple occurrences of directives
	  such as "~force" on a line.
	> Paul Fox:
	+ add mode parameter to open() call in ffwopen() used by imdying().
	> Tom Dickey:
	+ add configure check for wctype functions, to work around defect in
	  glibc's ctype functions: in UTF-8 locale, the latter return useless
	  information on character classes.  This works on Solaris.
	+ add configure option --with-screen=ncursesw to allow building the
	  curses driver using the wide-character version of ncurses.
	+ in UTF-8 locale, adjust termcap driver to use UTF-8 to display codes
	  in the 160-255 range, setting vile's locale to non-UTF-8 locale.
	  (yes, this is a short-term fix).
	+ modify logic in set_mode_value() to fix a memory leak of changes to
	  global mode values (see 9.2o, which made those consistently
	  allocated rather than some constants).
	+ modified filters.h and some filters to include estruct.h, thereby
	  using definitions for no-leaks checking in trace.h
	+ add more beginDisplay/endofDisplay macros to work with the assertions
	  in trace.c (basic.c, finderr.c, modes.c, select.c, tags.c).
	+ split-out fltstack.h to simplify state-stacks in filters.
	+ modify yaccfilt.l to use %keywords in yacc.key
	+ modify xml-filt.l to handle CDATA and inline DTD's.  Add some other
	  features based on patch from Mark Robinson.
	+ change term.set_title() calls so they are only executed in update(),
	  to make it more efficient, e.g., when [Buffer List] is visible, the
	  internal buffer-switching for that was causing 2 title updates for
	  each character modified in the current buffer.
	+ implement xterm-title mode.
	+ correct a "&" to "&&" in ifdef's generated by mktbls
	+ remove 'termdef' symbol, since it was redundant.
	+ change typeallocplus() to use calloc().
	+ add configure option --with-curses-dir
	+ altered search-lists for configure script to find ncurses in more
	  unusual places, such as the user's home directory.
	+ change default for --with-locale option to yes.  Note that this
	  option is only tested if locale support is found, and it is becoming
	  less common to encounter systems with broken locale support.
	+ update config.guess, config.sub
	+ add ".S" to asmode suffixes.
	+ add ".C" and ".cc" to cppmode suffixes.
	+ add "locale" to the $cfgopts variable if vile is compiled with
	  locale support.

 20021105 (h)
	> Clark Morgan:
	+ change home_dir() function to check for $HOME before $HOMEPATH, etc.,
	  on win32.  Otherwise home_dir() may return something like
	  c:\/usr/cmorgan, which performs badly.
	> Danny Zerkel:
	+ add a few Perl 5.6 reserved words, highlight binary values, and
	  version numbers.
	> Tom Dickey:
	+ modify logic of compute_majormodes_order() to avoid skipping items
	  in the list of majormodes.  This fixes the relative ordering of
	  "rc" versus "vile" modes.  Because some items were skipped, the
		"nr" after "sh"
	  	"rc" after "vile"
	  rules caused the second one to be ignored (reported by Clark Morgan).
	+ modify pathcat() so the MS-DOS configuration will not attempt to
	  supply an extra slash when concatenating strings such as "c:" and
	  "/usr/cmorgan" (report by Clark Morgan).
	+ correct allocation size of argv in ntwinio.c, which did not allow
	  enough space.
	+ correct handling of escaped backtic in sh-filt.l
	+ add syntax filters and corresponding modes for assembler (GNU and M$),
	  info and texinfo.
	+ add beginDisplay/endofDisplay macros in several places to work with
	  the assertions in trace.c
	+ add assertions to trace.c in doalloc/dofree to check for places where
	  beginDisplay/endofDisplay should be used to prevent the OPT_WORKING
	  code from interrupting malloc/free calls.
	+ improve error-checking for numbers in perl filter.
	+ implement pot-filt.l, to highlight ".po" files.  Using sh-filt.l was
	  not satisfactory since the quoting rules were not close enough.
	+ modify configure script to fix existence-style ifdef's for crypt,
	  setbuffer, strerror.

 20021027 (g)
	> Tom Dickey:
	+ improve perl filter by recognizing q[] and q() quote-like operators.
	+ improve rpm filter to avoid exiting text area on embedded "%" names,
	  added several keywords to rpm.key
	+ modify suffix rule for terminfo (timode) to allow nrmode to pick up
	  ncurses' terminfo.tail, and corrected preamble for nrmode, which used
	  the wrong quote character.
	+ add yankmotion mode, to control whether the cursor should be moved
	  as in vi after yanking text (discussion with George Eccles and Paul
	  Fox).
	+ modify ifdef's to allow builtin-filters to be tested with the
	  configure --no-leaks code.
	+ improved perl filter by recognizing a pattern at the beginning of
	  a statement, or after the word "split" (the latter was reported by
	  Duncan Sargeant).
	+ fix a place where 9.3f changes quoted a token which was already a
	  quoted string (report by George Eccles).

 20021023 (f)
	> Clark Morgan:
	+ update list of filters in config.doc
	> Tom Dickey:
	+ correct a check in builtflt.c that had the effect of making some
	  keyword files only work if the -v option was given in the filtername
	  string (broken in 9.2y).
	+ small fix to argument parsing in builtflt.c, to avoid going past the
	  end of the string (found with valgrind).
	+ documented the filtername majormode value in modes.doc
	+ correct initialization of which.rc, so it can be run more than once.
	+ improve/complete XtArgVal casts using macros Nval() and Sval().
	+ modify x11.c to make scrolling always use mvupwind() - one place used
	  forwline(), and to fix some cases where horizontal resizing would
	  change the width of the Xaw scrollbar (patch by D J Hawkey Jr).
	+ modify run_func() to quote string-results, to ensure that they are
	  not mistaken for other token types such as directives.  This change
	  is needed to make "which.rc" work on win32.
	+ implemented tilde-expansion on win32.  Actually it was present, but
	  globbing did not work, and the environment variables did not match
	  the Windows 2000 configuration.
	+ modify debug traces to allow Trace() to make an indented listing,
	  according to the function-nesting level.  This is done, originally in
	  ncurses by prefixing the format string with T_CALLED or T_RETURN
	  strings.  Used this feature to help debug changes for which.rc on
	  win32.  Not all functions are traced this way, but all that call
	  swbuffer() are, as well as some others that were useful.
	+ adjust ifdef's so VILE_ERROR_ABORT and VILE_OLE can be defined at
	  the same time.

 20021016 (e)
	> Clark Morgan:
	+ correction to 9.3d change:  @ was busted (command mode) and
	  :write-message "@stuff" caused vile to complain when '@' was pressed.
	+ I noticed recently that I could not use vile's file/directory
	  traversal feature (on linux) to find the value of an errno.h macro
	  (e.g., EINVAL).  As it turns out, linux puts these definitions in a
	  directory that's referenced via a symbolic link resident within
	  /usr/include (other features such as the X11 includes files are
	  handled similarly).  Seems that GNU's find won't traverse symbolic
	  links without specifying an explicit option (it appears SunOS 5.7
	  exhibits similar behavior and uses the exact same option name).  The
	  enclosed patch adds "-follow" as an optional parameter to vile's
	  file/directory traversal repertoire.
	> Duncan Sargeant:
	+ fix a small bug in the perl filter where pod code starting with
	  "=cut" would not be filtered (it's a valid start and end marker for
	  pod).
	> Paul Fox:
	+ make filters/makefile.in's LDFLAGS variable the same as in the
	  top-level makefile to fix a case where flex libraries were not found
	  in a nonstandard location.
	> Tom Dickey:
	+ add b_procname field to BUFFER, use that to save the given procedure
	  name when storing a macro.  This fixes a problem when removing
	  procedures whose name is longer than NBUFN-2, which could leave the
	  key binding table pointing to a non-existent buffer, e.g., ^X-, for
	  next-cur-identifier.
	+ documented ~elsewith in doc/modes.doc (report by Adam Denton).
	+ correct handling of "uc" keyword for perl filter in this line:
		if ($diagType =~ uc $widgetType)
	  It was being treated as a pattern delimiter.
	+ add several short-named relational operators "&geq", ">", "&leq",
	  "<", "&neq", "&sgeq", "&sgt", "&sleq", "&slt", "&sneq" to reduce
	  the need for "¬" (suggested by Adam Denton).
	+ change UFxxx variables to an enum, using this to check for unhandled
	  cases in eval.c
	+ repair missing mktemp() call in imydying(), broken in 9.3d changes
	  (reports by George Eccles and Paul Fox).
	+ add syntax filter for rpm ".spec" files.
	+ add syntax filter for PostScript ".ps" files.
	+ add syntax filter for enscript ".st" files.
	+ make cursor-movement on a yank command match vi's, tested for various
	  left/up motions such as yk, yh, yH, y1G, y0, y-, yb (report by
	  George Eccles).
	+ correct order of initialization in operyank() from 9.3b changes,
	  which could cause a core dump (reported by George Eccles).
	+ modify check for renaming the unnamed-buffer when writing it; do not
	  rename it if the write was to a pipe (report by Paul Fox).
	+ add definition for OWTOOLKIT_WARNING_DISABLED to x11.c, without which
	  the Xol version cannot be compiled under Solaris 8.
	+ add -Wundef flag for gcc warnings, modified ifdef's to make SYS_xxx,
	  CC_xxx, DISP_xxx variables always defined as 0/1, and use #ifdef to
	  check for the HAVE_xxx and similar variables rather than #if.
	+ modify configure check for Athena (Xaw, etc) libraries to include
	  Xpm, on which XFree86 4.x Xaw depends.  That allows xvile to be
	  built on cygwin.
	+ modify logic of pop_fake_win() to allow for the possibility that the
	  current buffer is not related to the current window.  This can/did
	  happen in tprintf(), for example, but could happen in one of the
	  other calls.  In particular, if ~trace was enabled, that resulted in
	  making ":ww" fail to write files which had no current window.
	+ add pattern for hexadecimal character codes in htmlfilt.l
	+ modify configure script to use '%' consistently as sed delimiter,
	  rather than sometimes '@', to avoid problems with AFS.
	+ update config.guess, config.sub

 20020902 (d)
	> Brendan O'Dea:
	+ updates to allow vile to build with perl 5.8.0 (ifdef's checked for
	  5.6.1, 5.5.3 and 5.4.5).
	> Clark Morgan:
	+ modify ntconio.c and ntwinio.c to recognize control/@ as a null,
	  to allow inserting null characters.
	+ config.doc:
	  - correct erroneous statement; namely, vile build only creates as many
	    external filters as necessary, not all filters.
	  - restructure doc/config.doc's builtin-filter prose for improved clarity.
	+ vile.hlp:
	  - fix ispell macro so that users avoid a "warn-reread" prompt.
	  - remove ShowManpage macro from vile.hlp; it's long and complex.
	    Interested readers can read the macro directly by browsing
	    manpage.rc .
	  - documented builtin filters.  One of the more notable changes here
	    is that I dumped the description of how to optimally build vile on
	    a Unix host when disk space is limited.  I don't think that's much
	    of an issue these days and it substantially simplifies the prose.
	> Tom Dickey:
	+ add which-keywords, as a macro.
	+ add $pathname-separator variable.
	+ implement edit-buffer command, to simplify which-keywords macro.
	  In turn, this required modifying readin() to allow us to treat
	  an empty filename as a non-error condition, and adding the KBD_OPTIONS
	  flags to the DONE_ARGS to propagate this down to kbd_complete(),
	  to make the code which does name-completion of buffer-names allow
	  a partial match.
	+ put nrmode after shmode to allow scripts such as "with-perl-5.8.0".
	+ reorganize decode_prefix() to allow parsing of bindings such as
	  ^X-#-a (report by Christian Neumann )
	+ reset, if possible, real uid/gid values to match effective uid/gid
	  values, to appease Perl's check for setuid scripts.  This fixes a
	  problem where vileperl.rc would stop during initialization because
	  fcron's fcrontab program would run the editor process with the group
	  id's not matching (reported by Clemens Fischer).
	+ change test in fscan(), aka forward-char-scan to an inequality to
	  allow for the case where the line is empty (report by Adam Denton).
	+ correct logic of label2bp(), which did not skip leading blanks on the
	  line before checking for a label.  This happened to work until 9.2u
	  indented macros as they are stored (reportd by Adam Denton).
	+ modify built-in spell filter to work with encrypted files.
	+ improve check for flex's version (patch by Danny Zerkel
	  ).
	+ correct check for mkdtemp() in create_save_dir() (reported by
	  D J Hawkey Jr ).
	+ add vile's patches to RPM spec (patch by Mark Milhollan
	  ).
	+ correct parsing of '+' in prc2kcod(), so one can bind that key
	  to a command, e.g.,
		bind-key next-buffer +
	  (patch by Brian T. Schellenberger ).
	+ add x11menu to descrip.mms and vmsbuild.com (patch by Jouk Jansen
	  ).
	+ use XtArgVal casts on data passed by XtVaSetValues() calls.  This is
	  needed to make xvile run reliably on an LP64 platform, since Xt
	  uses a long for this value.
	+ add an #error in perl.xs to flag instances where patchlevel.h is
	  included from places other than Perl's directory (report by Clemens
	  Fischer).

 20020704 (c)
	> Tom Dickey:
	+ add calls to file_stat() to make vile's cache obsolete when spawning
	  and external shell process or when handing ^Z (suspend).  This fixes
	  a problem where the subprocess may have removed a file.  Vile would
	  thereafter be unwilling to write the corresponding buffer to disk
	  (reported by Clark Morgan).
	+ omit double-quote in finderr expression for weblint, to avoid a
	  conflict with some of ncurses' messages.
	+ make vile syntax filter recognize hexadecimal constants.
	+ add a -t option to filters, to pass tabstop value.  Use this in
	  makefilt.l to provide better highlighting of problems with leading
	  whitespace.
	+ supply install-rule in makefile.in for gnugpg.rc, search.rc and
	  shifts.rc

 20020703 (b)
	> Tom Dickey:
	+ correct missing limit-check in repaint_window(), which caused winvile
	  to GPF if resizing beyond its initially allocated 256x128 size.
	+ add a dummy log-file majormode, to distinguish some makefiles from
	  logfiles.
	+ add some features of GNU make to makefilt.l and make.key that are
	  useful in conditional evaluation.
	+ add percent-crlf mode, which controls the threshold at which the
	  whole file will be considered DOS-format (CRLF record separators)
	  if the given percentage already ends with CR/LF.
	+ save/restore window modes such as linewrap when rereading a file,
	  or when executing a shell command.
	+ amend change to operyank() to also set the cursor position to the
	  beginning of the yanked region when it is before the current position,
	  e.g., by typing y?pattern or y1G (reported by Clark Morgan).

 20020630 (a)
	> Clark Morgan:
	+ document configure-script options for color syntax highlighting.
	> Tom Dickey:
	+ correct change made to operyank() to handle y0p command in 9.2za by
	  not moving the cursor when there is no motion associated with the
	  yank, e.g., when typing yy or Y (reported by Clark Morgan).
	+ fix esqlfilt.l to start with C symbol table rather than SQL.
	+ fix esqlfilt.l to allow a blank between "#" and "include".
	+ add check in tcap.c for terminfo kmous capability like xterm, in case
	  we are running in screen, which also supports xterm mouse protocol.
	+ modify sed-filt.c to allow semicolon as an address separator.
	+ modify spell.rc, spellflt.l and select.c to allow spell filter to
	  work as a built-in filter (reported by Clark Morgan).
	+ corrected misleading description of rc-filt.l (reported by Clark
	  Morgan).
	+ rewrote spell.rc to make it work properly if the spell-filter is
	  built-in (reported by Clark Morgan).
	+ remove a spurious call to flt_bfr_append() in sh-filt.l which broke
	  highlighting of quoted symbols such as "${foo+bar}".
	+ correct ifdef's in estruct.h and fileio.c so that DJGPP version
	  builds.

Changes for vile 9.3 (released Tue Jun 25 2002)

 20020625 (ze)
	> Clark Morgan:
	+ more trouble shooting tips for syntax coloring to vile.hlp
	+ update README.PC to cover platforms that have been tested.
	+ update README file to cover 9.3 changes.
	> Gary Jennejohn :
	+ add ".S" to default C suffixes on Unix.  The difference between ".s"
	  and ".S" is that the latter may have C-preprocessor statements.
	> Tom Dickey:
	+ update list of macros in makefile.in and makefile.wnt to include
	  gnugpg.rc, search.rc and shifts.rc
	+ add macro loaderrs.rc to illustrate how to extend the built-in
	  error expressions (request by Neil Milne ).

 20020521 (zd)
	> Tom Dickey:
	+ move save/restore of dotcmdactive and pre_op_dot variables from
	  autocolor() to run_a_hook() so they are restored if any hook calls
	  would modify them.  This fixes a case where the "." command did not
	  work when [Buffer List] was visible while a $buffer-hook was used to
	  set xvile's title (report by David Letcher ).
	+ add itb_visible() to trace.c

 20020514 (zc)
	> Tom Dickey:
	+ modify fallback definitions in path.c to work with CSet compiler,
	  which did not define S_IFMT in 
	+ modify mktbls.c to provide workaround for OS/2 CSet compiler, which
	  does not accept struct-offsets as switch-statement case values, e.g.,
	  as used in implementing the &default builtin function.
	+ add an ifdef'd version of ExitProgram() to main.c which will call
	  abort() rather than exit if the environment variable VILE_ERROR_ABORT
	  is set to a nonempty value.  This is useful for debugging.
	+ modify insert.c to rename 'leave' to 'leave_loop', avoiding symbol
	  defined in Visual C++ 4.1
	+ modify vileinit.rc to disable resolve-links on cygwin

 20020511 (zb)
	> Clark Morgan:
	+ more documentation tweaks.
	+ add example macro underline-currline to vile.hlp, based on submission
	  from Daniel L Ashbrook.
	> Tom Dickey:
	+ updated buglist
	+ add Help.pm and CaptHook.pm to makefile.wnt
	+ add a check to prevent runaway recursion in a case where a dynamic
	  buffer such as [Variables] was visible when a $buffer-hook is used.
	  When reading from a pipe, the buffer hook would activate and then
	  attempt to switch back to [Output], which was not yet marked active.
	  So it would attempt to re-read the pipe, which then repeated the
	  whole process indefinitely.  The check uses a new flag BFISREAD,
	  and macro b_is_reading().
	+ more fixes for pl-filt.c
	  + add 'grep' to the quote-like operator list, and in doing so make
	    is_QUOTE() simpler.
	  + modify check for blank lines in begin_POD() to allow for DOS-style
	    line endings.
	  + correct computation of number of blanks before a comment
	  + add/use isBlank() macro to treat tabs and spaces more alike, e.g.,
	    before embedded comments in a quoted list.
	  + modify test for end-delimiter of a quoted list which specified
	    a curly-brace to allow the square bracket and parenthesis pairs
	    that Perl recognizes.

 20020507 (za)
	> Clark Morgan:
	+ remove pointers to foxharp host.
	+ update copyrights.
	+ remove duplicate use of $(CFLWIN32) from makefile.wnt
	> J Chris Coppick:
	+ tcl files were being edited in shmod since .*sh was matching 'wish',
	  and we weren't catching files with tclsh, wishx, or tcl preambles,
	  unless the file suffix was '.tcl'.
	+ update Breadcrumbs.pm to version 0.4
	> Paul Fox:
	+ add 'directory' to modeline for directory buffers.
	+ change file-mode test in 9.2y to check for FIFO's rather than
	  character-devices.
	+ modify ifile() to avoid marking the current buffer as modified when
	  attempting to insert the contents of a file which fails the "not a
	  file" test.
	> Tom Dickey:
	+ disable "working..." when writing to a pipe, but not reading from it.
	  In that case, the pipe may be an interactive process, and we do not
	  want to pollute its display (reported by Clark Morgan).
	+ restore 'working()' mode at the end of directory.pm's dir() function,
	  which is required to allow xvile to resume processing mouse
	  double-clicks for hyperlink selection.  Reviewed/updated a few other
	  scripts which had the same issue (report by J Chris Coppick).
	+ disable autosave for readonly files.
	+ add check in main loop for failure in repeat-last-cmd, which may
	  have terminated in the middle of a change-command.  If a failure is
	  detected, discard the remaining characters in the replay (report by
	  Kevin Buettner).
	+ modify logic of operyank() to set DOT to the beginning of the region,
	  so that y0p will move the cursor to the beginning of the line just
	  like vi.
	+ improve perl filter's handling of quote-like operators.
	+ show filenames opened for read or write in [Trace], to make it
	  simpler to see which scripts are used.
	+ add check in finderr.c to ensure that line numbers past the end of
	  the buffer result in going to the end of the buffer rather than
	  wrapping around to the beginning.
	+ correct configure script CF_HEADER_PATH macro, which did not look in
	  the proper directories under $HOME.
	+ update config.guess, config.sub
	+ add expectk to programs in tclmode preamble.
	+ highlight TPU files like DCL (.com) files.  The available keywords
	  are different, but the syntax looks the same.
	+ move the list of majormodes from [Settings] to [Major Modes], to
	  reduce clutter in the former.
	+ indent'd (with updated patch against indent 2.0) api.c, fences.c,
	  glob.c, input.c, isearch.c itbuff.c, lckfiles.c, msgs.c, npopen.c,
	  spawn.c, statevar.c, tcap.c, window.c, as well as the .c files in
	  filters.

 20020228 (z)
	> Clark Morgan:
	+ makefiles converted to DevStudio V6.0
	+ visvile modified to pop winvile to foreground on Win2K/XP
	+ fix clipped text in configuration dialog (at various geometries)
	+ if the build log from an unsuccessful build is placed in winvile's
	  error buffer (visvile config option), the editor's CWD is changed to
	  match the build log's parent directory.  Without this change,
	  visvile's CWD defaults to \system32 on a Win2K host.
	+ remove compiler warnings from w32reg.c
	+ wheelmouse didn't work on my wife's laptop (uses an el cheapo USB
	  mouse) so I'm submitting an official patch to enable WM_WHEELMOUSE
	  support.  Adding this support requires mucking with the makefile a
	  bit.
	+ added a static child window that shows winvile row/col geometry as
	  winvile is resized (Win2K/NT/XP only).  I could only test this on a
	  single screen geometry (i.e., laptop's 1024 x 768).  Someone should
	  try resizing winvile on a 2K/NT/XP host with these screen settings:
	  800x600, 1280 x 1024, 1115 x 864 .  Let me know if you see text
	  clipping in the child window under these conditions.
	+ following tested on WinME/98 and Win2K:
	  + remove all but one warning from automation-based modules.
	  + add get_MainHwnd() method to automation-based version of winvile.
	  + modify wvwrap to pop winvile to foreground on a Win2K host.
	  + modify wvwrap to restore winvile window if minimized
	+ vile.hlp tweaks (typos, omissions, and minor formatting).
	> Tom Dickey:
	+ split-out specialized logic for cindent's character list as
	  cindent-chars mode so appropriate pieces can be applied to other
	  modes such as esqlmode and cppmode.
	+ filter scrollbar-tracking events to make winvile's scrollbars work
	  for files longer than 65536 lines.

 20020217 (y)
	> Tom Dickey:
	+ indent'd tags.c
	+ make xvile -rv work by adding reverseVideo resource to its
	  application resources, and interpreting that.
	+ add new selection for showformat, "foreign".  Change default of
	  showformat to this, to reduce clutter (discussion with Paul Fox).
	+ do not infer majormodes for directory buffers, e.g., vile-9.2 would
	  be inferred as nrmode (reported by Paul Fox).
	+ remove an empty section of the suffixes pattern for cppmode which
	  made it match files ending with ".".
	+ add a call to show_mark_is_set() in updatelistbuffers() so the
	  [Marks] buffer will be recomputed anytime it is visible and the
	  [Buffer List] is updated.  Usually that is when one of the buffers
	  changes size, which means that marks may have moved.
	+ repair logic for cleanup after pipes:  mods for directory buffer lost
	  the cleanup after writing a pipe because ffstatus is reset now in
	  ffclose() before it was tested in CleanAfterPipe().  Moved related
	  state & logic into CleanToPipe(), CleanAfterPipe() to make them
	  simpler to understand (reported by Clark Morgan).
	+ use catnap() rather than sleep() in softfork(), since the former is
	  less likely to get spurious SIGALRM's.
	+ correct tprintf() to fix a core-dump when using ^X-, in [Trace],
	  i.e., set DOT.o to zero.  Also prevent tprintf() from being called
	  recursively.
	+ add TPRINTF calls to show in [Trace] why a particular majormode was
	  chosen, i.e., whether the suffix or preamble matched, or both.
	+ add command-line -D option which turns on macro tracing (~trace on).
	+ simplify argument processing a little, removing the non-XTOOLKIT code.
	+ modify lremove() to fixup the bp->b_wline value.  This fixes a hole
	  exposed by the directory-buffer changes, e.g.,
		vile
		isomething
		:e /
		__
		:r /
		__
		(crash)
	  (reported by Paul Fox).
	+ avoid calling both mktemp() and mkdir() in create_save_dir().  Only
	  one flavor should be used (reported by Paul Fox).
	+ modify ffwopen(), ffclose() and ffputc() to avoid using buffered I/O
	  when called from imdying().  Recent versions of glibc make the
	  process lockup when using ElectricFence in this situation.  It is
	  not POSIX, anyway, to use buffered I/O or malloc in a signal handler.
	+ modify checks for non-file to allow character devices, e.g., a
	  named pipe for people who use that feature to randomly generate an
	  email signature (reported by Paul Fox).

 20020213 (x)
	> Tom Dickey:
	+ improve describe-key so it displays bindings for named procedures
	  and perl commands.
	+ add fence-patterns to sqlmode, for PL/SQL.
	+ implement extended command-line options for filters, allowing them
	  to specify which options (other than -k, -q, -v) are recognized for
	  their own use.  Use this to add -p option to c-filt.c, which tells
	  vile-c-filt to mark '#' (preprocessor) as an error.
	+ correct two bugs in sh-filt.l
	  a) add/use return value from embed_or_append() to decide whether to
	     switch to SUBST state.
	  b) emit token that does not match EOF-marker for here-document.
	+ add cursor-attributes and other keywords from Oracle 7.
	+ modify sql filter to flag "remark" as an error if it is not the
	  first token on a line.
	+ correct highlighting of "remark" keyword in sql filter, which did
	  not allow for "REMARK".

 20020203 (w)
	> Tom Dickey:
	+ indent'd line.c, oneliner.c, opers.c
	+ implemented '< and '> marks, which denote the limits of the
	  selection.
	+ add ".ac" as a suffix for m4-files.
	+ disallow attempts to re-read [p-lines] by making fileread() use the
	  is_internalname() function rather than simply checking the length
	  of the filename.
	+ add commands leading-detab-til and leading-entab-til, binding those
	  to ^X-' ' and ^X-^I.  Most of the logic was available internally.
	+ modify ifile() to avoid infinite loop when reading a directory buffer
	  into itself, e.g.,
		:e /
		:r /
	  This still has a minor problem: the window scrolls up by one line
	  each time the ":r" is performed.
	+ modify sortMyBuff() to avoid corrupting DOT when reconstructing
	  linked list, e.g., if reading a directory buffer into itself.
	+ modify file.c to print the number of lines read from a directory.
	+ modify makename() to check if the result buffer name is empty,
	  setting it to NoName if that happens, e.g., when editing the root
	  directory "/".
	+ modify current_directory() and pathcat() to ensure their result
	  cannot be longer than NFILEN.
	+ replace several strncpy() and strcpy() calls by vl_strncpy().
	+ modify fileuid_get() to discard file_stat's cache.
	+ modify append_to_path_list() to use file_stat(), to check if a given
	  file or directory exists before adding it to the list.

 20020121 (v)
	> Tom Dickey:
	+ indent'd menu.c, x11.c
	+ add commands for manipulating menus: hide-menus, show-menus,
	  load-menus and remove-menus.
	+ add $menu-file variable.
	+ modify menu-file lookup to look for $VILE_MENU as well as $XVILE_MENU,
	  making the latter derived from $progname, to make it more extensible.
	+ changed install rule for vilemenu to be consistent with other config
	  files, i.e., as vilemenu.rc rather than .vilemenu -- xvile will still
	  search for .vilemenu if vilemenu.rc is not found, however.
	+ split-out X11-specific part of menu support as x11menu.c
	+ add call to set_editor_title() at the end of set_buffer_name(), so
	  that if the filename changes as a result of writing to a file, the
	  window title is updated correspondingly.
	+ implemented bindings for shift/control/alt modifiers for function
	  keys in xvile and winvile by extending Clark Morgan's 9.1c changes.
	  This does not support remapping.
	+ modify prc2engl() so it may return an error_val, making the &bind
	  builtin function report any error in this function.
	+ correct logic in parse_filtername(), which could index out of bounds
	  when processing a manpage buffer.
	+ correct/improve highlighting of delimiters for here-documents, by
	  flagging places where the quoted delimiter includes a newline, and
	  by eliminating a spurious repeat of the ending delimiter.
	+ correct highlighting of variable in perl files where a pattern would
	  be expected, e.g.,
		if ( $c !~ $DST )
	+ add undo-dos-trim mode, which when true causes vile to make the
	  trimming of ^M's done as part of setting dosmode or set-dos, set-unix
	  commands undoable.  Also, trim ^Z character if it is the last line
	  in the buffer (suggested by Clark Morgan).
	+ remove spurious b_set_counted() from rewritten quickreadf(), which
	  had the effect of making bsizes() count crlf conversion twice.
	+ correct resync of CF_CURSES_TERMCAP, needed to make curses.h included
	  in some configurations.

 20020112 (u)
	> Clark Morgan:
	+ add example of --with-cflags to doc/config.doc
	> Paul Fox:
	+ modify c-filt.c to make it simpler to find unterminated quotes from
	  preprocessor lines.
	> Tom Dickey:
	+ indent'd basic.c, filec.c, insert.c, region.c
	+ cache stat() results for files to improve performance on systems that
	  do not do this automatically.
	+ modified treatment of attempt to read directory by reusing logic in
	  filec.c which builds a sorted list of the directory's contents, to
	  make a corresponding non-hidden buffer.
	+ add error checking to ensure vile does not open non-files such as
	  /dev/tty.
	+ modified directory.pm to limit the filename by the page width rather
	  than to a hardcoded 14.  The directory names are limited to 14 to
	  make the layout work.
	+ check in lremove() to avoid removing the buf_head() line.  Otherwise,
	  infinite loops would result in iterating over lines in the buffer.
	  This could happen if the cursor was placed on the next to last
	  line of a buffer, and the command yddp were given (report
	  by Clemens Fischer).
	+ correct an off-by-one that allowed a very long mode value to touch
	  the next column in [Settings] if the next column contained a boolean
	  set to "no".
	+ correct calculation in next_column(), which did not take into account
	  the HIGHBIT effect on cell width.
	+ correct $bflags value, which was only one character rather than a
	  combination.
	+ correct macro next-alt-identifier, which declared $identifier as a
	  local, which had the side-effect of marking the file as modified.
	+ moved array used for file- or directory-completion into BUFFER
	  struct, to make code in filec.c more reusable.
	+ eliminated symbols SIZE_T and ALLOC_T, replacing them by size_t.
	+ eliminated global curtabval.  Like curswval, it is not really
	  possible to update it properly everywhere.
	+ change beginDisplay() and endofDisplay() to macros, no need for
	  functions.
	+ indent macros as they are stored, making complex ones easier to
	  read and debug.
	+ add "noshell" to $cfgopts if shell is disabled in the current config.
	+ add --disable-filters option to configure script, to allow building
	  just the editor.
	+ eliminate a duplicated $(LIBS) in $(FILTER_LIBS) variable in makefile
	+ improved CF_TERM_H configure macro, to look for ncurses/term.h for
	  platforms where ncurses is an add-on.
	+ modify configure script to print message showing result of the
	  --disable-extensions and --disable-shell options.
	+ correct guess_recordseparator() to set the number of lines to at
	  least one if the file is not empty.  A binary file containing no CR's
	  or LF's would cause a core dump from 9.2s changes.
	+ modify logic of charinit() so that if one sets printing-high but not
	  printing-low, the latter defaults to 160.

 20011230 (t)
	> Tom Dickey:
	+ force screen to repaint if stripping ^M's as part of set-dos
	  command, overlooked in 9.2s.
	+ modify set-highlighting macro, using "~force" to prevent vile from
	  switching to show the macro buffer if the "setl" fails, e.g., if
	  one attempts to set the majormode of [Output].
	+ add "showformat" mode, to control when the recordseparator is shown
	  in the status line.  Choices are local, differs, always or never.
	+ add &stoken function, which searches for a token in a string, e.g.,
	  "perl" in $cfgopts by
		&stoken  "perl"  ","  $cfgopts
	+ add &translate function, e.g.,
		&trans   ","     " "  "a,b"
	  to change commas to spaces
	+ add backslash as a possible quote character in determining type of
	  here-documents for perl filter.
	+ add xvile configuration types to $cfgopts: openlook, motif, athena,
	  xaw, xaw3d and nextaw.
	+ ifdef'd $prompt string if extensions are disabled.
	+ indent'd display.c, version.c
	+ trim trailing blanks from some source files.  lispfilt.l did not
	  compile with Solaris lex because it was confused by a trailing blank.
	+ modify configure script to check $CFLAGS values obtained from perl or
	  imake with a test-compile to ensure that we do not try to use options
	  for a different compiler, e.g., gcc versus cc (report by Steven
	  Lembark ).
	+ update several configure macros to use AC_CACHE_CHECK to replace
	  AC_MSG_CHECKING and AC_CACHE_VAL, except those which are not
	  compatible, e.g., CF_MISSING_CHECK.
	+ updates for configure macros CF_CHECK_CACHE and CF_CURSES_CPPFLAGS

 20011225 (s)
	> Tom Dickey:
	+ fix a memory leak in vars_complete(), as well as make it faster by
	  caching the sorted list of temporary variables until one is added or
	  removed.
	+ modify modeline display to show local recordseparator values (cr, lf,
	  crlf) rather than dos mode, since the latter is redundant in that
	  context.
	+ implemented support for reading/writing Macintosh files, i.e.,
	  recordseparator=cr.  New commands set-rs-cr, set-rs-lf, set-rs-crlf
	  extend the set-unix-mode and set-dos-mode commands to include Mac's.
	+ indent'd fileio.c, mktbls.c, tbuff.c
	+ modify ntconio.c so that default fcolor is 7 (request by Walter
	  Kennedy ).
	+ modify ntconio.c so that "reverse" color scheme works.
	+ add $prompt variable, to allow changing the command-line prompt.
	+ fix an infinite loop in sh-filt.c (reported by Paul Fox).
	+ add a configure check for mkdtemp().
	+ regenerate configure script, overlooked in 9.2r after resyncing
	  macros in aclocal.m4

 20011216 (r)
	> Paul Fox:
	+ fix a problem where repeated ":!cmd" invocations (with no intervening
	  carriage return) cause the "Press return..." message to be
	  suppressed.  (The problem is that mlforce suppresses its output if
	  sgarbf is set.  The first shell invocation sets sgarbf, so the prompt
	  after the second shell command never comes out.)
	> Tom Dickey:
	+ change warning level in makefile.wnt to "-W4"
	+ modify ntconio.c to use the original attributes when erasing the last
	  line of the screen when closing the console.  This works around a bug
	  in w95/.../win-me that would leave vile's color settings in effect
	  after vile exited (reported by Walter Kennedy
	  ).
	+ modify pl-filt.c to handle pattern immediately after "if" keyword,
	  e.g.,
		if /SHLIB_VERSION_NUMBER *"([^"]+)"/; # "
	+ modify sh-filt.l to handle quotes in substitutions, e.g.,
		ACLOCAL=${ACLOCAL-"${am_missing_run}aclocal"}
	+ update config.guess and config.sub from
		http://subversions.gnu.org/cgi-bin/viewcvs/config/config/
	+ regenerate configure script with autoconf 2.52, patched with
		autoconf-2.52-20011201.patch.gz
	  at
		ftp://invisible-island.net/autoconf/
	+ check for $ac_top_srcdir in configure.in, to work with autoconf 2.5x,
	  which renamed this variable from $top_srcdir in 2.13.
	+ modify CF_PROG_PERL to work with autoconf 2.5x, which does not permit
	  unbalanced brackets, using a sed expression to obtain the "$]" token.
	+ modify configure.in to avoid using changequote(), which is broken
	  in autoconf 2.5x
	+ updated install.sh from tin.
	+ updated some configure script macros from changes for tin/lynx:
	  CF_HEADER_PATH, CF_LIBRARY_PATH, CF_MKSTEMP, CF_NCURSES_CPPFLAGS,
	  CF_NCURSES_LIBS, CF_PATH_SYNTAX.

 20011205 (q)
	> Clark Morgan:
	+ fix:  the new builtin find feature makes it relatively easy to
	  construct arbitrarily long pipe commands.  Such long commands could
	  overflow a number of vile's internal temp vars.
	+ Some win2k cleanups:
	  - on a win2k host, if $shell is bogus, read pipes don't display an
	    error message.  Instead, the editor would just hang.
	  - on a win2k host, the shell process spawned via ":!cmd" was usually
	    not executed in the foreground window.
	+ add a pattern to finderr.c to handle this case:  When using visvile
	  under developer studio, the compiler can generate (HTML-based)
	  messages have leading tabs before the filename.
	+ doc/config.doc - numbered macros noted as an anachronism
	+ doc/macros.doc - mention that numbered macros are allocated from fixed
	  pool and describe their (as far as I can tell) single
	  advantage.
	+ vile.hlp:
	  + fix typo where #- binding was attempted in insertmode.
	  + reorganize discussion of macros to mimic (in a very
	    abbreviated form) the key information from
	    doc/macros.doc .
	> J Chris Coppick:
	+ various fixes to Vileserv.pm:
	  + various code and documentation tweaks
	  + Vileserv now automatically installs a $write-hook
	    (for "vileget -w"), unless you tell it not to (details in the doc).
	  + Vileget used to start xvile if needed.  Now it tries 'xvile', then
	    'vile'.
	  + If you hand Vileget a directory name, it will try to do something
	    useful with it.
	  + handle old Vileserv sockets more gracefully, in theory...
	+ minor fixes to Breadcrumbs.pm
	+ add perl/Help.pm
	+ add perl/CaptHook.pm, which provides useful wrappers for Vile's
	  "hook" variables.
	> Tom Dickey:
	+ correct a state in sed-filt.c after parsing a substitute command,
	  which caused alternate lines to not be highlighted.
	+ indent'd trace.c
	+ modify trace.c to make Trace() thread-safe on win32.
	+ correct small bug in ntwinio.c which would allow repaint_window() to
	  be called for a scrollbar.  This normally will not occur because of
	  the way the event queue is processed, but was apparent in debugging.

 20010925 (p)
	> Clark Morgan:
	+ Removed an ugly wart from win32 vile (dated September 11).  Tested on
	  WinME (bash and command.com), Win98 (Thompson Toolkit and
	  command.com), Win2K (cmd.exe).
	+ makefile.wnt and makefile.blc no longer use npopen.c -- all
	  equivalent functionality has been moved into w32pipe.c
	+ w32pipe.c
	  - added completely new approach for temp-files-based pipes (required
	    when using command.com as shell).
	  - force-console code removed (see next bullet)
	  - during testing noticed cases where winvile writes last ditch error
	    messages to stdout.  Uses popup-msgs now.
	+ force-console mode is now a no-op for winvile (retained solely to
	  prevent breaking existing config files).
	+ spawn.c:
	  - npflush() no longer called if using native win32 pipes (the
	    original call was always a nop for native pipes).
	  - win32 hosts call npflush() _after_ closing write pipe file
	    descriptor (important for the temp files implementation).
	+ filters.rc no longer worries about the setting of w32pipes.
	+ gnugpg.rc no longer mentions w32pipes.
	+ macros.doc: remove force-console from example config file
	+ delete doc/w32modes.doc
	+ vile.hlp:
	  - w32pipes and force-console updates.
	  - mention macros/gnugpg.rc wrt encryption (updated in vile.1 as well)
	  - documented interaction between cygwin's bash, console vile, and
	    interrupts.
	  - updated $os description to mirror Tom's changes in doc/macros.doc
	  - within the "Color basics" topic, discuss custom winvile colors
	+ explain how to build filters via makefile.wnt (README.PC).
	+ update vile.hlp's install dir and be more specific regarding vile's
	  installation components (doc/config.doc).
	> J Chris Coppick:
	+ implement perl/Breadcrumbs.pm (request by Clemens Fischer).
	> Kuntal Daftary:
	+ two new perl extensions for vile:
	  1. man.pm is a Unix manual pages viewer in vile.
	  2. dict.pm is a dictionary/thesaurus interface (uses the DICT protocol)
	  Drop both the files in the appropriate path ($HOME/.vile/perl for
	  Unix) and add the following lines in your .vilerc
	     perl "use dict"
	     perl "use man"
	> Mark Robinson:
	+ modify selection in winvile so that DOT is not moved.
	+ improve paste-by-right-mouse-click operation in winvile by NOT
	  setting the insertion point at the position where the mouse happens
	  to be when executing the right-click, but rather pasting at the
	  current DOT (i.e.  right-mouse-click never sets DOT).
	+ change paste in winvile to insert at DOT rather than after.  Also,
	  when pasting in insert mode, set DOT to the end of the inserted
	  text.
	> Tom Dickey:
	+ modify the check in glueBufferToResult() so that parameters of
	  search-commands can have quote-characters escaped, for consistency
	  with the logic that strips them.
	+ extend insert-exec to allow ^A and ^X prefixes to be interpreted
	  in insert mode (based on a patch by Mark Robinson).
	+ corrected binding in dates.rc that demonstrates insert-mode bindings.
	+ add a show-key-names command to show the #-style coding for function-
	  and cursor-keys.
	+ correct number of arguments for &ftime (incorrect number of arguments
	  caused the increased error-checking in 9.2o to break this function).
	+ extend support for alternate bindings by duplicating the default
	  special-key bindings at initialization so they can be customized
	  independently.  For example, this lets one define in vileinit.rc a
	  different home/end key binding for command-mode than for the default
	  (prompted by a patch by Mark Robinson).
	+ modify support for alternate bindings to use different buffer names
	  for describe-xxx-bindings commands, i.e., [Command-Bindings],
	  [Insert-Bindings] and [Select-Bindings], to make it simpler to
	  distinguish them.
	+ add a configure check for working mkstemp() function, use this for
	  spell filter to quiet linker warnings (corresponding warnings for
	  file.c are bogus).
	+ modify configure script for VILE_LIBDIR_PATH and VILE_STARTUP_PATH
	  to double backslashes, just in case the user has defined the
	  corresponding environment variables in DOS-pathname syntax (request
	  by Mark Robinson).
	+ modify adjvalset() to allow an empty response for the mode value if
	  running in a macro.
	+ modify push_variable(), which implements "~local", to check if a
	  given symbol requires quoting to avoid interpreting meta characters
	  when restoring its value (reported by Clark Morgan, e.g., for
	  $paragraph).
	+ add C preprocessor parsing to xresmode, for files that use xrdb.
	+ extend xresmode suffix pattern to add .Xdefaults-hostname
	+ correct parsing of single-line "remark" comments in sql filter, which
	  did not work unless some character followed the "rem" or "remark"
	  keyword (report by Chris Green).
	+ split-out include of  into w32vile.h, adding some pragmas
	  which stifle warnings emitted by Visual C++ for M$ header files when
	  compiling with -W4 warning level.  Changed default warning level in
	  makefile.wnt to -W4.

 20010826 (o)
	> Clark Morgan:
	+ correct return code from set_files_to_edit() when no buffer can be
	  found or created.
	+ updates to vile.hlp:
	  a) refine w32pipes description as well as adding updates for
	     WinME/W2K
	  b) documented unmark-buffer
	+ doc/w32modes.doc now mentions WinME and W2K.
	+ add macros/gnugpg.rc, examples of using GNU gpg to encrypt/decrypt
	  a buffer.
	+ added &qpasswd, which solicits a password string from the keyboard.
	  Each typed character is echoed as '*'.  The password is not
	  recallable via vile's usual history mechanism.  This feature enhances
	  the security of the gpg macro wrappers (which have been successfully
	  tested on Unix and Windows).  The only fly in the ointment is the
	  brief time the passphrase is visible at the top of the buffer that's
	  being encrypted/decrypted.
	> Shawn Halpenny:
	+ add lisp syntax highlighter (lispfilt.l)
	> Tom Dickey:
	+ indent'd history.c, main.c, search.c
	+ add search.rc macro (based on discussion with clemens fischer
	  ).
	+ change a few places (search.c, eval.c) which used mlforce() to
	  display "Aborted" messages to use mlwarn().
	+ several changes to improve error handling in macros (prompted by
	  reports by Clark Morgan):
	  + modify run_func() to ensure that the pointer error_val is returned
	    on an error condition.  Previously the corresponding string "ERROR"
	    was returned rather than the special pointer value, preventing
	    run_func() from detecting operations on erroneous data.
	  + return error_val from run_func() if the built-in function
	    parameters were error_val, except for special cases such as the
	    &error function.
	  + add error-checking for divide-by-zero in ÷, and &modulo.
	  + return error_val from run_func() for built-in functions &dquery,
	    &qpasswd, &query if the user presses ESC to abort the input.
	  + check for ABORT return in prompts for missing macro parameters,
	    to cancel execution of the corresponding macro.
	+ modify hst_append() and related logic to store quoted tokens in
	  [History] if the eolchar is whitespace, and if the token contains
	  embedded whitespace or quote characters.  The tokens presented for
	  editing command history are dequoted.
	+ modify hst_append() to ensure that if the glue character is a return
	  or newline, then vile will interpret that as a blank to insert
	  between tokens.  This case happens when prompting for macro
	  parameters (reported by Clark Morgan).
	+ set umask before calling mkdir, in case user's umask has been
	  mistreated, e.g., by certain mail programs that remove execute-flags
	  from the umask.
	+ minor updates to configure script macros, for ncurses
	  (i.e., macros CF_CURSES_CPPFLAGS, CF_MAKEFLAGS, CF_NCURSES_CPPFLAGS,
	  CF_NCURSES_VERSION, CF_PROG_EXT).
	+ modify logic of popup-msgs to keep it from popping up [Messages]
	  before the end of initialization.  This would happen for example
	  if $pagelen were altered, since 9.2m change to set need_update
	  flag rather than call vile_refresh() for mode-settings which affect
	  the screen (report by Clark Morgan).
	+ add 'buffer' to the types of parameters which may be given in a
	  macro template (report by Clark Morgan).
	+ add logic to pl-filt.c to handle case such as the second pattern in
		if(/pat1/ || /pat2/)
	+ correct implementation of is_PREPRO() in pl-filt.c, which matched
	  "#!" rather than the documented C-style "# line  ".
	+ correct two problems in write_PATTERN() in pl-filt.c, noticed in
	  check_po script:
	  a) parse square-bracketed ranges
	  b) correct string address at the end of the loop.
	+ corrected expressions for strings in rexxfilt.l; backslash does not
	  act as an escape character.
	+ corrected special cases for $endtext and $rem in fdl-filt.l
	+ adjust ifdef's for strftime() to use it on win32.
	+ add several null-pointer checks in statevar.c
	+ use &default function to make vile-pager script a little more
	  portable with respect to the start-filename (report by Clark Morgan).
	+ implement &default built-in function, which returns the initial or
	  default value for modes and some state variables.
	+ rewrote global_val_init(), splitting out functions init_mode_value()
	  and init_state_value() to implement &default functions, which return
	  the initial/default value of the corresponding mode or state variable.
	+ reduce casts, fix signed/unsigned mismatch in prc2kcod().
	+ add missing ifdef around vl_atoul() in case no strtoul() is available
	  (report by Larry Gensch, on Tru64 5.1).
	+ modify ntwinio.c to check if the given argument list matches an
	  existing filename, and open that if so.  This allows one to use
	  SendTo to open files with blanks in their names.

 20010613 (n)
	> Tom Dickey:
	+ indent'd modes.c and os2vio.c
	+ implement show-error-expressions command, which shows more complete
	  information about the [Error Expressions] buffer.
	+ modify shmode preamble to accept a line such as
		#!/bin/sh --
	+ add a message to stderr in os2vio.c telling how to exit vile.  If the
	  OS/2 console version is run via telnet, it does not display anything,
	  and none of the screen-related functions return an error.  A message
	  is needed to guide a user to gracefully exit vile w/o rebooting the
	  system.  There is a small flicker when starting normally.
	+ add 'mouse' mode for OS/2 (CSet), to disable mouse when not wanted.
	  Modify logic in os2vio.c to sleep briefly in the loop polling the
	  keyboard and mouse, thereby reducing CPU time for that (report by
	  Paul Marwick ).
	+ widened ifdef for CSet error-expression, to make it useful when
	  building CSet applications with the OS/2 EMX version of vile.
	+ include  in file.c to make this build on OS/2 with CSet.

 20010523 (m)
	> Mark Robinson :
	+ when popup-menu is inactive, if text is selected, right-click copies
	  to w32clipboard; otherwise right-click pastes from w32clipboard.
	> Tom Dickey:
	+ replace the vile_refresh() calls in modes.c with need_update flag,
	  since vile_refresh() set sgarbf, which prevented _all_ screen updates
	  including messages.
	+ implement a simple example of macros to insert or display timestamps
	  for the current buffer (macros/dates.rc).
	+ modify prc2kcod() to recognize "M-" (meta) in combination with
	  other prefixes such as "#-", needed to parse KEY_F21 to KEY_F35 with
	  the termcap driver.
	+ change the octal character constants used in KEY_F21 to KEY_F35 to
	  decimal to avoid sign-extension.
	+ implement three functions for working with timestamps: &ftime, &stime,
	  and &date, respectively for file modification time, system time, and
	  formatted date/time.
	+ disable 'working' in writeall() while writing the output.
	+ two fixes for writeall() function: (a) don't use for_each_buffer()
	  macro to iterate, since the item referred to by the loop index moves,
	  making it possible to get an infinite loop, and (b) don't try to
	  write buffers which have not been loaded (the first was reported by
	  Brendan O'Dea; both bugs date to 1996).
	+ add commands "ww!" and "wall!", to respectively write all changed
	  buffers and write all buffers, using the "w!" behavior of ignoring
	  readonly file permissions.
	+ correct an out-of-order buffer flush for the strip_tabs logic in
	  sh-filt.l, which made the end of a here-document incorrectly colored.
	+ add a simple xml majormode.
	+ format lynx output in ShowFormatted to the screen width rather than
	  the default of 80 columns.
	+ improved perl syntax highlighting (pl-filt.c) by relaxing the
	  check for "=cut" to match perl's code rather than its documentation,
	  allowing for "{" "}" grouping around a regular expression, and
	  showing variables with Ident2 class.
	+ add a null-pointer check to slconv(), just in case (report by Mark
	  Robinson).
	+ implement bold/italic/underlined fonts in winvile (this is a first
	  cut, which occasionally has pixel trash when a bold or italic
	  character extends too far out of the normal font's bounding box).
	+ add a null-pointer check in sl_to_bsl(), since that is used, for
	  example, with a parameter from cfg_locate() which may return a null.
	+ indent'd path.c

 20010429 (l)
	> Clark Morgan:
	+ expanded description of "Favorites" in win32 section of vile.hlp
	+ if a multi-char map sequence includes a long timeoutlen-user value,
	  turn on the winvile cursor while waiting for keyboard input (bug
	  reported by Jason.D.Karney@clev.frb.org).
	+ modify ntwinio.c so that custom cursor manipulation code does not
	  show the cursor if the editor does not have focus.  This change is
	  required to support the aforementioned bug fix.  I've also seen
	  infrequent occasions where winvile still emits stray cursor glyphs.
	  This often occurs when I'm changing focus from some other app to the
	  editor via a mouse click.  I hope this latter change eliminates a
	  race condition within the editor.
	+ modify check in HighlightFilter macro to ensure that vile.exe also
	  must have w32pipes set to enable syntax highlighting.  This is a
	  necessary condition on W95/W98/WinME.
	> Tom Dickey
	+ indent'd buffer.c, file.c
	+ reimplement ":args" command to accept a filename expression.  If no
	  filename is given, as before it will show the buffer list, but if a
	  filename is given, it will replace the list of visible buffers with
	  those matching the expression.  Use ":args!" to discard changes
	  pending to one or more buffers (request by Vicki Brown).
	+ add hst_reset() function, called from main loop to reinitialize data
	  used for gluing portions of a command together for the [History]
	  buffer.  This addresses a problem reported by Clark Morgan where the
	  first time a ^WG!ls command was given, vile reported "No match for"
	  ls in the current directory.  This change by itself makes vile report
	  no matches all the time, because it was attempting to do
	  filename-completion on the "ls" string.
	+ add a special case in kbd_reply(), setting KBD_REGLUE to ensure that
	  when given the command ^WG!ls does not attempt to do
	  filename-completion on the "ls" string.  Though KBD_REGLUE was added
	  in 9.2c, it was not used, since the ^R fix relies on a different
	  part of the change.  This change uses KBD_REGLUE.
	+ fix highlighting of include's in c-filt.c, which did not allow a
	  blank in the filename.  Modify highlighting of filename to Literal.
	+ add a configure check for strtoul(), which was not available on
	  SunOS 4.x.
	+ updates to configure script macros:  CF_CURSES_LIBS (split-out
	  CF_CURSES_CPPFLAGS, add check for SunOS curses), CF_IMAKE_CFLAGS
	  (disable CDPATH during test), CF_NCURSES_CPPFLAGS (improve check for
	  ncurses headers), CF_NCURSES_VERSION, CF_TERMCAP_LIBS, as well as
	  newer config.guess, config.sub scripts.
	+ correct handling of backslash in htmlfilt.l, and highlight numbers
	  in that filter.
	+ fix a trailing comma in an enum in sed-filt.c
	+ quote filename in manpage.rc when it is used in shell commands, in
	  case it contains blanks or other special characters.

 20010407 (k)
	> Clark Morgan:
	+ update note in README.PC about problems with ActivePerl.
	> Tom Dickey
	+ add a check in zotbuf() to prevent a buffer from being deleted while
	  it is being executed as a macro (report by Paul Fox).
	+ fix a potential overflow of linebuf[] in ntconio.c
	+ fixes for ntwinio.c and ntconio.c to handle default color codes
	  properly.  The logic did not mask out unrelated bits from the
	  attribute field, did not apply bold and italic codes in the right
	  order to work with default colors.
	+ make manpage.rc work on win32, etc., assuming cawf is available as
	  a substitute for nroff.
	+ check imakemode before defmode.
	+ modify ntconio.c so control/@ is translated to ^@ on insertions
	  (reported by Clark Morgan).
	+ use SL_TO_BSL() to convert path separators to native form on DOS
	  and similar systems in the return values of builtin functions such
	  as &lookup, needed this to port manpage.rc
	+ improve bas-filt.l's rules for hexadecimal constants, add action
	  highlight for "_" used as a continuation marker, and show #date#
	  constructs as a string.
	+ accept ".cmd" as a suffix for batmode, resolving conflict with OS/2
	  by making it specific to the system.
	+ modify bat-filt.l to highlight the portion labels past 8 characters.
	  Only the first 8 are significant.
	+ modify bat-filt.l to handle '@' before any command, e.g., @rem.
	+ adjust ifdef's for OPT_FINDPATH to build with configure
	  --disable-extensions.
	+ modify ntwinio.c to recognize control/@ or control/2 as ^@.
	+ add ".exp" to tclmode, for 'expect' scripts.
	+ refine suffixes for rcmode to avoid conflict with names such as
	  .lynxrc

 20010322 (j)
	> Clark Morgan:
	+ added $findpath and $find-cmd state variables.
	+ on win32 and unix hosts, modified capturecmd (aka ^X-!) to support
	  find operations that span directory tree(s).   This feature is enabled
	  via a find-cfg mode.
	+ added a section to the help file entitled:
	    Working in a project hierarchy
	  which describes several features that enable quick access to many
	  files spread over a directory hierarchy.  Features discussed include:
	  - Directory navigation (the pushd, popd, et. al. commands).
	  - Hierarchical tags
	  - File/Directory traversal (win32/Unix hosts only)
		+ w32ole.cpp compiler warning fix.
		+ put ntwinio/ntconio msg strings in proper format.
		+ eliminate a couple of atoi() calls in random.c
	> Kevin Buettner:
	+ workaround for a Perl 5.005 bug in perl_prompt().
	+ several changes to shell.pm:
	  + some documentation updates
	  + bug fixes
	  + a new command called "xterm".  which starts a shell in one of
	    vile's buffers just as "start-shell" already does, but also
	    starts an xterm through which one may (also) interact with the
	    shell.  The shell output (and echoed input) is displayed in both
	    the xterm and a vile buffer.
	> Paul Fox:
	+ fix a typo in vile.hlp's example using bind-key for a space (report
	  by Clark Morgan).
	> Tom Dickey:
	+ change an inequality in read_quoted() which had the effect of
	  changing a null (^@) entered after ^V to a -1, preventing user from
	  inserting a null character (reported by Clark Morgan).
	+ correct a loop condition in put_majormode_after(), which caused a
	  core dump when an "after" qualifier referred to a majormode which was
	  not defined.
	+ add $majormode-hook, which can override the suffix/preamble rules
	  for choosing a majormode for the current buffer.  If the associated
	  script sets the majormode, the other rules are not run.
	+ implement new majormode submode "qualifiers", which can be set to
	  "all" to specify that both suffix and preamble must match.  This is
	  used to keep rcmode and vilemode from conflicting.
	+ add null-pointer checks to choice_to_code() and choice_to_name(),
	  guarding against unimplemented enum-tables.
	+ add syntax filters for Windows ".def" and ".rc" files.
	+ add Visual Basic majormode (vbmode).
	+ add syntax filter for BASIC, and majormode basicmode.

 20010304 (i)
	> Clark Morgan:
	+ elaborated on "apropos" and "describe-key" in macros.doc
	> Paul Fox:
	+ extended check-modtimes mode, necessitated by an interaction between
	  the new unique-buffers mode and check-modtimes.  The problem is this:
	  my current project lives in a tree that makes copious use of
	  symlinks.  This means that the name by which I edit a file may not
	  match the name by which "make" refers to the file when it reports an
	  error.  "unique-buffers" normally guarantees that I won't edit the
	  file twice in this case.  but if the file gets replaced, for example
	  with ":!co -l file.c"), then the inode will change on disk, but
	  vile's notion of the inode will not change.  this causes vile to
	  create a new buffer the next time make reports an error on it (with a
	  different pathname).  With this patch, if check-modtimes is on, then
	  when the file is reread, the inode (fileuid) info is updated, and
	  vile is again in-sync with the filesystem.
	> Tom Dickey:
	+ add/use code FILEC_WRITE2 to use in mlreply_file() to avoid getting
	  prompted about overwriting a file when using ":w! filename".
	+ add definitions so winvile.exe and vile.exe use utime() to set the
	  proper date on backup files.
	+ modify writereg() so that if the user specifies ":w!", and the file
	  is not writable, it will (try to) temporarily chmod the file for
	  writable access.  Note that the view-only mode overrides this
	  behavior, unlike vim (request by Igor Schein ).
	+ modify logic of read_argument() to force interactive input of
	  parameters which have not been specified in the command.  This allows
	  a user to write a macro which can be bound to a function key and
	  still prompt for parameter values.  Unlike the '@' response token,
	  parameters can be something more than an untyped string, e.g.,
	  file/directory completion (report by ).
	+ add a "directory" parameter type.
	+ change mlsave to a TBUFF, so popup-msgs will not show messages
	  truncated to NSTRING (143) columns.
	+ add $with-prefix variable which shows the prefix string in effect
	  from a "~with" or "~elsewith" directive.
	+ add $title-format variable which can be used to specify a customized
	  title for xvile or winvile.
	+ make swap-title option apply to any platform that sets window-title.
	+ modify makefile.wnt to check PROGNAME variable, which can be set
	  to override the target name, and the $progname state variable.
	+ add missing braces around a chunk of logic in api_command_cleanup(),
	  reported by antic.
	+ add ".vile" to suffixes for vilemode.

 20010224 (h)
	> Clark Morgan:
	+ fix some compiler warnings highlighted by change in 9.2g to use "-W3"
	  warning level in makefile.wnt (mktbls.c, ntwinio.c, w32oo.cpp,
	  wvwrap.cpp).
	+ fix bug introduced in getfile2bp() in 9.2g by compiler-warning
	  cleanup which broke ^X-e command.
	> Tom Dickey:
	+ modify definition of $progname so it can be redefined at build time,
	  allowing multiple versions of winvile to coexist.
	+ minor tweak to Clark's fix for getfile2bp() to fix the compiler
	  warning too.
	+ improved expressions for $filename-expr to avoid picking up ':'
	  unnecessarily.
	+ add an error expression for 'antic', which uses line and column
	  numbers, and correct column placement to account for tabs.  The
	  other expressions using columns were applied to listing files with
	  tabs already converted.

 20010217 (g)
	> Clark Morgan:
	+ rewrote much of the internals of winprint() and associated functions
	  were for better clarity and documentation (for the next person who
	  wanders through this code).  Corrected bugs and many FIXME's.
	+ text selection printing is now supported.
	+ if a formfeed is encountered in the text, the current page is
	  ejected.
	+ the "copies" and "collation" print dialog box options are now
	  supported regardless of the associated printer driver's capabilities
	  (or lack thereof).  The one exception is that uncollated text
	  selection copies are not permitted unless the printer driver provides
	  "native" multiple copy support.  In the event it's not possible to
	  print uncollated text selection copies, a message box is displayed
	  that notes the restriction and then offers a chance to continue with
	  collated copies.
	+ finish win32 copyright updates for 2001.
	+ if winvile's ntgetch() ignores a WM_TIMER message, dispatch the
	  message to a window proc that "cares".
	+ noticed that when incanting ":!ls | less" from within winvile, the
	  spawned console's close button is _not_ disabled if the shell
	  modifies the console title (a la bash).  Fixed for win9x hosts.  I
	  assume that the fix applies equally to NT and W2K.
	+ added bulletproof "string to [unsigned] long" conversion routines to
	  random.c (vl_atol and vl_atoul).
	+ substantially changed the implementation of vile's insertion cursor
	  interface.  Insertion cursor state changes are now handled in
	  update().
	+ added icursor (insertion cursor) mode for win32 hosts.
	+ added a boolean swap-title mode (win32 only).  If set, the editor's
	  title is displayed as " - " instead of the
	  usual " - ".  The former conforms with the
	  behavior of many win32 apps and is also much more useful, e.g., from
	  a screen real estate point of view, when many apps are resident in
	  the task bar.
	> Juan Carlos Gil Montoro 
	+ modify store_tag() function in tags.c to accept tags with qident
	  class rather than ident, that is, including colons as part of the
	  identifier.
	> Paul Fox:
	+ add setenv (set-environment-variable) command.
	> Tom Dickey:
	+ make current_undo_cookie have the same type as LINE.l_undo_cookie to
	  avoid spurious matches.
	+ add checks to finderr.c to ensure that line and column number are
	  actually numbers.
	+ correct logic in finderr.c which did not work properly if pattern
	  contained \( and \) delimiters.
	+ add pattern to finderr.c for Solaris lex.
	+ add patterns to finderr.c for Borland C++ (reported by Manish Bhobe
	  ).
	+ fix various minor things to make vile and winvile compile with
	  Borland C++ 5.5
	+ fix several unused-assignments reported by Borland C++ 5.5
	+ make statevar.c more compact using new functions any_rw_BOOL(),
	  any_ro_BOOL(), any_ro_INT() and any_ro_STR().
	+ change ifdef's for vl_atol() and vl_atoul() to make them independent
	  of __STDC__ value.
	+ indent'd undo.c
	+ reindented ntconio.c, ntwinio.c, random.c undo.c
	+ change most instances of 'unsigned long' to ULONG, etc., for
	  consistency.
	+ workaround in configure script macros to allow testing with autoconf
	  2.49c, which has broken the changequote() feature.
	+ fix a check in CF_CURSES_LIBS which caused the configure script to
	  assume it had found ncurses when it had not.
	+ update config.guess/config.sub to subversions version, which finally
	  includes OS/2 EMX.
	+ fix sh-filt.l to compile with lex that uses yytext array rather
	  than char* pointer, e.g., SCO OpenServer.

 20010122 (f)
	> Tom Dickey:
	+ several related changes to regexp.c:
	  + add first cut of logic for bounds (but see buglist).
	  + implement POSIX character classes and analogous escapes like \d to
	    make them more vile-like (prompted by discussion with George
	    Eccles).
	  + remove fallback for strcspn().
	  + indent'd
	+ work around NetBSD 1.5's use of MK symbol in curses.h (reported by
	  Matthias Buelow).
	+ add syntax filter for ECLiPSe, a dialect of Prolog (from Joachim
	  Schimpf ).
	+ modify sh-filt.l to recognize "<<-" marker beginning a here-document.
	  That tells ksh and similar shells to ignore leading tabs, including
	  when matching the final word of the here-document.
	+ fix some of the staircasing problems with curses.c driver by saving
	  and restoring the tty modes explicitly, so we can separate that
	  effect from the screen initialization that curses does (fixes a
	  staircasing in the usage message reported by Mikel Finch
	  ).
	+ add Verlog filter and corresponding majormode vlogmode (request by
	  Balekudru Krishna ).
	+ correct an 'awk' in configure.in that should have been $AWK.

 20010106 (e)
	> Clark Morgan:
	+ workaround for a bug in wvwrap observed on win96/winme.  wvwrap uses
	  COM to send this stream of commands to winvile:
		:cd \n:e \n
	  Playing with this a bit, I found that I could reproduce this problem
	  using these commands (sans wvwrap):
		[win]vile
		:cd \\remote_node\share_drive_name
		:e autoexec.bat           ; for example
	  [win]vile could not "open" the specified file and treated it as a new
	  file.  The problem persists even if forward slashes are used as an
	  argument to the cd command.  I don't know if this problem exists on
	  NT or W2K.  The fix is to pass filenames to fopen() in canonical
	  Win32/DOS format (i.e., paths include backslash delimiters).  I've
	  heard several developers say that the win32 version of fopen()
	  supports both forward and backward slashes.  Well, using VC5.0++
	  (SP3), I know of at least one case where that assertion is false.  In
	  addition, it was also necessary to ripple SL_TO_BSL() changes through
	  various system calls in write_backup_file(), due to the same observed
	  behavior.
	+ modify sh-filt.l to avoid coloring the white space that precedes the
	  ':' command.
	+ added basic win32 printing for winvile via these two new commands:
	       winprint winpage-setup
	  This feature is not currently available for console vile.  _Missing_
	  printing features include:
	  + ability to set printing font (distinct from display font),
	  + header/footer strings (footer currently hardwired as centered page #)
	  + printing of current selection
	  + collation for printer drivers that don't support this feature
	  + N copies for printer drivers that don't support this feature
	  + color and visual attributes
	  Tested on Win98/95 using an HP LJ4Plus and an HP DJ870CSe.
	+ added  "Print..." and "Page setup..." selections to winvile system
	  menu.
	+ when win32 common open/save dialog boxes are dismissed during a
	  console vile editing session, attempt to re-establish window focus
	  for the editor.
	+ found a way to disable a spawned console's close button (significant
	  winvile hole closed).  Thank you, Mr. Petzold.
	+ clean out a couple of bugs in buglist that were fixed long ago.
	+ in ntwinio_font_frm_str(), report win32 error(s) before making another
	  win32 API call (doh).
	+ in the remarks section of a number of Win32 API calls, I noticed
	  verbiage similar to this:
	      "Resources associated with a menu that is assigned to a window
	      are freed automatically.  If the menu is not assigned to a
	      window, an application must free system resources associated with
	      the menu before closing.  An application frees menu resources by
	      calling the DestroyMenu function."
	  Since winvile's popup menu is not assigned to a window, I added code
	  to clean it up.  If the verbiage above is to be believed, then
	  apparently "modern" Windows apps (i.e., post-Win 3.11) can still leak
	  system resources.  Oh my.
	> Tom Dickey:
	+ make check in filesave() for missing filename consistent with
	  writereg, which checked for internal filenames rather than simply a
	  missing name.
	+ add check in writeall() for attempt to write internal buffer such
	  as [unnamed], and show the buffer name rather than the empty filename
	  in the resulting warning message.
	+ add write-all-buffers command, to attempt to write all buffers
	  whether or not modified (request by Clark Morgan).
	+ modify adjvalueset() to allow users to set strings and patterns to an
	  empty value with 'unset'.  Previously, an 'unset' would always prompt
	  for a value, which had the effect of treating an empty response as
	  keeping the current global buffer or window value.  Note that
	  'unsetl' is unaffected.
	+ modify var_LCOLS() to avoid having the sideways value subtracted from
	  $lcols.  This is used in ^G (reported by Clark Morgan).
	+ change several entries in dcl.key to shorter abbreviations.
	+ add configure check for existence of /dev/tty, to work around broken
	  pty implementation on QNX: if one su's from root, /dev/tty is usable
	  while the pty (which ttyname() cites) is not.
	+ implement x-modifier parsing for perl expressions.  According to the
	  perl documentation, the '#' markers in Jim Crigler's example would be
	  treated as comments if there was a /x modifier.  vim does not check
	  for this.
	+ fix an infinite loop in pl-filt.c when parsing this example:
	    $rest =~ /^1\s+              # first action
		      (\S+)\s+           # date
		      (\S+)\s+           # time
		      ((?:\w|\s)+)\b\s+
	  The code was expecting the first "\s" on the last line to be
	  followed by a "+" sign or other meta character, and dithered between
	  eCODE and ePATTERN cases (reported by Jim Crigler).
	+ correct winvile command-line parsing:  single-quotes should
	  be considered part of the parameter.  Also, ignore empty
	  parameters, to allow scripts to use double-quoted
	  parameters, though note that SendTo under W2K automatically
	  double-quotes pathnames that require this.
	+ correct filtername compiled into vile-nr-filt, which did not match
	  nrmode.
	+ add popup-menu mode for winvile (patch by Mark Robinson
	  ).
	+ modify value for bindir in filters/makefile to exclude paths past
	  the first in $VILE_LIBDIR_PATH (reported by Chris Green
	  ).
	+ apply $CFLAGS/$CPPFLAGS change to CF_X_TOOLKIT configure macro.
	+ correct allocation size in OpenKeywords(), which was not long enough
	  (patch by Joachim Schimpf ).
	+ fixes to build on Windows 2000 (win2k) with perl 5.6.0, Visual C++
	  5.0 (mkprlenv.wnt, filters/makefile.wnt).

 20001206 (d)
	> Kevin Buettner:
	+ change default for $XSHELLFLAGS from "-c" to "-e", which matches the
	  documentation for $xshell-flags.
	+ make updlineattrs() even more efficient and also fixes a problem
	  with attributes not always being displayed correctly across adjacent
	  rows.
	> Tom Dickey:
	+ revert part of the PutChar() change from 9.2c, since it incorrectly
	  puts the cursor at the first character of a line after a "put"
	  (reported by Paul Fox).
	+ add/use BUFFER.b_inuse value to ensure that we do not recreate a
	  stored procedure that is currently being executed (reported by
	  George Eccles, Clark Morgan).
	+ add dummy parameters to invocation of tparm() to make this build on
	  HPUX and AIX which use the X/Open non-varargs prototype for that
	  function (reported by Jordan Henderson
	  ).

 20001115 (c)
	> Clark Morgan:
	+ minor updates to vile.hlp, macros.doc
	+ added select-all and selection-clear commands.  The former command
	  selects, highlights, and yanks all text in the current buffer to the
	  unnamed register.  The latter command removes a selection's
	  highlighted attributes.  Select-all is only available on hosts where
	  vile provides integrated mouse support.
	+ added "Select All" to winvile's right-mouse-button menu.
	+ added text to properly describe win32 bindings that use VK_DELETE
	  (delete key).  This is a bug fix.
	+ winvile's right-mouse-button displays the key bindings of all menu
	  items that are bound to vile commands (previously, only some bindings
	  were displayed).  The menu's key binding text is synthesized at
	  runtime.  This synthesis code was modified so that if there is no
	  binding, winvile displays nothing, rather than garbage (bug fix).
	+ stub in some commands for win32 printing.
	+ fixes for this problem reported by Richard Hussong
	  :
	    "Winvile sometimes appears to receive and process cursor-motion
	    events when the cursor is not in the window, even when it does not
	    have the focus.  The effect is that the Vile window scrolls.  I
	    have even seen this happen when the cursor was moved from one half
	    of a split Winvile window to the other - the window that the cursor
	    had just left started scrolling spontaneously.  Note that this
	    happens with no mouse buttons pressed."
	  * implement mouse capture a la Petzold's "Programming Windows 95".
	  * make sure timer is allocated before starting autoscroll.
	  * only autoscroll if WM_TIMER timer ID matches that of timer created
	    during autoscroll init.
	> Kevin Buettner:
	+ improve performance for very long syntax-highlighted lines
	  essentially converts a quadratic algorithm into a linear one.  It
	  also fixes the crasher you get when you change from linewrap mode to
	  nolinewrap mode where the first line won't fit on the screen.
	  (report by Clark Morgan).
	+ fix related problem where VASPCOL code was interpreted incorrectly as
	  VASPCOL | VASEL | VAREV, making add_line_attribute() consider this to
	  be a selection (due to VASEL being set) and forcing the attribute to
	  a buffer attribute (which it needs to be for selections.)
	+ add check in update() to make sure that movements in very long
	  wrapped lines get updated properly (reported by Clark Morgan).
	> Paul Fox:
	+ modify handling of select() in ttgetc() to check for out-of-band
	  conditions, to avoid looping on errors in stdin.
	> Tom Dickey:
	+ add check in vileperl.rc in case the server is still running, to
	  avoid error message (reported by Bruno Betro ,
	  discussion by J Chris Coppick and Clark Morgan).
	+ make corresponding changes for poll() in ttgetc(), as noted by Paul
	  Fox.
	+ fix two quirks of PutChar(), in line.c:
	  + yanking all of vile.hlp with yG, then putting (p) into an empty
	    buffer would put an empty line on the end, but remove the initial
	    empty line (reported by Clark Morgan).
	  + restore DOT to the original location after putting the text.
	+ modify treatment of pushed_back flag in kbd_reply() so it will force
	  the given partial result to be glued to the pushed-back string.
	  This fixes a problem using ^R to read the result of a shell command
	  (reported by George Eccles ).
	+ modify form of includes to be consistent, e.g., quoted includes for
	  vile's source files other than config.h which should always use
	  brackets (reported by Clark Morgan).

 20001104 (b)
	> Clark Morgan:
	+ add command dirs-clear, which clears dirstack and kills dirstack
	  buffer.
	+ add command dirs-add, which adds a directory to dirstack[top -1]; cwd
	  remains unchanged.  This command permits initialization of dirstack
	  via a macro and/or startup file.
	+ remove a state variable from ntgetch(), which could conceivably fall
	  out of sync due to calls to winvile_cursor_state() by other vile
	  modules.  This appears to fix a bug which would cause winvile's
	  cursor to vanish.  Switching to a different window would eventually
	  allow winvile's cursor to reappear (reported by Richard Hussong
	  ).
	+ update README for 9.2
	+ add caveat in doc/macros.doc regarding inline comments for commands
	  that accept optional parameters.
	+ update vile.1:  Add -i, -R, and -k to invocation switches.  Add a new
	  encryption section.  Note that vile's encryption is not compatible
	  with vim.  Remove reference to nonexistent -m switch (which was
	  supposed to encrypt/decrypt mail messages).
	+ document that write-file accepts an optional filename argument
	+ change $crypt variable so attempts to read it return the string
	  "[write only]" rather than the ERROR token.
	+ if last element is popped off dirstack and [DirStack] is the only
	  visible buffer, be sure to update [DirStack].
	+ add consistent error message delimiters for modules that I regularly
	  modify.
	+ when winvile spawns a dynamic console, the parent process ignores all
	  win32-supported signals until the console exits.  This prevents a
	  Ctrl+Break in the console window (for example) from rolling up
	  winvile.  Patch is based on code I recently noticed in the vim
	  sources.
	> Tom Dickey:
	+ add configure check for ispell or spell program, use that in spell
	  filter.
	+ add double-quote character to those not treated as part of a filename
	  in the default for $filename-expr
	+ add/use CharOf() macro to suppress sign-extension of char type on
	  platforms where this is a problem in ctype macros, e.g., Solaris.
	+ add variables $error-expr and $error-match, which show the last error
	  expression and the text it matched.
	+ expand ifdef's for pop_fake_win()/push_fake_win() to include the
	  tprintf() logic, making 9.2 build on VMS.
	+ change several configure macros to use $CPPFLAGS consistently for
	  preprocessor options rather than $CFLAGS.

 20001026 (a)
	> Clark Morgan:
	+ expanded description of 00-10-11 item in buglist (:!ls in winvile)
	> Tom Dickey:
	+ minor fix to sh-filt.l, adding default action for , which
	  is needed to match $'s.
	+ rename getcchar() to vl_getcchar() to avoid conflict with X/Open
	  curses function.
	+ correct change to imply_buf (9.1x), which resulted in reading each
	  file twice if implybuf was set true.  Only files that are being
	  written should be reread.
	+ update config.guess, config.sub to reflect changes at
	  subversions.gnu.org
	+ update some details in doc/dir.doc to reflect renaming, etc (reported
	  by Kevin Luu ).
	+ correct substitution of path to filters source-directory in
	  mk-2nd.awk, which did not take in account that 'configure' might be
	  invoked with an absolute path, so the $top_srcdir value also would
	  be absolute (reported by Kevin Buettner).
	+ correct regular expressions for configure script's option value of
	  --with-builtin-filters, probably broken in 9.1p when changing
	  genmake.mak to 3-column format (reported by Michael Finken).

Changes for vile 9.2 (released Tue Oct 17 2000)

 20001015 (za)
	> Clark Morgan:
	+ added pushd, popd, dirs.
	+ added ~trace/$debug documentation (taken from doc/macros.doc) to
	  Debug section of help file.
	+ made paragraph spacing in macros.doc consistent.  Fixed an instance
	  where the formatted text exceeded 80 cols with tabstops set at 8.
	+ when winvile is started from a shell, there are times when stdout and
	  stdin (and maybe stderr) have been redirected to handles that can't
	  be accessed by the running (GUI) process.  This is known to occur
	  with the CYGWIN shell(s) on a WinNT host.  Add code to get the proper
	  stdin/stdout handles, as well as ensure that the dynamically
	  allocated console doesn't use black text on black background.
	+ documentation updates: buglist item for winvile with :!ls
	> Brendan O'Dea:
	+ fix a couple more places with untying handles for Perl.
	> Tom Dickey:
	+ document known problems with curses.c driver

 20001010 (z)
	> Clark Morgan:
	+ fix a display glitch in w32_keybrd_reopen().
	> Brendan O'Dea:
	+ problem:  in Perl 5.6.0, some changes to the tied filehandle
	  mechanism break anything which attempts to re-open STDOUT/STDERR,
	  such as shell.pm as that now attempts to invoke the non-existent
	  method Vile::Buffer::OPEN .
	  Workaround: untie the handles before re-opening.
	> Tom Dickey:
	+ use new function SamePixel() to treat Pixel values as equivalent if
	  the difference between each of their RGB components is relatively
	  small.  Add a check for the default resource value of fcolor0,
	  forcing that to black if xvile's foreground does not look different
	  from white.  This makes some of the color palette commands, e.g.,
		:set cs=black
	  work properly.
	+ correct computation of 'diff' variable in tcapattr(), and add a check
	  for coincidence between strings that are used to turn off
	  corresponding video attributes.  The first error made vile turn off
	  the wrong attributes under some conditions, and the second would
	  cause it to omit turning back on attributes that it had inadvertently
	  turned off (reported by Clark Morgan).
	+ add imakeflt.l, to highlight Imakefile's.  Using c-filt.c was not
	  satisfactory because it did not treat quotes properly on comment
	  lines.
	+ minor fix to makefilt.l to treat "#include" as a comment.
	+ minor fix to vilefilt.l to prevent double-quoted text from spanning
	  multiple lines.

 20001005 (y)
	> Clark Morgan:
	+ update makefile.blc, add w32oo.obj
	+ when pasting to clipboard, use a less ambiguous status message.
	+ change global var that's used to detect when minibuffer is active.
	  Keying on "bminip" doesn't work in all cases.
	+ for winvile, allow clipboard paste via RMB menu into minibuffer.
	+ when pasting into minibuffer, don't report an error if an attempt is
	  made to paste more than one line.  Instead, clip the paste to a
	  single line.  This behavior mimics the action taken under similar
	  circumstances by nontrivial windows apps (e.g., Outlook and IE).
	+ initialize the winvile "Save As" dialog with the name of the current
	  open file.
	+ modify 'setv' logic to provide the current value of a variable when
	  setting it (request by Pedro Gomes).
	+ added the state variable $favorites, which returns the path to the Windows
	  Favorites directory.  On a Win95/98 host, this feature affects
	  console vile.  When console vile starts, the "launch cursor"
	  (combined pointer/hour glass cursor) is displayed for ~15 seconds on
	  a 166 MHz Classic Pentium host.  I would presume this is because the
	  console app is now linked with OLE32.LIB .  During this 15-sec
	  interval, normal vile operations are unaffected.  This effect does
	  not occur on NT hosts available for my tests (although they are a tad
	  faster than 166 MHz :-).
	+ added new file w32oo.cpp to vile's distribution.  This module
	  comprises a collection of Win32-specific functions that require a C++
	  (OO) compilation.
	+ winopen, winopen-nocd, winsave, and winsave-nocd now each take an
	  optional directory argument, which specifies the initial directory
	  opened by the Open/Save Win32 common dialogs.  If the optional
	  directory is not specified, cwd is used by default.
	+ added a "Favorites" menu selection to winvile's RMB menu, which
	  executes the command "winopen $favorites".
	+ shorten the path in set_directory()'s "Couldn't change" error message
	  if the complete text won't fit in the message line.
	+ on a win32 host, ":cd" is mapped to ":cd ~".  This change makes
	  win32 hosts compatble with VMS and Unix.
	> Tom Dickey:
	+ modify flt_putc() in builtflt.c to avoid incrementing line pointer
	  twice if the filter emits a newline before the actual end of line.
	  That could make the program count a line twice, for instance.
	+ implement name-completion for user variables, e.g., %foo.
	+ rephrase loop in purge_line_attribs() to handle the case where the
	  ending line-pointer is at the end of the buffer.  This makes the
	  ^A-NG command (clear-attributes-til) work when the cursor is on the
	  first line (reported by Christian Lindig).
	+ modify sh-filt.l to allow here-document tags such as containing
	  punctuation characters, e.g., "eof/".

 20000926 (x)
	> Clark Morgan:
	+ prevent autocolor from overwriting the message-line when '_' or ^X-_
	  have been pressed, but the subsequent buffer selection key has not
	  yet been pressed.
	+ for several select cases, when a long path causes message line text
	  to exceed the current window width, that path is shortened on the
	  left until the message text fits (if possible).  Those select cases
	  include failure to save a file, reading in a new file, and writing
	  out (or appending to) a file.
	+ document ":w >>filename" in vile.hlp
	+ report errors if user attempts to copy from mini-buffer.  The error
	  message only shows up if "pm" is enabled, since there's currently no
	  graceful way for a vile command to unwind execution from the
	  minibuffer context.
	+ allow pasting of one line of text into mini-buffer.
	+ improve makefile.l, don't add syntax attributes to the whitespace
	  embedded within these token sequences:
	     ([][]|\\\n)+(:|=)
	> Tom Dickey:
	+ correct default attribute in key-filt.c's color_of() function, which
	  made newlines colored as "Error".
	+ modify behavior of imply_alt() so that if the buffer already exists
	  and is not modified, it will be automatically reread.
	+ correct behavior of imply_alt() when the specified file is being
	  appended to.  Given ":w >>foo", it was making a buffer named ">>foo".
	+ add uppercase "TRUE" and "FALSE" to fsm_bool_choices[], so
	  assignments to boolean modes works properly within a macro (reported
	  by Clark Morgan).
	+ add %c and %l format types to finderr.c, which use 0-based offsets
	  rather than 1-based offsets (prompted by comments by Christian Lindig
	   that some tools use 0-based offsets).
	+ modify logic for name-completion in kbd_reply() to force the cursor
	  to the end of the input buffer before attempting to complete.
	  Otherwise, partial completions could be written in the middle of the
	  buffer.
	+ modify handling of motion commands in editMiniBuffer() to use NOMINI
	  flag rather than guess which commands with MOTION flag should not be
	  applied (fixes a bug report by Jim Crigler, which noted that 'h'
	  following '^G' was not treated as a cursor motion).
	+ add/use NOMINI flag to indicate commands that cannot be used in
	  minibuffer editing motions.
	+ use DisplayHeight() rather than 1000 for paneMaximum of scrollbars
	  in Motif version of xvile (report/analysis by Larry Gensch).
	+ add 'prefix=$(prefix)' to makefile.in where it recurs to filters
	  directory to accommodate older 'make' programs which do not inherit
	  options (request by Michael Finken).
	+ show unterminated quotes in sh, make and perl filters as "Error".
	+ correct handling of QUOTED (double-quote) state in sh-filt.l, which
	  did not interpret escaped double-quote or identifiers since one
	  pattern was too greedy.  Show escaped double-quote as "Action".
	+ correct SSTRING expression in sh-filt.l, which was assuming backslash
	  would quote other characters in a single-quoted string.
	+ change mapping in vileinit.rc for ToggleList and ToggleTabs to omit
	  the "execute-procedure" since that is no longer needed, and makes
	  the :history less useful.

 20000914 (w)
	> Clark Morgan
	+ macros.doc:  expand description regarding comment delimiters in
	  macros.
	+ fix vilefilt.l:  syntax attributes should not applied to leading
	  white space that precedes a macro keyword
	+ fix vilefilt.l:  most cases of trailing comments are rendered in the
	  "Comment" class attribute (new functionality).  There is one corner
	  case that's not handled, as described in block comments added to
	  vilefilt.l .
	> Tom Dickey
	+ modify htmlfilt.l to parse comments line-by-line, making it work
	  properly with Solaris' lex program which does not match newlines in a
	  pattern.  Solaris lex also is easily confused by RE's that look like
	  ranges but are not, such as "[^-\n"], and can only apply '+' to a
	  single-character RE (report by Jenny Brown ).
	+ add functions flt_begin(), etc., to filters.c to consolidate logic
	  in filters for attributing multi-line text as a single region.
	  Use this to simplify bat, make, perl, py, tbl, txt, xres filters.
	+ add a check for an empty table in fill_partial() to avoid buffer
	  overrun if caller provides incorrect parameter.
	+ correct a case in editMinibuffer() which did not completely restore
	  the buffer position when an error was found.  This led to passing
	  an empty buffer with an associated nonzero position to fill_partial(),
	  which dumped core.
	+ add &dquery function which prompts for input with a given default
	  value (request by George Eccles).
	+ indent'd exec.c
	+ modify logic in kbd_reply() a different manner, by adding a parameter
	  to get_token() which returns the actual eolchar matched, so that for
	  expressions such as "foo=x", we use '=' rather than 'x' for the
	  parameter to set_end_string() (reported by Clark Morgan).
	+ add a check for line length in editMinibuffer(), in case an
	  unexpected message such as the one in kbd_complete() from 9.1v wipes
	  out the current minibuffer.  The combination of the two caused a GPF
	  when typing ":set vis=off" (reported by Pedro Gomes
	  .
	+ modify kbd_complete() to only show the 'No match for ...' message if
	  it is run via a macro.  Interactive mismatches will just beep,
	  because a message would get in the way.
	+ modified bat-filt.l and tcl-filt.l to build with Solaris lex.  The
	  latter requires a larger tablesize (reported by Jim Crigler).

 20000905 (v)
	> Tom Dickey
	+ add check in CF_CURSES_LIBS in case $LIBS is already set to something
	  like "-lcurses -ltermcap".
	+ update config.guess, config.sub to 20000819 patch.
	+ modify tcl-filt.l based on examples by Juan Carlos Gil Montoro
	  :
	  + add namespace syntax to IDENT rule, and apply this to the IDENT1
	    rule as well.
	  + allow comments to have continuation lines.
	  + flag errors for badly-formatted numbers.
	  + treat {"} and \" specially (not as string literals).
	  + handle unterminated string, i.e., a newline ends a string even if
	    no quote is found.
	  + highlight trailing backslash as "Action".
	  + make a new class, "Braces" to control how curly braces are
	    highlighted, so this is not part of tcl-filt.l, but specified in
	    tcl.key
	+ modify logic in kbd_reply() to set last_eolchar from the given
	  eolchar, e.g., '=', rather than the current contents of execstr,
	  since that may contain an arbitrary character such as the first
	  one of an identifier.  That made commands such as
		setl autowrite=false
	  in a macro not work, since 'f' (false) was used (reported by
	  Clark Morgan).
	+ modify kbd_complete() to show a message when it fails to find a
	  match.
	+ relaxed suffix rule for vilemode to ensure that vile.rc is always
	  interpreted in that mode, even if it does not reside in a directory
	  named "vile" (reported by Clark Morgan).
	+ implement new Perl syntax filter, pl-filt.c (the older one is still
	  available for comparison, but is internally renamed to "pl" rather
	  than "perl").
	+ use tgoto() to simplify alternative to tparm() when formatting
	  escape sequence for colors in tcap.c
	+ suppress logic in tcap.c that resets colors when the terminal does
	  not support color.  Otherwise, reverse video and other non-color
	  attributes do not work (reported by Clark Morgan).

 20000828 (u)
	> Tom Dickey
	+ add error checks in sed-filt.c for unbalanced curly or square
	  brackets.
	+ make regular expression delimiters easier to read in sedmode by
	  coloring them with Action class.
	+ modify preamble expressions that match a pathname (e.g., "#!/bin/sh")
	  to allow trailing blanks on that line.
	+ correct preamble expression for sedmode, which interfered with shmode.
	+ correct syntax error in filters/filterio.c for stub functions used
	  for vilemode symbols (reported by Pedro Miguel Marrecas Gomes
	   and Jim Crigler ).

 20000828 (t)
	> Tom Dickey
	+ add stubs for dname_to_dirnum(), vl_lookup_func() and engl2fnc() to
	  filters/filterio.c, use those to provide hooks for vilemode when
	  configured for builtin filters to highlight unknown keywords.
	+ modify dname_to_dirnum() to treat any negative return from
	  choice_to_code() as D_UNKNOWN, restoring logic that warns about
	  unknown directives (reported by Clark Morgan).
	+ add sedmode, and corresponding syntax filter.
	+ rename some functions (line_count, filename, cd, help, source) to
	  use "vl_" prefix to avoid shadow-warnings from gcc.
	+ indent'd eval.c
	+ implement function &error, which returns true if its argument was
	  an ERROR token (i.e., internally error_val).
	+ add new TBUFF-oriented functions mlreply2(), kbd_string2() to wrap
	  kbd_reply().  These are needed to support &error, but would be useful
	  in making vile able to handle input data with nulls.
	+ modify TBUFF functions to check if error_val is copied to a TBUFF.
	  In that case, set a flag which makes tb_values() return error_val.
	+ fixes to recover if a 'source' command results in runaway recursion,
	  e.g., if foo.rc contains the line "source foo.rc".  In
	  perform_dobuf(), ensure that the line pointer we are using to restore
	  the buffer/window current line is actually in them, and add a
	  reference count in dofile() to avoid removing a buffer which is in
	  use for sourcing.
	+ corrected some places in makefilt.l and mms-filt.l which were writing
	  via yyout, which caused spurious characters to be printed with
	  builtin-filters.

 20000820 (s)
	> Clark Morgan:
	+ make Ian Jamison's change to w32pipe.c the default on all hosts,
	  tested in W95 and NT.
	> Tom Dickey:
	+ minor fixes to IDENT and VARIABLE definitions in bat-filt.l
	+ modify win32 scripts to eliminate redirecting standard output as
	  part of generating portions of makefiles, since that simply does
	  not work on w95 (reported by Clark Morgan).
	+ modify configure script to avoid using 'find', since OS/2 EMX's
	  'find' utility is a different program altogether (like grep).
	+ add configure --with-ncurses option, mainly for OS/2 EMX which has
	  an unusable termcap library.
	+ updated config.guess, config.sub from lynx 2.8.4dev.7 (now on my
	  ftp area as autoconf 2.13 patch 200000819, since I resync'd the
	  OS/2 EMX patch as well).
	+ refine fence-elif expression in shmode's "case" group, which allowed
	  a right parenthesis with only spaces before it to match (reported by
	  Clark Morgan).

 20000816 (r)
	> Tom Dickey:
	+ add logic to m4-filt.c to handle argument lists that span multiple
	  lines.
	+ highlight unbalanced quote in m4-filt.c as an error.
	+ modify majormode suffix matching to use the ignorecase mode values
	  for those systems that are normally case-sensitive, making this work
	  for names such as "FOO.BAT" which happen to be uppercase.
	+ suppress autocolor when doingsweep is true, e.g., in multimotion().
	+ add variable $filter-list to show all of the builtin-filters.
	+ modify win32 scripts to avoid redirecting the output of 'echo',
	  which apparently goes to stderr on w95 (reported by Clark Morgan).
	+ minor fixes for configure script macro CF_CURSES_LIBS,
	  CF_CURSES_TERMCAP, CF_SIZECHANGE, CF_TYPE_OUTCHAR, CF_UPPER,
	  CF_X_ATHENA from lynx, xterm and tin.
	+ newer config.guess, config.sub, from lynx 2.8.4dev.7
	+ fix starting condition of STRING in tc-filt.l
	+ add pcmode, for printcap.
	+ refine xresmode to require that mixed-case names match only in an
	  app-defaults directory, to avoid matching things such as MD5sums.

 20000809 (q)
	> J. Chris Coppick (with some advice from Brendan O'Dea):
	+ cleanup of Vileserv.pm and vileget (version 1.2)
	+ Vileserv now uses the registry, so 'perl "use Vileserv"' in
	  your .vilerc automagically adds the commands startserv, stopserv,
	  and vileserv-help.
	+ Vileserv tries to be smarter about finding your perl binary.  The
	  Vile variable %vileserv-perl-path can be used for customization.
	+ Vileserv tries to be smarter about the socket path that it uses.  The
	  env.  variable VILESOCK, as well as the Vile variable
	  %vileserv-socket-path can be used.  Also, vileget supports an option
	  for overriding the socket path.  The default location is still
	  ~/.vilesock.  With a little scheming, you can now run and control
	  multiple XVile sessions on one host, or use Vileserv on multiple
	  hosts with a shared home dir.
	+ Vileget now uses the -d option to change XVile's working directory.
	  This is an interface change from version 1.1, where the -c option
	  was used for this.
	+ Vileget now uses the -c and -C options for passing arbitrary Vile
	  commands to a running XVile.  See the vileget manual page ('perldoc
	  vileget') for more info on this.  Please note the necessary Vile
	  variable %vileserv-accept-commands.
	> Tom Dickey:
	+ improve PATTERN definition in awk, lex and yacc to color unescaped
	  blanks within a bracketed range.
	+ fix logic in flt_puts(), which did not ensure that regionshape was
	  set, and also remove spurious trailing blanks from attribute string.
	+ initialize static variables in several filters to make them work
	  properly in the builtin-filters configuration.
	+ change indent.pro to line up parentheses.
	+ add example macro AddError to vile.hlp which illustrates how to add a
	  string to [Error Expressions] (request by Christian Lindig
	  )
	+ modify win32 scripts which generate portions of makefile.wnt to not
	  rely on WinNT's "enhanced" shell for-loop feature, using new utility
	  program genmake.  Adjust generated builtflt.h on win32 to allow for
	  building C filters only, if no $(LEX) is specified.  Also, modify
	  makefile.wnt to avoid using && in recursion to work around
	  limitations of w95 shell (reports by Clark Morgan).
	> Ian Jamison:
	+ add workaround for broken DuplicateHandle() function on WIN2K,
	  ifdef'd with DUP_HANDLE_BROKEN_ON_WIN2K.  That caused
	  w32_inout_popen() to fail.

 20000728 (p)
	> Tom Dickey:
	+ add a mode for the Standard ML language.  There is also a minor tweak
	  to cpp.key (patch by Felix Advantage ).
	+ modify builtflt.c to treat record separators as newlines, consistent
	  with filter logic.
	+ rewrote filters/makefile.wnt to generate lists and rules using
	  scripts reading genmake.mak, to facilitate building internal or
	  external filters.
	+ change 1-or-more blanks in one of the error-finder expressions to
	  0-or-more to make this work with weblint.

 20000725 (o)
	> Clark Morgan:
	+ add example macro to vile.hlp from this-file-dir by Richard Hussong
	  but renamed to cdcur like Alex Wetmore's variation as suggested by
	  Paul Fox.
	+ if an NT console's display and buffer geometry are not the same, then
	  vile.exe's cursor defaults to the minimum size.  Modify so that the
	  editor's cursor size is inherited from the parent console window.
	+ correct glob test for "~" which can be expanded as user's home
	  directory for VMS and win32.  The test allowed expansion of tilde at
	  points other than the beginning of a path component, which can happen
	  on win32.
	> Tom Dickey:
	+ modify decode_exp() to skip over null pointers in the list
	  of subexpressions in regexp struct which are set when a
	  nested group was parsed, e.g., in the $filename-expr for
	  hgrep on win32.  The regular expression code finds the proper
	  number of \( \) atoms, but the array indices do not match,
	  causing ^X^X to fail (reported by Clark Morgan).
	+ correct missing check for backslash within a character range in
	  regatom(), which caused patterns such as "[^\[\]]" to match any
	  character other than left bracket which was followed by a right
	  bracket.
	+ implement 'highlight' mode, which when disabled prevents the
	  corresponding buffers from being syntax-highlighted (request by
	  Moo Kim ).
	+ add newsrcmode to prevent ".newsrc" file from being treated as a
	  shell script; otherwise every number in the file will be highlighted,
	  which is very slow for long lines (reported by Clark Morgan).

 20000710 (n)
	> Clark Morgan:
	+ enable tilde-expansion for win32 in glob.c
	+ modify spawncli() for win32 to ensure that a console window is
	  created for the ":sh" command when winvile is invoked from a GUI
	  rather than the command-line.
	+ add -console command-line option to win32 console vile to provide
	  workaround for make the mouse work when reading from stdin.
	+ update some win32-specific features in help file.
	+ copying to clipboard (via right mouse button) does not clear
	  selection (mimics expected win32 application behavior).
	+ undo/redo selections (via right mouse button) are context sensitive.
	> Tom Dickey:
	+ move special case for literal ^A in syntax-highlighted text into
	  flt_putc() so other filters that happen to find a control/A will echo
	  it as two characters, to work with the logic in parse_attribute().
	+ add reset-majormode command, which tells vile to recompute the
	  appropriate $majormode for the current buffer (prompted by a report
	  by Shawn Halpenny who was constructing a temporary buffer which had
	  no majormode associated -- setting the filename temporarily would
	  allow this command to set the majormode).
	+ revert binding change in editMinibuffer() so that vi-like commands
	  such as B, e, $ will work again in ^G mode (reported by Jim Crigler
	  ).
	+ small fix to allow sccsfilt.l to build with flex 2.4, which did not
	  define YYSTATE (on FreeBSD 2.1.5).

 20000627 (m)
	> Clark Morgan:
	+ small fix for doc/macros.doc
	> Tom Dickey:
	+ initialize $xshell-flags to empty string since xshell.sh does not
	  accept a "-c" parameter.
	+ modify manpage.rc to unset the filename associated with the buffer so
	  it does not display.  This ensures that the ruler is always visible.
	+ add command unset-variable, which resets the given variable to a
	  null or default value.  This is useful only for the $-variables,
	  since modes require a value.
	+ modify color support in xvile to allow the pre-8.3s color scheme as a
	  special case:  setting bcolor to fcolor makes xvile use the bcolorN
	  resources on syntax-highlighted text rather than the color selected
	  by bcolor (which is actually taken from the fcolorN resource in this
	  case).  This uses a new function get_color_gc() to simplify caching
	  of GC's (report by Dave Turner )
	+ remove some logic from x_fcol() from 8.3s (990914) which mirrored
	  x_bcol().  That broke the behavior of "set fcolor" (noted while
	  investigating Dave Turner's report).
	+ adjust filters/mk-0th.awk to work with SGI's nawk.
	+ fix typo in configure macro CF_CHECK_ERRNO (reported by John Coyne
	  ).
	+ translate soft hyphens to '-' in manfilt.c
	+ treat leading (unary) backslash in perlfilt.l as an operator, not
	  as an escape.
	+ add makefile dependency so "make vile" works when --with-builtin-filters is
	  used.

 20000617 (l)
	> Kevin Buettner:
	+ updates to config.guess and config.sub and resync with version from
	  PCRE 3.2
	> Tom Dickey:
	+ update ftp and web-site pointers to reflect demise of ClarkNet
	  (reminder by Clark Morgan).
	+ use new function search_mode_list() to make binary search of the
	  my_mode_list[] array, to make it faster, since strcmp calls when
	  searching this array were the largest component in initializing
	  majormodes.
	+ correct length computation in finderr.c for %F token, which caused
	  heap corruption on win32 (cf: 9.1d).
	+ use $majormode rather than file suffix in manpage.rc to check for
	  HTML files, since the suffix is too easily confused by double-dot
	  suffixes.

 20000609 (k)
	> Tom Dickey:
	+ add command attribute-directly, to invoke internal filter on the
	  current buffer.  External files are still used for the keywords, but
	  this can eliminate the subprocess and pipes for filters that are
	  built-in.
	+ add built-in function &filter, to tell if the given majormode has
	  a built-in filter.
	+ show majormode ordering in the subheaders of show-majormodes.
	+ rewrite put_majormode_after() and put_majormode_before(), fixing
	  a potential infinite loop.
	+ modify manpage.rc to use lynx to render html files.  This uses the
	  development version of lynx (2.8.4dev.3, with the -stdin and
	  -with_backspaces options).
	+ check timode suffixes before shmode.

 20000529 (j)
	> Tom Dickey:
	+ fixes to make shell commands work properly with curses.c driver:
	  remove unneeded term.kclose from one version of ttunclean
	+ allow whitespace after '<<' that begins here-document in perl filter.
	+ modify suffix qualifiers for shmode and vilemode to make most dot
	  files that end in "rc" in shmode, unless the filename contains the
	  string "vile".
	+ add error-checks for init_pair() calls in curses.c (bug report by
	  Brendan O'Dea).

 20000519 (i)
	> Tom Dickey:
	+ use $cmd-count in AlignToCol to align more than one line at the
	  cursor's column.
	+ modify logic of $cmd-count to increment only for the topmost level
	  of dobuf() nesting.
	+ update ifdef's for building with SMALLER defined.
	+ add key binding for select mode, use that rather than insert mode
	  binding.
	+ correct parameter of bkgdset() in curses.c for Solaris curses.

 20000517 (h)
	> Tom Dickey:
	+ add key binding functions for insert-mode and command-mode, making it
	  simpler to bind a space or tab to a given function without having it
	  confused for a function while in insert mode.  New commands:
	  bind-cmdmode-key, bind-insmode-key, describe-cmdmode-bindings,
	  describe-cmdmode-key, describe-insmode-bindings,
	  describe-insmode-key, rebind-cmdmode-key, rebind-insmode-key,
	  unbind-cmdmode-key and unbind-insmode-key.  (fixes problems
	  introduced in 9.1, reported by George Eccles and Sean Ahern)
	+ implement a curses/ncurses terminal driver.  Use --with-screen=curses
	  or --with-screen=ncurses to configure this.  No mouse is supported
	  in this configuration.  This version builds only with SVr4 curses
	  or ncurses.
	+ accept -i option as an alias for -I, which has the added benefit of
	  allowing vile to be used as a $SHELL value for script, since that
	  passes a -i option to the "shell".
	+ change logic of dobuf() to implement the repeat-count there, rather
	  than the callers.
	+ add variable $cmd-count, which tracks the number of times a macro is
	  repeated by prefixing it with a repeat-count.

 20000501 (g)
	> Brendan O'Dea:
	+ prefix the "source ~/.vilerc" in vile-pager with "~force" in case
	  a user has no such file.
	> Tom Dickey:
	+ add macros/shifts.rc, which implements left/right shifting of words
	  in the current line to align with the cursor.
	+ reset DOT.o after calling deltoeol() in lrepltext().  This fixes a
	  problem with setting $line; the reinserted newline would fall after
	  the first character of the following line.
	+ save/restore window traits, setting DOT to the end of [Trace] when
	  writing into it with tprintf().  Otherwise tracing was writing at
	  the current location, and the buffer would scroll as data was written.
	+ two fixes for vile_op(): correct parameter for no_such_function()
	  when processing a macro, and consistently use f_godotplus to handle
	  missing or unknown motion parameters in a macro.
	+ set/clear reading_msg_line in pressreturn() to avoid autocolor
	  repainting the screen just after a shell command.
	+ add color-ls.rc, example using improved manfilt.c to display color
	  ls output in a buffer.
	+ improve decoding of ANSI escape sequences in manfilt.c, including
	  parsing of foreground colors.
	+ add $xshell-flags variable to allow customising $xshell (request by
	  Ian Jamison).
	+ remove $(LIBS) from filters/makefile.in to fix linking problem on
	  Debian.  The alternative is to add $(X_LIBS), which seems unneeded
	  for ecrypt.c and manfilt.c, which use only standard C library
	  functions.

 20000425 (f)
	> Brendan O'Dea:
	+ fix unquoted '^' character from 9.1e configure script changes.
	+ mods to build with Perl 5.6.0, which now requires that all perl
	  globals need a PL_ prefix (which affects `errgv', `na' and `sv_undef'
	  in perl.xs/ptypemap).  The change is backward compatible to 5.005 and
	  *should* be to 5.004 (untested).
	> Clark Morgan:
	+ modify joinregion() to refrain from modifying an empty region, i.e.,
	  where the start/end lines are the same.
	> Tom Dickey:
	+ add reset-rgb-palette command for winvile.
	+ add set-rgb-palette command for winvile (adapted from a patch by Ian
	  Jamison ).
	+ install Vileserv.pm without executable permissions (reported and
	  suggested solution by Brendan O'Dea).
	+ change an "ls -1" to "find" in configure script, to work around
	  nonportability to SVr3 (reported by Brendan O'Dea).
	+ add :g! and :v! as synonyms for :v and :g, respectively.
	+ modify bat-filt.l to highlight variables that are set or used in
	  a script.  also, highlight quoted strings.
	+ fix double-quotes with continuation lines in esqlfilt.l
	+ corrected wildcard patterns for dos/win32 in vileinit.rc
	+ add '#' to URL patterns in syntax filters.
	+ implement abbreviations for syntax keywords, using '*' as the
	  default delimiter.
	+ add vimmode, for vim syntax files
	+ implement $filename-ic, to use in filters.rc to avoid matching
	  xresmode for systems that have case-independent matching for
	  filenames.
	+ make configure macros that search for header- and library-paths a
	  little more general, e.g., searching under /usr/foo/lib or $HOME/foo,
	  from tin updates (i.e., macros CF_FIND_LIBRARY, CF_HEADER_PATH,
	  CF_LIBRARY_PATH, CF_NCURSES_LIBS).
	+ update config.guess, config.sub
	+ add a 'depend' rule to makefile.in
	+ update ne*.h rules in makefile.blc

 20000318 (e)
	> Tom Dickey:
	+ add configure --with-builtin-filters option.  This is only to test
	  the build scripts; the builtin filters are stubs.
	+ add cindent to awkmode.
	+ correct awk-filt.l - it did not echo curly braces.
	+ add '^' at beginning of pattern for hgrep in finderr.c
	+ correct index for W_FILE in finderr.c for %F token, omitted in
	  changes for 9.1d (reported by Clark Morgan).

 20000314 (d)
	> Brendan O'Dea:
	+ modify perl.xs to allow perl operators to be used with a range.  Also
	  clears the VIEWOK flag for operators.
	> Clark Morgan:
	+ winvile:  turn off cursor during menu-based cut/delete/paste ops
	  (avoid stray cursor glyphs).
	+ winvile:  fix repaint bug that was introduced when "fixing" the
	  occluded notepad update bug in 9.1a.
	+ fix winvile ":sh" command, which used to pop up a separate window,
	  but does not as of 9.1 In 9.1, ":sh" on a win32 host is executed as
	  "$shell {-c|/c} $shell" .  As it turns out, cmd.exe's intrepretation
	  of the /c switch is to run the specified command and exit
	  immediately.  The fix is to simply launch $shell via CreateProcess().
	> Tom Dickey:
	+ modify SetVarValue() to make it handle mode values, which were being
	  ignored.  This makes
		~local report
	  work properly (reported by Clark Morgan).
	+ add variable $filename-expr, to specify the actual pattern used for
	  %F in [Error Expressions].  On DOS and Win32, this is initialized to
	  a more complex pattern, to accommodate drive letters.
	+ allow invisible buffers such as [Trace] to be the error-buffer.
	+ add macro command "~trace", which sets or reports the value of the
	  $debug variable.
	+ modify treatment of $debug to trace into internal buffer [Trace].
	+ fix ifdef's in btree.c to disable assert's when not debugging.
	+ improve sqlmode preamble, making it more distinct from batmode.
	+ improve cshmode complex fence patterns for foreach and switch.
	+ revert the change to ffgetline().  For some reason, fread() runs more
	  slowly when vile is rendering a manpage than fgetc().  Change all
	  fgetc() and fputc() calls to getc() and putc(), since as macros they
	  generally will run faster than the functions, as noted by Clark
	  Morgan.
	+ correction to 9.1c's change for shpreamble: it omitted a '?' (0/1)
	  around the options pattern.

 20000228 (c)
	> Clark Morgan:
	+ added cut-to-clipboard (windows Cut) and delete-text-selection
	  (windows Delete) to [win]vile.  The former is bound to Shift+Delete,
	  the latter to Alt+Delete.  Both commands require a current text
	  selection.
	+ bug fix:  winvile geometry only shown when window is resized :-).
	  Prior to bug fix, geometry also shown during a window move.
	+ added a winvile `about' box (available from the System Menu).
	+ winvile's right mouse menu includes these new commands:
	    cmd name  bound to                        txt slctn  txt slctn must
							 rqd?    be in curbuf?
	    --------  --------                        ---------  -------------
	    undo      undo-changes-backward
	    redo      redo-changes-forward
	    cut       cut-to-clipboard                    X           X
	    copy      copy-unnamed-reg-to-clipboard       X
	    paste     paste-from-clipboard
	    delete    delete-text-selection               X           X
	  All but undo and redo are context sensitive.
	+ documented that ~local doesn't save/restore mode vars (this is an
	  assumption on my part).
	+ beefed up example vile.rc with more macros and removed outdated
	  color syntax macro.
	+ optimize ffgetline(), buffering data read from fread() rather than
	  via fgetc().
	+ add to vile.hlp more information about installing vile, particularly
	  the effect of $VILE_STARTUP_PATH and $VILE_LIBDIR_PATH
	+ fix a redundant screen repaint for this scenario with the termcap
	  configuration:
		$ vile /etc/termcap
		:stop
		$ fg %1
	> Tom Dickey:
	+ converted most occurrences of yyout in the filters to calls into
	  filterio.c that do not specify a FILE*.
	+ split-out main program and I/O from filters.c as filterio.c
	+ modify filters.c to avoid concatenating $HOMEDRIVE when $HOME already
	  specifies the device in home_dir() (reported by Richard Hussong
	  ).
	+ further narrow the scope of insert-exec by excluding all whitespace,
	  to avoid interpreting tab and formfeed.
	+ add mode insert-exec to control logic in ins_any_time() which
	  interprets control characters which are bound to GOAL or MOTION
	  commands rather than inserting them without quoting (see 9.0a and
	  9.0b changes).  This restores the default behavior, since some users
	  had control characters bound to a function which was then executed
	  (reported by George Eccles and Christian Lindig).
	+ modify which-source and which-exec to always show the places where
	  vile searches, even if not found (suggested by Clark Morgan).
	+ modify shmode prefix pattern to allow "-" alone as an option, rather
	  than requiring it to be followed by a letter.  This is done in
	  Linux's MAKEDEV script.  Also, corrected parenthesis in the pattern
	  to make a ":" line recognized as a shell comment.
	+ correct logic for &left and &middle functions, which returned one too
	  many characters after 8.3d changes to use TBUFF's (reported by
	  (William Yuan )
	+ correct modetbl entry for &sless function, which was returning a
	  string rather than a boolean (this was broken between 8.2 and 8.3).
	+ add a check for the base parameter of mk_to_vcol(), in case it is
	  negative (reported by Clark Morgan).

 20000210 (b)
	> Kevin Buettner:
	+ x11.c (x_preparse_args): Set window manager resize hints.
	  (x_configure_window): Removed code for setting window manager
	  resize hints.  Also added code to avoid BadMatch errors
	  when window is too small.
	> Paul Fox:
	+ implement a new mode, "unique-buffers", which does dev/inode checking
	  to be sure files aren't edited more than once.  this differs from
	  "resolve-links" in that a) the "true" filename may never be
	  discovered -- vile will use the first name its given for a given
	  file, b) it detects hard links, and c) it's a lot faster.
	+ shorten the confirmation questions/messages that result from modtime
	  checking.  with very long buffernames the current messages extend
	  past the 80 column boundary, making the tail end of the question
	  invisible in some cases.
	> Clark Morgan:
	+ add a pin-tagstack mode, which prevents the editor from switching
	  windows during a tag/push operation (i.e., all tag ops are pinned to
	  the current window).  By default, this mode is not enabled, which
	  ensures backward compatibility with previous editor behavior.
	+ modify ntwinio.c to continuously show the geometry during a resize.
	+ ifdef'd use of auto_set_title to compile x11.c on VMS.
	+ update README.PC's description of vile search-paths.
	> Tom Dickey:
	+ annotate the verbose form of which-source and which-exec, showing
	  the corresponding variable for each path which is tested, e.g.,
	  "$PATH" when checking items in $PATH.
	+ add $exec-path variable
	+ modify filter modules so they export only one variable (filter_def)
	  to simplify building a library for built-in filters.
	+ change ntscroll() to use RedrawWindow() to repaint the update-region
	  after ScrollWindowEx() - works no worse on my home machine, will
	  re-test at work: the problem to fix is incorrectly-shifted text when
	  scrolling via repeat-keying j/k.
	+ change position (^G) command to show "File is empty" if the current
	  buffer is empty, rather than "Line 1 of 0 ..." (reported by Clark
	  Morgan).
	+ correct char_no() function to use record-separator length, so
	  $curchar is evaluated properly for dos files (reported by Clark
	  Morgan, for ^G command).

 20000130 (a)
	> Kevin Buettner:
	+ gdb.pm:  New file.  Runs gdb in a vile window and tracks changes in
	  editor.  (Must be used with shell.pm.)
	+ shell.pm (terminal_emulation): Fixed bug which was preventing
	  ESC [ Pn B from moving down lines.
	  (shell, clean_resume_sub): Improve workaround for perl crasher.
	  (dead): Fetch parameters.
	+ estruct.h (OPT_LINE_ATTRS): Define.
	  (LINE): Added new member l_attrs.
	  (LINE_ATTR_ENTRY): New structure typedef.
	+ edef.h (line_attr_tbl): Hash table for line-based attributes.
	+ proto.h (lattr_shift): New function.
	+ select.c (lattr_shift, free_line_attribs, add_line_attrib,
	  purge_line_attribs, init_line_attr_tbl, find_line_attr_idx):  New
	  functions which implement the guts of the new line-based attribution
	  mechanism.
	  (free_attribs): Call free_line_attribs().
	  (attributeregion):  Call add_line_attrib() and purge_line_attribs()
	  as appropriate.  Also reindented this function.  [I thought I was
	  going to have to make more extensive modifications than I did.]
	+ file.c (quickreadf): Initialize l_attrs.
	+ line.c (lalloc): Likewise.
	  (linsert, ldelete): Call lattr_shift() to adjust l_attrs.
	  (ltextfree, lnewline, ldelnewline): Free (and null) l_attrs.
	+ undo.c (lineundo, repointstuff): Likewise.
	+ api.c (lreplace): Likewise.
	+ display.c (updattrs):  Call updlineattrs().  Also split out code into
	  which sets the attributes in vscreen into...
	  (mergeattr): New function.
	  (updlineattrs): New function which decodes attributes associated
	  with the l_attr member of the LINE structure.
	+ makefile.in (gdb.pm): New perl file to install.
	+ select.c (attributeregion, add_line_attrib): Fix bugs preventing
	  hypertext commands from working.
	+ display.c (updlineattrs): Stop processing attributes if end of
	  buffer is reached.
	> Clark Morgan:
	+ fix the winvile repaint bug that I reported last week.  Problem was
	  caused by code in ntscroll() that was clearing 95% of the ClientRect
	  after the scroll operation.  I would never have figured this out
	  except by looking at traces generated by the extremely useful TRACE
	  facility (I find it impossible to debug paint problems using a local
	  debugger).
	+ additionally, unhandled/ignored scrollbar messages don't trigger an
	  update(), thus precluding two updates for each scrollbar operation
	  (e.g., one update for SB_LINEUP, followed immediately by another
	  update for SB_ENDSCROLL).
	+ implementation of term.typahead for ntwinio.c
	+ remove apparently unused kbhit and khit functionality. in ntwinio.c
	  (amended by Russ Schnapp).
	+ clarify build instructions for win32+perl configuration in README.PC
	  (from report by Russ Schnapp ).
	+ documented some of the new 9.1 features (which included adding a new
	  Debugging section)
	+ fixed some typos in vile.hlp
	+ expanded/corrected some old features in vile.hlp
	+ integrated "Command files" topic a bit more with "Invocation" topic
	  and streamlined the latter in vile.hlp
	+ used more precise wording in Credits (which triggered a large change).
	+ update buglist to reflect vms_ffexists() changes.
	+ fix bogus comment in w32reg.c
	+ win32 console vile now has "true" autoscroll support (this feature
	  based on Ed Henderson's work).
	+ win32 console vile's mouse-based text selection (via LMB) modified to
	  fairly closely mirror winvile's features, except that a single click
	  does not clear the current text selection (a la notepad).  The most
	  significant change is that text selection is not initiated until the
	  mouse has moved at least one character cell in either the X or Y
	  coordinate.  This change precludes the editor from discarding the
	  contents of the unnamed register due to a simple mouse click, as
	  opposed to an actual mouse move.
	+ fix:  If the user releases the left mouse button (LMB) outside
	  winvile's main window following an autoscroll operation, no text is
	  copied to the unnamed register.
	  This patch doesn't yank to the unnamed register if the user resizes a
	  window via a mode line drag.  In addition, this patch fixes another
	  problem:  if the mouse cursor is moved to the message line and then
	  LMB is held down, autoscroll starts in the current window _and_
	  cursor glyphs are dropped in same during the scrolling.
	+ document $error-buffer in macros.doc
	+ update README for 9.1 release.
	> Tom Dickey
	+ modify which-source, which-exec to be consistent with other commands
	  that use the existence of a repeat count as a flag, not whether it
	  it bigger than one (reported by Clark Morgan).
	+ modify filters, eliminating write_string() function which
	  accommodated pre-9.1 restriction of vile for completing each
	  attribute on one line.  Now, filters attribute multi-line regions
	  when appropriate, e.g., multi-line comments in C.
	+ correct a typo in txtmode's suffix qualifier for ChangeLog.

Changes for vile 9.1 (released Sat Jan 15 2000)

 20000115 (t)
	> Clark Morgan:
	+ fix a file-descriptor leak in win32 pipes.
	> Tom Dickey:
	+ small compiler warnings (using 'antic' and SGI's lint)

 20000114 (s)
	> Kevin Buettner:
	+ perl.xs (do_perl_cmd):  Partially revert changes from 9.0p regarding
	  the clexec/isnamedcmd/no_msgs flags.  We (once again) set isnamedcmd
	  to TRUE in order to cause mlreply_dir and mlreply_file to prompt the
	  user when a perl command is invoked via a key binding.
	  (mlreply_no_opts): Remove.
	  (mlreply): Make mlreply_no_opts and mlreply_shell aliases with
	  slightly different functionality.
	+ perl/capture.pm:
	  + New documentation.
	  + New command, async-capture-command, for displaying
	    the documentation.
	  + Use mlreply_shell in order to provide the appropriate shell
	    completions (requested by Paul Fox)
	  + Remember last command run (requested by Paul Fox)
	  + Added work-around to prevent [Buffer not found] message from
	    displaying when Vile::Buffer::edit is asked to find an internal
	    buffer.  (Does getfile2bp really need to call mlforce() to print
	    this message out?)
	+ perl/shell.pm:
	  + New documentation.
	  + New command, shell-help, for displaying the documentation.
	  + Handle partial (incomplete) terminal control sequences.
	    [Fixes bugs reported by Paul Fox.]
	  + gdb annotation support.  (Use --fullname with gdb to make
	    use of this.)
	  + Facilities for supporting upcoming gdb.pm.
	  + Revise mechanism for escaping from shell.  (Expect it to
	    be revised even more though.)
	> Clark Morgan:
	+ modify mailmode to support mutt's temporary file names
	+ modify nttypahead() to exit immediately during an autocolor operation.
	+ add section on 'Color Basics' to vile.hlp, integrated/revised with
	  description of color syntax highlighting (with feedback from Brendan
	  O'Dea and Paul Fox).
	> Tom Dickey:
	+ modify suffix qualifiers of cshmode and mailmode to avoid matching
	  directory names.
	+ corrected status checks on return from prompt_scheme_name(), which
	  may be ABORT (reported by Paul Fox).

 20000112 (r)
	> Kevin Buettner:
	+ correct two variables in perl.xs which were incorrectly typed as
	  'int', and passed by reference which is a problem on Tru64 Unix 5.0
	  (Alpha) where the prototype specified 'unsigned long' (reported by
	  Larry Gensch )
	> Clark Morgan:
	+ update credits in vile.hlp (with additions from Paul Fox).
	+ updated w32modes.doc
	+ remove very stale documentation/comment from c-filt.c .
	+ add -q switch to filters.c, which forces the filter to exit as soon
	  as it reads its first line of input.  Useful in conjunction with -v
	  and -vv switches.  Necessary for Unix vile (but not win32 vile) if
	  you want to do this:
	      ^X-!~/.vile/vile-c-filt -vvq
	  without hanging the editor's keyboard and forcing the user to type ^C
	  to kill the child process.
	+ fix a 250 millisecond dead spot built into the winvile autoscrolling
	  computations, and also throttle back the initial rate of scrolling so
	  that the user has a chance to read the text as it moves up/down the
	  screen.
	+ reword/correct the description of searching for .keywords files in
	  doc/filters.doc
	> Tom Dickey:
	+ modify ins_anytime(), allowing undoable commands to be executed
	  within an insertion (Clark Morgan stated that the winvile
	  paste-from-clipboard used to work in insertion mode).
	+ correct logic of gotoeosent(), which would skip past the end of the
	  current sentence (which ended at the end of a line), over following
	  blank lines, to the end of the next text line.  Now it skips into the
	  beginning of the first line following the sentence.  A following call
	  will skip the blank lines to the beginning of the next text line
	  (reported by Clark Morgan).
	+ add README*, CHANGES*, ChangeLog* and COPYING to txtmode suffix
	  qualifier.
	+ modify makefilt.l to flag as an error lines that start a quote but
	  do not end it.  Some make programs allow this.
	+ modify suffix qualifiers for imake, mail, make, vile majormodes to ensure
	  they do not match directory names such as /mail/.
	+ modify directive_arg_eval() to expand "~/" expressions for non-UNIX
	  systems, making "so ~/vile.rc" work within a source'd file on WinNT
	  (reported by Clark Morgan).
	+ modify install rule for Vileserv.pm to ensure we update the path
	  of the perl program embedded in that script.
	+ modify vileperl.rc so the terminfo/termcap version does not start
	  the edit-server.
	+ add a null-pointer check for wp in AutoScroll().
	+ modify previndent() to refrain from copying previous indent over a
	  line beginning with '#' if cindent is disabled (reported by Clark
	  Morgan).
	+ change show-colors command to reflect limited number of colors if
	  $ncolors is set to 2, 8 or 16.
	+ modify set_colors() to allow initializing to white/black if termcap
	  or terminfo has no color specified.  This makes the list shown for
	  visual-matches limited to the available colors (reported by Clark
	  Morgan).

 20000109 (q)
	> Ed Henderson :
	+ implement autoscrolling feature for winvile, which makes the buffer
	  scroll in the direction where the mouse leaves the window,
	  automatically extending selection highlighting.
	+ make the scroll speed increase over time, rather than distance
	  above/below the window (suggested by Clark Morgan).
	> Clark Morgan:
	+ fix build with dbg=1 for winvile (reported by Ed Henderson).
	+ update doc/modes.doc, using ~with to simplify perlmode example, and
	  adding cindent to cmode description.
	> Brendan O'Dea:
	+ back out change that attempted to make the .pl files use "#!/bin/echo"
	  to work around a warning from the Debian package checker - but it now
	  adds a different warning.
	> Tom Dickey:
	+ modify configure --with-xpm option to allow builder to specify path
	  of Xpm library in the configure --with-xpm option (adapted from patch
	  by Albert Chin-A-Young ).
	+ modify sh-filt.c to mark ':' lines as Action (should be ':'
	  statements, but we do not parse statements yet).
	+ modify key-filt.c to show color codes in Action color rather than
	  Literal, to make it simpler to distinguish special constants such
	  as m4's LeftQuote.
	+ document show-colors and show-color-schemes in vile.hlp
	+ modify the [Color Palette] buffer created by show-colors to make it
	  clearer that the internal codes used in the syntax filters are a
	  single hexadecimal digit (suggested by Clark Morgan).
	+ comment-out the perlmode "while" group, since perl's ambiguities make
	  it not very useful.  Retained the default (if) group, since there are
	  usually more if/elsif/else statements than the others (feedback from
	  Kevin Buettner).
	+ add table entries to tcap.c for terminfo italic mode (sitm/ritm),
	  with terminfo's termcap equivalences (ZH/ZR).  If not found, we
	  continue to fallback to underlining.

 20000104 (p)
	> Kevin Buettner:
	+ window.c (push_fake_win, pop_fake_win): Set curbp.
	+ api.c, select.c:  Change callers of push_fake_win and pop_fake_win to
	  not set curbp.  Actually, it wouldn't hurt, but you'd have to be
	  careful to make sure the setting and restoring is done in the proper
	  order.  [Fixes bug reported by Clark Morgan in which only one dirty
	  window would get colored at a time.]
	+ perl.xs: Minor doc fixes.
	> Clark Morgan:
	+ implement autocolor for win32 console and GUI.
	+ fix some stale doc in doc/macros.doc
	+ fix compiler warnings in ntwinio.c
	> Brendan O'Dea:
	+ remove the clexec/isnamedcmd/no_msgs tweaking in perl.xs for perl
	  commands.  These flags were changed to allow mlreply* to work
	  interactively when perl subs such as hgrep were called from a wrapper
	  macro, although this makes using a registered perl extension
	  non-interactively impossible.
	> Tom Dickey:
	+ minor correction to perl filter, special cases of backslashing to
	  handle perl5's MM_Win32.pm, which incidentally contains a syntax
	  error right after "UNINSTALL =".
	+ modify DrawMenuBar() to use HWND parameter rather than HMENU, as
	  documented (reported by Rick Sladkey).
	+ correct a couple of missing characters after backslashes in perl and
	  sql modes (reported by Kevin Buettner).
	+ add pattern to finderr.c for SGI 7.3 SGI MIPSpro 7.3 compilers (from
	  Anton Koning ).
	+ minor keyword additions for C and Java.

 20000104 (o)
	> Kevin Buettner:
	+ modify updattrs() and offs2col() to fix an extra highlighted
	  character at the end of the line.
	+ add a check to update() to ensure the current window is visible,
	  fixes a case where autocoloring would pick up a buffer with negativa
	  row value (reported by Clark Morgan).
	> Brendan O'Dea:
	+ uncomment line in directory.pm which keeps vile's $cwd variable
	  updated, so hypertext links will work better.
	+ remove doc/hilite.doc, since the corresponding script is gone.
	> Clark Morgan:
	+ miscellaneous updates to vile.hlp
	> Tom Dickey:
	+ fix a null-pointer reference in make_current() (reported by Clark
	  Morgan).
	+ modify autocolor() to refrain from coloring buffers that are not
	  associated with a majormode, e.g., [Buffer List] (reported by
	  Clark Morgan).
	+ minor optimization of offs2col(), moved expressions out of loop.
	+ set/clear 'reading_msg_line' in mlyesno() and mlquickask() to make
	  them behave more like mlreply().  This prevents autocolor from wiping
	  out the highlighting set by substitutions such as
		:%s/pat/replacement/gc
	  (reported by Kevin Buettner).

 20000102 (n)
	> Kevin Buettner:
	+ perl/shell.pm:  Better terminal emulation; several bugs fixed.
	+ perl.xs (do_perl_cmd):  Make sure that curwp is visible on the way
	  out.
	> Brendan O'Dea:
	+ improve Manual.pm, getting highlighting as perldoc does, using nroff
	  and vile-manfilt.
	+ corrections to 9.0m changes to make directory.pm and dirlist.pm work
	  on win32 (comparison for $os was not against proper types, besides
	  Perl has $^O to identify the operating system)
	> Tom Dickey:
	+ modify xvile so that if the -title option is given, xvile will not
	  automatically set the window's title.  Setting $title explicitly will
	  still work (reported by Eric Krohn).
	+ correct usage-message for xvile's options, i.e., -title is used
	  rather than -wm and -T option is used to specify a tag.

 (kev) 991231 (m)
	+ doc/macros.doc, macros/vileperl.rc, perl.xs, vile.hlp:  Fix hgrep
	  references; hgrep.pl is now hgrep.pm.  Also, fixed usage examples.
	+ makefile.in:  Added perl modules Glob2re.pm, Vile/Manual.pm,
	  Visit.pm, dirlist.pm.  Removed glob2re.pl and visit.pl.
	+ perl/Glob2re.pm, perl/Visit.pm:  Renamed and revised from the .pl
	  versions.
	+ perl/glob2re.pl, perl/visit.pl: Removed these files.
	+ perl/Vile/Manual.pm: New file for displaying embedded POD
	  documentation.
	+ perl/dirlist.pm:  New file; creates a flat hierarchical directory
	  listing.
	+ perl/hgrep.pm:  Moved introductory comments to end of file and
	  rewrote in POD format.  Added binding hgrep-help which will display
	  the POD documentation.  Fixed problem with backslashes in the buffer
	  name given to the error-buffer command.
	+ perl.xs:
	  + (newVBrv):  Revert change in "l" which was supposed to prevent
	    circular structure from being created.
	  + (perl_free_handle):  Instead, break circular structure here so
	    handle will get freed properly.  [Analysis by Brendan O'Dea.]
	> Brendan O'Dea:
	+ Vileserv now also works for vile.
	+ registration commands are a bit more efficient when the module is
	  already loaded.
	+ hgrep now sets error-buffer internally.
	+ add perl "use capture".
	> Tom Dickey:
	+ modify Vile::get() method to accept functions, used to replace use
	  of `pwd` in perl scripts to make them portable to win32 [Brendan
	  O'Dea points out that there is Cwd.pm for this sort of thing].
	+ modify directory.pm and dirlist.pm to make them work on win32, i.e.,
	  by not executing portions that will not work (such as mime types) and
	  using vile's builtin functions to workaround deficiencies in perl.
	+ add check in vileperl.rc to avoid registering scripts that will not
	  work on win32.

 (tom) 991229 (l)
	+ save/restore selection highlighting in attribute-from-filter, so that
	  autocolor does not clear the current selection.
	+ add OS/2 EMX to list of platforms that must open text files in binary
	  mode, to see trailing carriage-returns on a line in vileinit.rc
	+ modify makefile.wnt to copy the .rc files to $VILE_STARTUP_PATH
	  during build, as the Perl files already were.
	+ update makefile.wnt to install renamed/new Perl scripts
	+ modify tc-filt.l to flag as an error an unescaped newline within
	  a description.
	+ modify c-filt.c to flag as an error a multi-line literal which is
	  missing a backslashed newline.  This is allowed by gcc, but the
	  C standard is explicit.
	+ modify c-filt.c to not treat a line beginning with a '#' if the
	  previous line ended with a backslash.  This is needed to not flag as
	  an error tokens in a macro which are quoted with '#'.
	+ update vileperl.rc to work with Brendan's renaming/simplification.
	> Paul Fox:
	+ add cc and reply-to to the list of recognized mail headers, and makes
	  them all caseless.
	+ also added '+' as a valid character in email names, since more and
	  more people are using the user+foo style convention mail sorting.
	> Kevin Buettner:
	+ buffer.c (killbuffer):  When attempting to free more than one buffer
	  by use of a glob expression, don't use recently freed memory after a
	  buffer kill to obtain the next buffer to check.
	+ perl/hgrep.pl:  Change "rgrep" to "hgrep".  Also, don't allow buffer
	  to be autocolor'd.
	+ perl.xs (PDEBUG):  Added/revised code for debugging reference counts.
	  + (newVBrv):  Pass NULL for the obj (second) parameter to sv_magic().
	    This prevents a circular structure from being created which was
	    quite difficult for Perl to free properly.  (newVBrv):  Removed
	    extraneous calls to SvREFCNT_inc().  [Analysis by Brendan O'Dea.]
	  + (do_perl_cmd, svcurbuf_set):  Don't use sv_2mortal() on the new SV
	    passed to newVBrv().  Instead, explicitly call SvREFCNT_dec() on it
	    after svcurbuf assignment.  [Analysis by Brendan O'Dea.]
	  + (do_perl_cmd):  Instead of doing an explicit SvREFCNT_dec() on
	    svcurbuf, assign undef to this variable.  This will still decrement
	    the reference count.  I think this is the reason we needed the
	    extra SvREFCNT_inc() statements.  We would decrement the reference
	    count here without also removing the reference.  As a result, when
	    svcurbuf was assigned to again, the reference count was decremented
	    again on the thing being replaced.
	+ makefile.in: Look for perl .pm files in the perl subdirectory.
	+ hgrep.pl: Set up the error finder.
	> Brendan O'Dea:
	+ Deletes hilight.pl, manfilt.pl, syntax.pl and tailf.pl.
	+ rename most .pl files to .pm (makefile.in).
	+ add an Exporter-like mechanism to Perl5 interface, although instead
	  of exposing a module's functions to the caller, it exposes them to
	  vile as registered commands.  By renaming the extensions as `.pm',
	  and making some minor changes to use Vile::Exporter, an extension
	  becomes visible by simply adding:
		  use extension;
	  to vileinit.pl.  There is also provision for only including some
	  commands provided by the extension, and for overriding the keybinding
	  defined by the developer (documented in the attached module).
	  Of course you can still say:
		   require extension;
	  and do the registering yourself if you so choose.

 (tom) 991226 (k)
	+ disable autocolor in manpage.rc macros, which have txtmode set.
	+ suppress autocolor when 'working...' message is active.
	+ modify filters.c to always initialize predefined classes whenever
	  a symbol table is created.  It was done before only for the first
	  symbol table, which meant that some filters using multiple symbol
	  tables were not able to use class names for keyword attributes.
	+ change cpp.key's inclusion of c.key to ".include" to avoid forcing
	  cweb filter, which includes cpp.key, to keep track of C and C++
	  tables.
	+ split-out cweb.key, install vile-cweb-filt
	+ add syntax filter for embedded SQL (esqlfilt.l)
	+ add syntax filter for REXX (rexxfilt.l)
	+ minor fix to c-filt.l in write_number(): recognize "..." string.
	+ correct some missing .key files in the install rule for makefile.wnt
	+ correct some forward references from 9.0j (ntconio.c, ntwinio.c).

 (tom) 991224 (j)
	+ add cygwin to list of platforms that must open text files in binary
	  mode, to see trailing carriage-returns on a line in vileinit.rc
	+ restore Kevin's change to main.c, which calls term.close() within
	  tidy_exit() after perl_exit(), to ensure that ".vilesock" is removed.
	  At the same time, call ExitProgram() directly from newprocessgroup()
	  so that xvile does not exit prematurely when invoked w/o forking
	  (analysis by Kevin Buettner).
	+ more fixes for special case numbers in c-filt.c, e.g., ".1", "..1"
	  (err), "0x.p1" (err).
	+ implement special attribute code 'N' to allow users to disable syntax
	  highlighting for a given class.
	+ indent'd random.c
	+ indent'd ntconio.c and ntwinio.c, reordering some chunks to eliminate
	  forward-references.
	+ correct an off-by-one in repaint_window() from 9.0g changes that left
	  debris after an exposure event (ntwinio.c).
	+ add rules to makefile.wnt for compiling all filters, not merely those
	  which are normally installed.
	+ correct a minor formatting error in describe-bindings for command
	  names longer than 31 characters using new function quote_and_pad().
	+ change TRACE macro usage to put a ';' on the end, since it works
	  better that way with 'indent'.
	+ fix some places where K&R/unproto combination on SunOS could not
	  compile, e.g., aggregate initialization in bind.c, termio.c.
	> Kevin Buettner:
	+ buffer.c (swbuffer_lfl):  Set MK to nullmark.  Since we're switching
	  buffers here, we want to make sure that MK doesn't refer to a line in
	  a buffer different than curbp.  This fixes the "BUG:  hit buf end in
	  getregion" message that would frequently pop up when using the perl
	  facilities.
	+ perl.xs (set_curwp0):  New function.  Use this instead of set_curwp()
	  in many of the Vile::Window methods to prevent the buffer tracking
	  list from getting updated.  [Reported by Paul Fox.]
	+ random.c (autocolor):  Save/restore dotcmdactive.  This fixes the bug
	  with "." (repeat-last-cmd) in which an autocolor() call would shut
	  off the dot recording.  As a result, "." would replay some earlier
	  command than the one you thought you were repeating.

 (kev) 991222 (i)
	+ makefile.in (capture.pl, winops.pl): New files/targets.
	+ perl.xs (perl_exit): Clear perl_interp variable so that
	  we get out early if we're called twice.  This won't
	  presently happen, but we want to be prepared if it does.
	  (stringify_coderef):  Fixed situation in which the coderef
	  was getting pushed on @Vile::CRs twice -- and also
	  incrementing the reference count twice which was preventing
	  the code ref from being freed up.
	  (perl_free_deferred): New code to work around perl bug
	  in which parts of the coderef are getting freed too
	  early causing memory corruption.
	  (perl_free_callback):  Ditto.  Also added a comment
	  regarding a (now removed) call to SvREFCNT_dec() and why it
	  shouldn't be there.  Also, don't increment the reference
	  count on a newly created integer (newSViv).  It's already
	  incremented when allocated.
	+ proto.h (perl_free_deferred): Declared.
	  (perl_free_callback): Change return type.  This is so
	  that the GROW macro may be used to increase the size
	  of the vector of Sv's to deallocate in perl_free_deferred().
	+ api.c (api_command_cleanup): Call perl_free_deferred() in order
	  to work around perl bug.  I didn't ifdef it because we may
	  someday find some other deferred allocations which need to
	  be performed.
	+ main.c (quit): Don't shut down X11's display here.
	  (tidy_exit): Shut it down here instead.
	  Fixes bug reported by Sean Ahern in which .vilesock was
	  not getting removed properly.  Thanks also to Brendan
	  O'Dea for additional insight into the problem.
	+ npopen.c (pipe_pid2): New static variable.
	  (npclose): Wait on both pids associated with a filtering
	  operation.  This cleans up the zombies (and there were a lot
	  of them) associated with automatic syntax coloring.
	  (softfork): Set pipe_pid2 for callers who are too lazy
	  to remember the pid.  [Note: I consider this to be an
	  ugly hack.  Please feel free to improve upon it.]
	+ modetbl (loading): New mode.
	+ display.c (modeline_modes): Added code for "loading" mode.
	+ capture.pl: Some improvements:
	    + Error finder now hooked up
	    + [loading] message on modeline when loading a file
	    + New name for the binding: async-capture-command instead
	      of perl-capture-command
	    + New keybinding ^A-!.  Think of the ^A as "asynchronous".
	    + Prettier header
	    + Dot reset to top of new buffer contents if appropriate
	      (If you're browsing the buffer, it won't interfere with
	      your browsing.)
	    + Lots of new comments in the code
	+ watch.c (dowatchcallback):  Do not run watch callbacks when
	  user is typing on the message line.  (This cures a nasty
	  abort that I encountered while using async-capture-command.)
	> Tom Dickey:
	+ revert Kev's change to main.c - this made xvile not run when it
	  forks on startup.
	+ compiler warnings in x11.c (reported by Michael Finken
	  )
	+ improve attribute_from_filter() by draining a pipe that has data;
	  if the filter program incorrectly sends more data than vile expects,
	  vile would not be able to close the pipe.
	+ correct check in c-filt.c from 9.0g for nested comments; it flagged
	  adjacent comments.
	+ modify m4-filt.c to test multi-line attributes by writing Literal's
	  as a single token rather than each piece split by lines.
	+ improve attribute-from-filter and attribute-cntl_a-sequences-til to
	  allow lengths beyond the end of the current line (Kevin & I were
	  aware of this - report by Christian Lindig ).
	+ modify c-filt.c to highlight C9X hexadecimal floating constants
	+ add new C9X keywords to c.key: inline, restrict, _Bool, _Complex,
	  _Imaginary, _Pragma, __STDC_VERSION__, __VA_ARGS__, __func__.
	+ correction to c-filt.c's parsing of floating-point constants (missed
	  a toupper).

 (kev) 991220 (h)
	+ perl/capture.pl: New perl script which implements a perl version
	  of capture-command.  This version incrementally updates the
	  window however.
	+ perl/winops.pl: New perl script which implements various window
	  related operations.  Good for testing implementation of the
	  Vile::Window API.
	+ perl.xs: Documentation fixes.
	  (package Vile::Window):  Documentation and implementation of
	  Vile::Window API.
	  (perl_free_callback): Disable deallocation of the coderef since
	  this causes problems when called from within the subroutine
	  being deallocated.  Added a FIXME comment noting the problem.
	  (set_selection, selection_buffer): Fixed croak messages.
	  (dotq): New Vile::Buffer method.
	+ api.c (api_dotinsert): Set changed flag.  This fixes a bug
	  where perl would add characters to the buffer, but they
	  wouldn't appear until the user did something else to force
	  a hard update.
	  (api_command_cleanup): Make sure results of unmark operation
	  get propagated back to the editor.
	+ api.h (VileWin): Declare.
	+ buffer.c (swbuffer_lfl): Don't call undispbuff() unless all
	  windows associated with the buffer are gone.
	+ estruct.h (WINDOW): Added w_id as a new field to this structure.
	+ window.c, proto.h (id2win, win2id, index2win, win2index):
	  New functions.
	+ window.c (w_id_next): New static global.
	  (FAKE_WINDOW_ID): New define.
	  (splitw, winit, push_fake_win): Set/initialize w_id field in
	  WINDOW structure.
	+ ptypemap (T_VileWin): New type in typemap.
	+ x11.c (x_autocolor_timeout): Send a null message to ourselves
	  to prevent stalling in the event loop.  This fixes the bug
	  in which a keypress while the filter was running would
	  cause the keypress to be noticed at the next X event.
	  (paste_from_primary): New function.
	+ cmdtbl (paste-from-primary): New command.  (Requested by Sean
	  Ahern.)

 (kev) 991219 (g)
	+ cmdtbl, buffer.c:  Added binding / support for ^X-_ aka
	  "historical-buffer-to-current-window".  [Requested by Mike J.  Bell.]
	+ random.c (autocolor):  Save/restore pre_op_dot.  Fixes bug reported
	  by Paul Fox:  "if autocoloring kicks in between an operation and the
	  motion that completes it (e.g.  'd' and 'w'), the operation acts on
	  the wrong selected region -- i think it acts on 'dot to top of
	  buffer'."
	+ improve set-window (actually swbuffer()) by initializing a window's
	  traits, e.g., position, from the buffer's traits.
	+ buffer.c (swbuffer_lfl):  Make sure window count gets decremented for
	  the window being replaced even if buffer we're replacing it with is
	  already on-screen (fixes a core dump in set-window, reported by Clark
	  Morgan).
	+ fileio.c (ffclose): Use mlwrite() instead of mlforce().
	+ edef.h (in_autocolor): New variable.
	+ display.c (mlerase, mlwrite):  Use in_autocolor to determine whether
	  or not to position the cursor on the message line.
	+ random.c (autocolor): Set autocolor as appropriate.
	+ macros/vileinit.rc, vile.hlp:  Revise so that autocolor timeouts are
	  in milliseconds.
	+ termio.c (ttgetc): Likewise.
	+ x11.c (x_start_autocolor_timer): Ditto.
	> Clark Morgan:
	+ ifdef'd autocolor mode and logic with OPT_COLOR to accommodate VMS,
	  which does not support syntax highlighting anyway.
	+ fix vmsbuild.com for the case of building xvile.exe with VAXC, adding
	  menu.obj to vms_link.opt _before_ the CRT.  That ensures that the
	  linker looks for menu.obj in the cwd, not in sys$library.
	> Tom Dickey:
	+ improve logic of repaint_window(), so it paints long chunks rather
	  than single characters.  This makes the screen paint properly when
	  switching to an Italic font.
	+ refine logic for gui_resize_in_progress in ntwinio.c so that it
	  only affects the case where a font-sizechange is in progress.
	  This restores the behavior of 8.3d, which allows a user to specify
	  $pagewid and $pagelen in vile.rc to control the initial screensize
	  (reported by George Young ).
	+ add $brightness variable to winvile, allowing users to customize the
	  overall intensity of colors, to accommodate different monitors
	  (prompted by Chris Green ).
	+ modify backspacelimit mode to allow backspacing through a newline
	  when nobackspacelimit is specified (request by Todd Moody
	  ).
	+ change Kevin's use of in_autocolor which suppresses message-output to
	  make that part of ~hidden behavior.
	+ remove elif/else clauses from m4mode "do" group, since they interfere
	  too much with balancing square brackets intermixed with parentheses.
	+ implement poll()-based watchfd/autocolor support.
	+ implement BeOS-specific watchfd/autocolor support, by rearranging
	  logic used for catnap(): beos_has_input(), beos_can_output() and
	  beos_napms().
	+ make repeat-count apply to @register commands.  This repeats the
	  entire command, and is not necessarily compatible with vi: some
	  implementations do not recognize a repeat count, and other, e.g.,
	  SVr3 repeat the last command in the register contents.  elvis does
	  the former, nvi does the latter, and vim repeats the entire string.
	  It's fortunate that the simpler implementation is more useful
	  (requested by Ed Henderson).
	+ modify vilefilt.l to recognize .vilemenu syntax.
	+ modify menu.c to allow double-quote as comment-marker.
	+ remove full-line behavior from goto-char command.
	+ correct behavior of "Clear Highlighting (below)" menu entry in sample
	  vilemenu.rc which did not clear the final line of a buffer.
	+ add some pointer checks to swbuffer(), getcol() and gocol(), so
	  piping to vile works properly when trying to initialize window's
	  traits.
	+ add a note about set-window to vile.hlp
	+ improve coloring of literals in vilefilt.l by interpreting strings
	  beginning with ^A, ^X or escape.
	+ modify c-filt.c show nested-comment as error.
	+ fix c-filt.c to highlight properly a number immediately after a
	  leading "#", to accommodate non-standard usage by GCC's preprocessor.

 (kev) 991214 (f)
	+ buffer.c (chg_buff, unchg_buff): Set the "recently changed"
	  flag for syntax coloring purposes.
	+ edef.h (autocolorhook): Declare.
	+ macros/vileinit.rc: Added example code for automatic syntax
	  coloring.
	+ main.c (global_val_init): Initialize VAL_AUTOCOLOR.
	+ modetbl (AUTOCOLOR): New mode.
	  (autocolor-hook): New hook.
	+ perl/shell.pl: Revised to use IO:Pty instead of Comm.pl (which
	  seems to be no longer maintained).
	+ proto.h (autocolor, ttwatchfd, ttunwatchfd): New declarations.
	+ random.c (run_a_hook): Return status from running the command
	  instead of unconditionally returning TRUE.
	  (autocolor): New function.
	+ statevar.c (var_AUTOCOLORHOOK): New function.
	+ tcap.c (term): Use ttwatchfd and ttunwatchfd instead of the
	  nullterm versions.
	+ termio.c (USE_SELECT): New alternative to USE_FCNTL and
	  USE_FIONREAD.  Preferred over both of these methods for
	  determining if there are new characters to be read from
	  the keyboard.
	  (watchfd_read_fds, watchfd_write_fds, watchfd_maxfd): New
	  static variables.
	  (ttwatchfd, ttunwatchfd): New functions.
	  (ttgetc): Added new USE_SELECT code for reading a character.
	  This new code also watches for activity on file descriptors
	  registered with watchfd() and will invoke the automatic
	  syntax coloring function, autocolor, as appropriate.
	+ vile.hlp: Documented new autocolor mechanism.
	+ x11.c (x_start_autocolor_timer, x_autocolor_timeout,
	  x_stop_autocolor_timer): New functions.
	  (x_getc): Call x_start_autocolor_timer and x_stop_autocolor_timer
	  as appropriate.
	  (x_key_press): Call x_start_autocolor_timer to reset the timer
	  on each keystroke.
	> patches by Tom Dickey:
	+ color continued comment-lines in makemode.
	+ correct c-filt.c parsing of numbers such as 0.0, from 9.0e rewrite.
	+ correct display of termcap numbers, which were highlighted as errors
	  after allowing '#' in capability-names.

 (tom) 991212 (e)
	+ improve c-filt.c's parsing of numbers to flag spuriously-repeated
	  suffixes as errors (request by Kevin Buettner).
	+ indent'd word.c, add a special case to avoid putting two spaces after
	  "i.e." or "e.g." to accommodate some European usage.
	+ add several perl5 keywords to perl.key (listed by )
	+ remove "unsetl view" logic from :f command, since it is an obscure
	  and not desirable side-effect.  Appeared in filename() and
	  commdlg_save_file() (reported by Clark Morgan).
	+ modify HighlightFilter to check if user is trying to run this with
	  winvile w/o w32pipes set.  That combination does not work, so don't
	  try it.
	+ update CF_ANSI_CC_CHECK to match that in tin, which now uses -Ae
	  option for HPUX (patch by Urs Jansen).
	+ modify config.sub to recognize ia64 machine (patch by Kevin Buettner).
	+ allow '_' and '.' in terminfo aliases.
	+ correct a file-descriptor leak in npflush for win32, which showed up
	  as undeleted temp-files.  This would happen when opening read/write
	  pipes, e.g., for syntax filtering, when now32pipe was specified.
	+ remove obsolete/unused Win31 ifdef's (reported by Clark Morgan).
	> patch by Clark Morgan:
	+ changed the VMS build document (README.VMS) to specify exclusive use
	  of vmsbuild.com rather than MMS directly.
	+ changed vmsbuild.com to accept a compiler specification on the
	  command line, which is much more convenient than editing the build
	  script by hand.  compiler defaults to VAXC on Vax hosts and DECC on
	  Alpha hosts.

 (tom) 991209 (d)
	+ implement "before" and "after" qualifiers for majormodes.
	+ add C++ majormode cppmode,
	+ change prompt for majormode in procedure parameter lists to allow
	  mixed case.
	+ add ".table" and ".default" to filter interpreter.
	+ add a syntax filter for vile's .key files, use that to fix some
	  errors in make.key, tcl.key .
	+ add a syntax filter for Lynx config file.
	+ add '_' to URL patterns, used in txt and mail filters.
	+ corrected DSTRINGS definition in awk syntax filter, which did not
	  handle quoted backslash.
	+ allow '+' in alias in termcap syntax filter.
	+ add variable $error-buffer, use this in manpage.rc to avoid losing
	  the setting when creating a manpage buffer.
	+ add error-patterns for ncurses tic and atac.
	+ implement ".merge" in filter keyword files, needed for C and HTML
	  filters.
	+ improve C syntax filter:
	  + marking misspelled preprocessor keywords as an error.
	  + marking numbers run-on to names as an error,
	  + marking unexpected escapes as an error,
	+ minor fixes of ifdef's for glob_match_leaf(), for building with
	  configure --disable-extensions.
	> patches by Clark Morgan:
	+ add the Win32 common dialog "save as" feature to both console
	  vile and winvile.
	+ update vile.hlp was updated to reflect recent
	  questions about macros.doc
	+ split-out the win32 command-specific code (e.g., winopen, winsave,
	  etc) from w32misc.c to a new file called w32cmd.c
	+ add a note about obscure "unsetl view" side-effect of the :f command
	+ add special case to expand_wild_args() for VMS to handle +/string
	  syntax.
	+ update README.VMS for building xvile
	+ fix for VAXC to include icons/vile.xbm

 (tom) 991202 (c)
	+ modified vmsbuild.com and descrip.mms (untested) to build the Motif
	  version with menus, the X toolkit version without (based on discussion
	  with Clark Morgan and Jonathan Ridler).
	+ fix ttclean() function for xvile on VMS (Clark Morgan, from problem
	  report by Jonathan Ridler ).
	+ add .Xdefaults to xresmode.
	+ add backslashes as needed to digraph.rc, to work with the new single
	  quote interpretation (reported by Paul Fox).
	+ correct a place where expression evaluation result was overwritten
	  with the nested result in a complex expression from 8.3d (reported
	  by George Eccles).
	+ highlight whitespace in makefiles between backspace and newline as
	  an error.
	+ define "Error" class for syntax filters.
	+ correct make filter's handling of escaped newline: '.' does not match
	  newline.

 (tom) 991127 (b)
	+ add "case" and "do" groups to m4mode.
	+ add ".ms" and ".me" suffixes for nrmode.
	+ add ``quote'' quoting to txt filter.
	+ refine treatment of double-quote in txt filter so it can be quoted
	  by single-quote or parenthesis.
	+ allow "~" in URL patterns for txt and mail filters, omitted in 9.0a.
	+ correct some missing backslashes before vertical bar and parentheses
	  in filters.rc, made apparent by the change to use single-quoted
	  strings.
	+ restore handling of special control characters such as ^D, ^T in
	  insert mode which happened to be GOAL or MOTION commands (reported by
	  Clark Morgan).

 (tom) 991124 (a)
	+ add single-quoted strings, which eliminate the need for escaping
	  backslash (suggested by Paul Fox).
	+ modify logic in ins_any_time() to interpret control characters which
	  are bound to GOAL or MOTION commands rather than inserting them
	  without quoting.  This allows ^E and ^Y as commands within an insert
	  (request by Quang Ngo ).
	+ change several commands to use GOAL flag, which tells vile that they
	  may move to a new line, but try to keep the column constant.  Doing
	  this has the side-effect that they are usable in quoted-motion:
	  grow-window, move-next-window-down, move-next-window-up,
	  position-window (z), redraw-display, scroll-next-window-down,
	  scroll-next-window-up and shrink-window, as well as api_motion().
	+ modify quoted-motion so that commands with the GOAL flag are allowed,
	  since those do not change the buffer contents.
	+ change handling of status return from readpattern() so that an abort
	  is passed up to the caller.  In execute-named-procedure, check for
	  abort, and restore DOT to the value before evaluating addresses
	  (reported by Clark Morgan).
	+ correct bug in wrapmargin/fillcol logic which did not split a line
	  when a newline was inserted into a string containing no blanks
	  after the fillcol position.  Instead, an empty line was inserted
	  (reported by Clark Morgan).
	+ correct missing allocation of default help-string for user-defined
	  procedures, which could cause core dump if a procedure were redefined,
	  e.g., by source'ing .vilerc (reported by Paul Fox).
	+ add tags syntax filter and majormode tagsmode.
	+ add X resource syntax filter and majormode xresmode.
	+ improve URL pattern in mail and txt filters, to allow it to match
	  ftp and other URL types, as well as limited the pattern to avoid
	  picking up things like trailing '>' characters.
	+ correct some syntax filters' expressions for REAL, which were
	  expecting two digits after the decimal point, rather one.
	> patches by Clark Morgan:
	+ enable "kill-buffer " on VMS.
	+ fix to allow accessing multiple versions of DECNET-based files.
	  That is, this now works:
		$ vile node::dir:log.txt;*       <- open all copies of log.txt
	+ eliminate stray cursor glyphs in the message buffer (most often
	  happens when a Win32 dialog is dismissed at the "same time" that a
	  winvile command writes status text).

This change log started on Friday Nov 19, 1999.
vile-9.8v/CHANGES.R3000066400000000000000000003670031415556424100140150ustar00rootroot00000000000000
NOTICE: This change log is officially (sez me) closed.
	All further changes documented (hopefully) in "CHANGES".  This
	file was renamed from "CHANGES" to "CHANGES.R3" on Tue Feb 22, 1994.

Changes for vile 3.65: (released Mon Feb 7, 1994)
(pgf)
    Big change this release is 8-bit cleanliness.  See the help file
    for 8-bit settings.  
    
    NOTE: If you had a FN-key binding which was bound to a "meta" (high
    bit) key, you must change your binding to be a M- binding.  FN- and M-
    are no longer synonymous.  In addition, we now preserve more of the
    termio settings, so you may have to explicitly use "stty" to get
    your meta-bit back.  (We used to clear istrip and the parity settings.)

    NOTE2: pc vile, if built with djgpp or watcom compilers, cannot change
    screens to 43 or 50 line mode.  i'm working on it.

	+ fix bug in charprocreg() that allowed a buffer to be marked
	  modified even if no changes were made and there is nothing to
	  undo.  (region.c)

	+ Brackets '[' and ']' are now treated like braces and parentheses
	  when inserting in c-mode. added new #defines for [LR]BRACK to assist
	  this. (insert.c, estruct.h, main.c)

    	+ A buffer's local "dos" mode is now set to the same as the global
	  "dos" mode when empty, fresh, or when dos-style lines equal unix-
	  style lines. (main.c, file.c, random.c)

	+ giving an argument to "set-dos-mode" causes it to turn dos-mode
	  off rather than on. (file.c)

	+ allow backspacing over autoindented whitespace, whether  or not
	  backspacelimit is set. (insert.c)

	+ new commands, ^A-i, ^A-o, and ^A-O, corresponding to i, o, and O,
	  but which do autoindent-override during an insert.  Most useful
	  when pasting into a buffer, since the pasted text often already
	  has leading whitespace, and autoindent just adds more.   this
	  is a different kind of override than used when pasting in xvile.
	  hmmm.  (insert.c, cmdtbl)

	+ fixed core dump resulting from calculating indentlen and checking
	  for '#' char at start of empty line.  (insert.c)

	+ add directory and host names to "vile died" message.  added ifdef
	  and prototype for usage of gethostname.  currently only used #if
	  BERK is true.  (greg mcfarlane) (file.c, proto.h, estruct.h)

	+ apply (greg mcfarlane's) fix for bug in unqname, when it's being
	  used at startup, and can't ask for input from user. (file.c)

	+ only reclaim or destroy empty unmodified buffers if they don't
	  correspond to existing files.  new routine ffexists() to support
	  this. (buffer.c, file.c, fileio,c, proto.h)

	+ changed calls to kbd_key() to tgetc(), since SPEC is now outside
	  the range that callers can handle.  (window.c spawn.c
	  insert.c history.c exec.c eval.c csrch.c bind.c)

	+ changed all references to last1key to refer to lastkey instead,
	  to accompany above change.  last1key is gone. (basic.c, opers.c,
	  edef.h)

	+ kbd_key() now translates system-specific function-key sequences
	  to canonical '#-c' sequences, which kbd_seq() now interprets.
	  (input.c)

	+ allow 8-bit input, by changing SPEC definition, and some table
	  sizes. (estruct.h, input.c, mktbls.c)

	+ translate X key-events to a default set of xvile FN-bindings,
	  without using the SPEC define, since it won't fit through the
	  8-bit wide pipe we've constructed. (x11.c)

	+ added new modes, printing-low and printing-high, which define
	  the range of 8-bit chars which should _not_ be displayed in
	  octal, but rather as themselves.  (modetbl, modes.c, main.c)

	+ change how we display 8-bit chars. (display.c)

	+ new mode, unprintable-as-octal, to control display of non-printing
	  chars in hex or octal. (display.c, modetbl)

	+ new mode, meta-insert-bindings, which allows meta-bindings (M-c)
	  to work while in insert mode.  when off, all characters, meta
	  or not, are simply inserted as themselves.  when on, meta keys
	  which are bound to functions execute those functions, all others
	  insert themselves. (insert.c, modetbl)

	+ tb_get now returns a true 8 bits, no sign-extension.  (tbuff.c)

	+ allow focusFollowsMouse to be disabled by XDefaults (x11.c)

	+ apply fix (kev) for infinite loop on extended lines with certain
	  kinds of tab values. (display.c)

	+ attempt at better video support, and raw i/o, for djgpp (ibmpc.c)

	+ new routines for ctrl-c/ctrl-break/critical-error handling in
	  djgpp environment. (main.c, proto.h, new file djhandl.c, makefile,
	  makefile.djg)

    	+ added DJGPP to the direct/dirent ifdef in dirstuff.h

	+ fix for sys5 tgetent behavior, when attempting to determine if
	  we're an xterm. (tcap.c)

	+ new targets for motorola delta machines (makefile)

 	+ fixes for core dumps on window resize (from kev) (x11.c)

	+ new define for min no. of lines per window. (estruct.h)

	+ change if_OPT_WORKING to simple ifdefs. (file.c fileio.c display.c
	  estruct.h)

	+ added vanillashar target to makefile, so i can produce shars
	  that the gnuish DOS unshar program will unpack.  (makefile)

	+ clarify help file regarding regions as used by the operator
	  commands (vile.hlp)

	+ applied contributed fix for null fontname (x11.c)

	+ changed logic of tags lookup, so i can understand it, and to
	  correct logic surrounding "taglength" (again).  if taglength is
	  0, matches must be exact (i.e.  all characters significant).  if
	  the user enters less than 'taglength' characters, this match must
	  also be exact.  if the user enters 'taglength' or more
	  characters, only that many characters will be significant in the
	  lookup. (tags.c)

	+ fixed bug with wrap-around reverse searching for a string occurring
	  on the last line of a buffer.  (search.c)

	+ fixed bug in search/replace operations where replacement string
	  was of the form 'text\1moretext'.  the length of the \1 replacement
	  pattern was being obtained incorrectly. (oneliner.c)

	+ changed GO32 ifdef to DJGPP, to avoid name conflict with
	  predefinition. (input.c, fileio.c, estruct.h, ibmpc.c, path.c,
	  random.c, termio.c)

	+ changed the 'interrupted' global to a routine, so we can poll for
	  a control-C character when real signals aren't available. (buffer.c,
	  edef.h, fences.c, main.c, search.c, word.c)

(tom)
	+ corrected EVCURCHAR case in 'gtenv()' that tried to return the
	  characters at the current position, even when the buffer was empty
	  (eval.c).

	+ added ifdef-controls OPT_SHOW_EVAL, OPT_SHOW_REGS, OPT_SHOW_TAGS
	  (cmdtbl, eval.c, estruct.h, line.c, proto.h, tags.c), and renamed
	  OPT_MAP_DISPLAY to OPT_SHOW_MAPS (map.c, estruct.h).

	+ use OPT_UPBUFF in 'killbuffer()' (buffer.c).

	+ added ifdef-control OPT_WIDE_CTYPES (estruct.h, input.c, main.c).

	+ use new macro 'chrBIT()' to fix long/short bitmasks in character
	  tests (estruct.h, line.c).

	+ changed 'set_bname()' to a procedure so that it can trim trailing
	  blanks from the buffer-name.  This is done so that a ^X-k command
	  applied to a buffer-name beginning with "!" will work.

	+ corrected length-computation in 'delins()' so that command
	  ":s/abc\[\(..\))/abc[\1]/" works properly (oneliner.c).

	+ corrected offset-computation in 'scanner()' so that wrapped search
	  finds text on the first line after wrapping (search.c).

	+ added call to 'update()' in 'ms_processing()' so that
	  "show-registers" display will be properly updated at the end of
	  mouse-selection (ibmpc.c).

	+ corrected logic in 'execute_named_command()' that prevented user from
	  typing ":0r foo" in an empty buffer (exec.c).

	+ corrected 'bclear()', so that the b_ulinep member is reset if it is
	  freed (buffer.c).

	+ lint (fileio.c, npopen.c, spawn.c)

	+ absorbed 'fnc2key()' into 'fnc2kcod()' (bind.c), to simplify
	  unbinding of prefix-keys in 'install_bind()'.

	+ corrected 'install_bind()' by new procedure 'reset_prefix()', so that
	  mapping characters that happen to be prefix-keys will override their
	  binding (bind.c).

	+ added definition LTRIMMED, to use in special cases (i.e., scratch
	  buffers) where we don't really want to show "^J" at the end of lines
	  when "list" mode is enabled (estruct.h, display.c, file.c, line.c,
	  map.c).

	+ animated [Mapped Characters] buffer (map.c).

	+ modified display of mappings so that using a repeat-count for the
	  ":map" command causes the actual characters to be shown, e.g.,
	  "#1" instead of "FN1", (map.c, modes.c).

	+ added alternate boolean "glob" mode (in contrast to the normal string
	  mode), for configurations in which vile cannot read filename
	  expansions via a pipe, e.g., VMS or UNIX (mktbls.c, modetbl, glob.c).

	+ moved "glob.h" definitions into estruct.h and proto.h because
	  the preceding change requires some definitions to precede inclusion
	  of "nemode.h" within estruct.h (descrip.mms, eval.c, filec.c, glob.c,
	  main.c, makefile, makefile.djg, makefile.tbc, makefile.wat, proto.h,
	  random.c, revlist, tags.c).

	+ corrected test in 'index2ukb()', which caused the unnamed-buffer
	  to be shown incorrectly when yanking text after lines had been
	  deleted (line.c).

	+ use 'DOT', 'mode_row()', 'buf_head()' and 'win_head()' macros (basic.c, buffer.c,
	  csrch.c, display.c, eval.c, exec.c,
	  file.c, filec.c, finderr.c, globals.c, line.c, random.c, tags.c,
	  tcap.c, tmp.c, undo.c, window.c, word.c) for consistency and readability.

	+ modified lines/cols initialization so that 24x80 is assumed if all
	  other lookups fail, needed for apollo sr10.2 dial-in (tcap.c).

	+ added macro 'KbSize()' (file.c, estruct.h, x11.c, spawn.c, line.c).

	+ corrected 'imdying()' to not save temporary buffers, and to suppress
	  "implybuffer" mode (file.c).

Changes for vile 3.64: (released Wed Dec 23, 1993)
(pgf)
	+ change arithmetic expression in mktbls.c, so we don't assume
	  boolean expression returns exactly 0 and 1.  this exercised
	  a bug in an HP compiler (mktbls,c, from chris sherman)

	+ added fallback definition of VDISABLE to termio.c, in case
	  system doesn'd define it. (termio.c)

	+ increased stack size for Watcom DOS builds to 16K.  probably
	  overkill, but the other DOS builds seems to use 16K as well.

	+ cleaned up some of the scanf nonsense, but not nearly enough.
	  (finderr.c)

	+ don't let display-page changes affect the user's chosen cursor.
	  (ibmpc.c)

	+ use _previous_ indentation level after a line beginning with '#'
	  in cmode.  (insert.c, proto.h)

	+ use COMSPEC environment variable when spawning a DOS shell (spawn.c)

	+ assume we're an xterm if the word "xterm" appears anywhere in the
	  first field of the tcbuf, rather than just in the user's TERM
	  variable. (tcap.c)

	+ increased size of tcbuf since SCO core dumps on overflow (tcap.c)

	+ initialized tb_last in tb_alloc(). (tbuff.c)

	+ couple of minor user suggestions for vile.hlp and the README.

	+ don't beep when motions fail due to being aborted. (main.c)

	+ check modification time on first change to buffer (file.c, exec.c,
	  proto.h)

	+ the filename found for a tags lookup is now passed through doglob(),
	  which means tagfiles can now refer to environment variables etc.
	  (tags.c, from S.Suresh)

	+ new X resource, "focusFollowsMouse", causes xvile's current window
	  to track with the mouse cursor. (x11.c, from S.Suresh)

	+ added '~' to the characters considered part of a pathname, so
	  ^X-e will pick up ~pgf/foo correctly (main.c).

(tom)
	+ corrected last change to allow pipe to vile, in case it is invoked
	  via 'rsh' and cannot open /dev/tty (main.c).

	+ added config flag OPT_TERMCHRS (estruct.h, bind.c).

	+ animated [Terminal] and [Binding List] buffers (bind.c, buffer.c).

	+ corrected call on 'slowreadf()' that resulted in wrong line numbers
	  when a file was piped to vile (main.c).

	+ modified TurboC makefile to merge duplicate strings, saving a little
	  memory (makefile.tbc).

	+ corrected logic that makes ".bak" file on MSDOS so that when
	  appending to a file (e.g., ":w >>foo") the file is copied after
	  renaming (fileio.c).

	+ consolidated some code that sets errno when user attempts to read or
	  write a directory-file (fileio.c).

	+ applied fix from eric krohn to fix uninitialized structure member
	  (tbuff.c).

	+ corrected "EGA" table entry (ibmpc.c)

	+ prevent 'flash' mode from being used until after 'TTopen()' (ibmpc.c)

	+ corrected a hole in 'swbuffer()' that tried to use a null value for
	  'curwp' (buffer.c).

	+ modified to allow "@" startup file to have errors w/o defaulting to
	  "vile.rc", by checking to see if a buffer was created (main.c)

	+ corrected logic of 'vtputc()' and 'vtset()' to make line-wrap display
	  properly when the line contains control characters (display.c).

	+ corrected limits of highlighting in 'change_selection()' (x11.c)

Changes for vile 3.63: (released  Wed Nov 10, 1993)
(tom)
	+ corrected 'pathcat()', to avoid using autoincrement in 'slashc()'
	  macro (path.c).

    	+ cleanup for gcc-2.4.5's -Wall warnings (estruct.h, display.c, exec.c,
	  finderr.c, glob.c, mktbls.c, modes.c, npopen.c, proto.h).

	+ compiled with CenterLine 'clcc' compiler (bind.c, buffer.c,
	  display.c, eval.c, file.c, filec.c, glob.c, globals.c, line.c,
	  tags.c).

	+ corrected 'backpage()' to update mode-line after "previous-page".

	+ modified ibmpc.c to make flash/mouse code more portable.

	+ corrected call on 'strncpy()' in 'kbd_reply()' where 'extbuf' may be
	  copied onto itself.  On HP/UX, this causes the destination to be
	  cleared (input.c).

	+ modified initialization of IBMPC to make "flash" mode work better on
	  MSDOS (ibmpc.c).

	+ modified so that on MSDOS and VMS vile properly handles files that
	  are redirected to it via the standard input (main.c).

	+ corrected bug that caused ":e#" command to ignore the '#' character
	  (exec.c).

	+ corrected handling of ":tag" command so that if a tag's length is
	  shorter than the taglength setting, the shorter value is used
	  (tags.c).

	+ modified 'writereg()' to prevent inadvertent file-write using a
	  read-pipe expression (file.c).
(pgf)
	+ fixed indenting bug in formatregion().  (word.c)

	+ added SHELL=/bin/sh to makefile

Changes for vile 3.62: (released  Mon Oct 11, 1993)
(pgf)
	+ enable DOS mouse processing for Turbo-C only, since some code
	  uses Turbo-isms to get at registers (_AX, etc)  (estruct.h)

	+ change references to x.ax, x.bx, x.di, etc to be x._AX_, x._BX_, etc.
	  to satisfy the Watcom 386 need for eax, ebx, edi, etc.

	+ improper automatic indent on brace insertion fixed (insert.c,
	  fmatch,c, proto.h)

	+ the ls -a output in imdying() was producing a line with a lone '.'
	  on it, which was terminating /bin/mail.  use sort -r to rearrange
	  it. (file.c)

	+ re-ifdefed getscreensize, for machines without SIGWINCH

	+ guard against zero values for tabstop and shiftwidth 	(buffer.c)

	+ added global control variable to make it easy to turn off the
	  "working..." message. (display.c)

	+ don't let hst_append() do anything if clexec is set (history.c)

	+ click the mouse (with xterm-mouse set) no longer calls showcpos().
	  if you want the mouse position, turn on "ruler-mode" (tcap.c)

	+ flash mode is now off by default.  beeps should be beeps until
	  requested otherwise. (main.c)

	+ applied vms path fix in pathcat() (path.c)

	+ don't insert tabs during reformat if notabinsert is set (word.c)

	+ applied patches for djgpp from Jim Crigler. (estruct.h, ibmpc.c)

(tom)
	+ TurboC compiler warnings (history.c, mktbls.c, oneliner.c, search.c).

	+ added TurboC compiler warning patterns (finderr.c).

	+ implemented mouse highlighting for MSDOS (display.c, ibmpc.c).

	+ made the table-driven combinations for $sres work properly (ibmpc.c).

	+ corrected 'repointstuff()', so that undo works properly for multiple
	  windows; other window's dot wasn't being updated (undo.c).

	+ modified 'execute_named_command()' to set dot-moved flag if the
	  range-computation moves it, fixes warning from 'updpos()' (exec.c).

	+ linted remaining size_t usage (basic.c bind.c display.c estruct.h
	  eval.c exec.c filec.c glob.c history.c isearch.c mktbls.c npopen.c
	  oneliner.c proto.h regexp.c search.c spawn.c vmsvt.c).

	+ guarded &left, &right, related functions against negative indices,
	  etc., (eval.c).

	+ changed sizes in regexp-struct to SIZE_T (from short, int) to support
	  lint (estruct.h).

	+ added command-line option "-wm" to set X11 window-manager title
	  (main.c, version.c, x11.c).

	+ modified prompts to make ^V echo until the character is followed by
	  what we want to see a la vi (input.c).

	+ modified treatment of '!' character (in shell prompts) to expand it
	  immediately, more like vi (main.c, history.c, input.c, spawn.c).

	+ corrected some ifdefs that broke !-commands when compiling small
	  configuration for testing (cmdtbl, bind.c, eval.c).

	+ whitespace spawn.c

	+ corrected redisplay logic in 'execute_named_command()' when repeated
	  backspace characters were received (exec.c).

	+ modified logic in 'imworking()' to be a little more conservative when
	  erasing leftover text in the message line, e.g., when it happens
	  during filename-completion on large directories (display.c).

	+ corrected a hole in 'hst_append()' that allowed non-interactive use
	  of the bind-key function to erroneously set the 'clexec' flag
	  breaking subsequent named-commands (history.c).

	+ trailing blank, e.g., "inttgetc(quotec)" breaks apollo
	  ctags by making it generate a pattern only for the "int" (bind.c,
	  input.c, isearch.c, search.c).

	+ modified 'imply_buffer()' so that c-mode is set as in 'readin()'
	  (buffer.c).

	+ corrected 'getfile()' to treat names longer than NBUFN as filenames,
	  and 'unqname()' to assume its 'bname' argument can have a trailing
	  null (buffer.c, exec.c, file.c, main.c).  (This fixes a bug I
	  introduced in 3.60 that prevented using ":e %+" properly, where "%"
	  expands to a long buffer name, because the buffer names are compared
	  with 'strncmp()').

	+ modified 'getfile()' to suppress redundant prompt by using returned
	  state of 'unqname()' (file.c).

	+ modified 'mlreply_file()' to prompt if a wildcard expands to multiple
	  files (e.g., when reading a file) (filec.c).

	+ modified 'tokval()' to expand ~-paths so macros can refer to user's
	  home paths (eval.c).

	+ corrections to vms filename-completion (path.c).

	With Purify demo

	+ corrected memory leak in 'FreeBuffer()' (buffer.c).
	
	+ corrected uninit-memory reference in 'kbd_show_response()' (input.c,
	  history.c), in 'dfputsn()' (display.c).

	+ corrected reference to freed memory in 'listmodes()' and modified
	  logic to use 'animated' logic, and variables 'relisting_b_vals' and
	  'relisting_w_vals'.  As a side-effect, this allows local buffer and
	  window modes to be set in [Settings] (buffer.c, display.c, edef.h,
	  main.c, modes.c).

	+ corrected a null-pointer reference to 'fromline' when a ":0" command
	  was entered in an empty buffer (exec.c).

Changes for vile 3.61: (released  Thu Sep 16, 1993)
(pgf)
	+ when files are saved in /tmp, and mail is sent, the list is now
	  created with "ls -a" to make all files visible. (file.c)

	+ when trying to get back to the current buffer in globber(), use
	  set_curwp() instead of swbuffer(), since swbuffer() may not take
	  us back to the same window we started in, if the buffer is
	  multiply displayed. (globals.c)

	+ moving the cursor with the mouse (xterm-mouse) causes showcpos()
	  to be called, as if a ^G had been typed.  the message line needed
	  to be cleared in any case, to delete old ^G output, so i thought
	  i'd try updating it instead (should a similar change be made in
	  x11.c?). (tcap.c)

	+ in cmode, parentheses are treated like braces, in that if a line
	  ends with a left one, the next line is indented, and if it starts
	  with a right one, the line is aligned with the line containing the
	  match.  this may be useful for parentheses-heavy languages like

(tom)
	+ nits from 3.60 integration (file.c, mktbls.c, proto.h, glob.h)

	+ allow "number" mode to be set/unset in scratch buffers (modetbl,
	  display.c, random.c).

	+ use 'delay()' function in TurboC for 'catnap()' (random.c)

	+ ifdef'd "dirc" and "history" modes so that they don't appear in
	  [Settings] when not configured (modetbl, main.c).

	+ brought TurboC makefile up-to-date (makefile.tbc).

	+ corrected logic of 'makemodelist()' so that both buffer and window
	  local modes are shown (modes.c).

	+ corrected my last change to 'unqname()' to ensure that if the b_bname
	  field is short enough, it will have a null terminator (file.c).

	+ moved logic that reports lines-deleted from 'ldelete()' to common
	  logic of 'operdel()' and 'operlinedel()', so that using 'ldelete()'
	  internally won't generate spurious messages (line.c, opers.c).

	+ used 'doingopcmd' to modify return-status of motion commands (h,l) to
	  get rid of special-case handling so that when used internally they
	  don't fail; obsoleted 'forwchar_in_line()' (basic.c).

	+ use macro 'cmdBIT()' to clarify flags for CMDFUNC, added flag OPTREG
	  to simplify test in 'execute_named_command()', and make test for
	  optional register and/or line-count more explicit by allowing it only
	  when non-punctuation follows the command (fixes ":s/pattern")
	  (cmdtbl, estruct.h, exec.c, input.c).

	+ corrected my last change to make "2p work correctly, by using new
	  function 'index2ukb()' (line.c).

	+ modified 'mlreply_file()' so that filename completion works on the ^W
	  and ^R screen commands (filec.c).

	+ modified 'getregion()' to use line-number to simplify computation,
	  and to work with left-margin.  Also whitespaced (region.c).

	+ corrected test in 'loop()' that caused j/k commands to go awry in the
	  [Registers] buffer at blank lines (main.c).

	+ corrected test in 'kbd_reply()' to avoid name-completion when the
	  current-response is a shell-command, e.g., "!foo -?" (input.c).

	+ corrected logic in 'forwchar_to_eol()' and 'ins_anytime()' that lets
	  arrow-keys to go past the end of the line while in insert (or
	  replace) mode (basic.c, insert.c).

	+ corrected logic that allowed a user to begin an insertion in one
	  buffer, then click the mouse to reposition into a readonly buffer
	  and continue inserting -- in the readonly buffer (basic.c, insert.c).

	+ added mode 'flash' (ibmpc.c, main.c, tcap.c, x11.c)

	+ added logic to support msdos-mouse, using defines OPT_MS_MOUSE and
	  OPT_MOUSE.  This version only supports repositioning clicks (basic.c,
	  display.c, estruct.h, ibmpc.c, termio.c).

	+ use symbol ALLOC_T to clarify distinction between size_t/int/unsigned
	  (display.c, edef.h, estruct.h, eval.c, filec.c, fileio.c, finderr.c,
	  line.c, oneliner.c, proto.h, regexp.c, tbuff.c, undo.c, x11.c)

Changes for vile 3.60: (unreleased)
(pgf)
	+ added "stop" command (synonym for "suspend-vile", aka ^Z) (cmdtbl)

	+ ensure shiftwidth and tabstop are always set correctly after modes
	  are adjusted -- any of cmode, cts/ts, csw/sw can affect. (modes.c)

	+ added support to finderr() for OSF1 (DEC Alpha's, at least) compiler
	  errors, of the form:
		/usr/lib/cmplrs/cc/cfe: Error: test.c, line 8: Syntax Error

	+ took out leftover dbwrite() call from rangespec() -- may fix errant
	  behavior on ":.$d" (exec.c)

	+ fixed helpfile note about X11 -name option -- it sets the name
	  used for resource lookups, not the window name.  (vile.hlp)
	  how do we set the window name?

	+ under DOS, leave the cursor shape and the keyboard repeat rate
	  alone.  if we get complaints, perhaps we should mode-ify these,
	  but in general, settings like that are personal, and we shouldn't
	  muck with them.  (ibmpc.c)

	+ don't introduce extra path separators in pathcat() (path.c)

	+ protect against NULL returns from getcwd, in case the directory
	  we're in has been removed. (random.c)

	+ changed symbol "glob()" to "doglob()" to stop name conflict with
	  standard libraries (glob.c, eval.c, random.c, filec.c)

	+ added prototypes for glob.c to proto.h

	+ eliminated infinite loop when using goto-beginning-of-sentence from
	  end of buffer (basic.c)

	+ added mode "multibeep" to control the "one beep per failed motion"
	  logic -- if multibeep is on (default), then every failed motion
	  produces a beep.  if it's off, then only the first (of a set of
	  identical) causes a beep. (modetbl, main.c)

	+ corrected possible use of uninited locals in file.c (was really
	  only a warning suppression) and  display.c

	+ turned off beeping in search.c and csrch.c, now that all failed
	  motions cause beeps.

	+ change "Date" to "installed" in version.c, since modtime really
	  only reflects installation date.

	+ don't let vile use a screen dimension of less than 2 in either
	  direction (display.c, tcap.c)

	+ fixed bug that made all TERM types be thought of as xterms. (tcap.c)

	+ fixed documentation of the help commands.  it's been wrong
	  for over three years now, and it's in the first screen of
	  help! (^X-^H and ^A-^H should be ^X-h and ^A-h) (vile.hlp)

	+ added AIX to the machines that need sys/ioctl.h, to pick up
	  TIOCGWINSIZE (display.c)

	+ reset the "calledbefore" flag in docmd().  fixes chris sherman's
	  problem where a second substitute-til in a macro would appear to
	  do nothing.  (actually it was reusing its previous args, so there
	  was simply nothing to do)  (exec.c)

	+ added '>' to the characters known to the reformatting code, so
	  you can reformat most email replies. (word.c)

	+ added automatic patchfile generation to the makefile.  hopefully
	  i can generate patches for all future releases, in addition to
	  shar files. (makefile)

(tom)
	+ made ansi.c work with TurboC (ansi.c, main.c, display.c, termio.c),
	  to use as test-case for COLOR.

	+ corrected highlighting code for ":%s" command with ibmpc display
	  (display.c, ibmpc.c).

	+ modified 'bfind()' to always return a buffer (unless it cannot create
	  the buffer), use 'find_b_name()' for the no-create mode (bind.c,
	  buffer.c, eval.c, exec.c, file.c, filec.c, finderr.c, history.c,
	  main.c, map.c, modes.c, oneliner.c, random.c, spawn.c, tags.c).

	+ use macros 'set_bname()' and 'eql_bname()' and function 'get_bname()'
	  to encapsulate buffer name, which does not necessarily have a
	  trailing null (bind.c, buffer.c, display.c, estruct.h, eval.c,
	  exec.c, file.c, finderr.c, input.c, main.c, modes.c, oneliner.c,
	  spawn.c, tags.c, tmp.c).

	+ removed nonstandard 'strncpy()' (main.c).

	+ corrected 'kbd_show_response()' to work with expand-chars mode
	  (input.c).

	+ corrected 'kbd_reply()' to make the number of characters shown have
	  the same limit as the caller's buffer-length, and to make it always
	  return the data with a trailing null (input.c).

	+ made 'animated' mode work for [Registers] buffer (line.c), and
	  modified the logic so that numbered-buffers are displayed in a
	  vi-compatible manner.

	+ make shift-commands work more like vi, allowing repeated '<' or '>'
	  characters in a :-command to imply a repeat count (bind.c, exec.c,
	  opers.c).

	+ corrected logic of 'dofile()' so that if an error is found in the
	  startup file, vile properly sets curbp and curwp (exec.c).

	+ simplified/corrected command-history logic of to fix error that
	  prevented scrolling past ":e!" command, and to allow scrolling of
	  '<', '>' command even when repeated (bind.c, exec.c, history.c,
	  spawn.c).

	+ added flag KBD_EXPCMD to handle the case (from rewrite of history)
	  where %,#,: expansion must be done for shell commands (estruct.h,
	  bind.c, input.c).

	+ added OPT_HISTORY to allow ifdef'ing of history.c code (estruct.h,
	  history.c)

	+ cache home-directories looked up in 'home_path()' to make it run
	  faster (path.c)

	+ modified glob-expansion to allow "~" expansion.  This doesn't work
	  with wildcards in the user-portion (e.g., "~ab?"), but suffices for
	  most cases (glob.c).

	+ added a find-error case for apollo's C++ compiler (finderr.c).

	+ modified logic for 'displaying' vs 'imworking()' slightly, to get rid
	  of erroneous cursor movement (display.c).

	+ added function 'slowtime()' to force updates in 'slowreadf()' more
	  often (file.c).

	+ adjusted definitions for better lint checks on apollo sr10.2
	  (estruct.h, makefile).

	+ make piped-input also set error-buffer (main.c).

	+ revised logic that sets VAL-structs for modes to correct places where
	  buffer & window traits are saved without converting to local values.
	  Also removed code (e.g., copy_val) that checks reference counts,
	  since they aren't really necessary (buffer.c estruct.h main.c modes.c
	  proto.h)

	+ modified behavior of 'unsetl' command to delete local setting
	  (eval.c, modes.c).  It was only modifying (toggling) boolean modes.

	+ corrected 'reframe()' to handle linewrapping case submitted by
	  alistair (display.c).

	+ corrected cursor-update in 'x_scroll()' that left stray cursor images
	  remaining after ^D/^U commands (x11.c).

	+ corrected logic that caused selection-text to be lost when keypress
	  was received (x11.c).

	+ modified X-windows pasting to trim unneeded whitespace when inserting
	  into cmode or autoindent buffer (bind.c, x11.c).

	+ corrected kill-buffer flag KAPPEND, which had the same value as
	  KLINES (estruct.h, line.c).

	+ corrected error in 'doindent()' that caused a "}" insertion to
	  delete nonwhite characters (insert.c).

	+ corrected ":tags" command for exact (taglen=0) lookups (tags.c)

	+ make failed motion-commands sound an alarm like vi (main.c).

	+ modified logic for h,j,k,l,^D,^U,^F,^B commands to return false when
	  they fail, so failed-motion alarm works (basic.c).

	+ corrected logic for b,B,w,W,e,E commands to return false only when
	  backing/forwarding past the buffer ends (word.c).

	+ modified alternate-window motions 'scrnextup()', 'scrnextdw()',
	  'mvdnnxtwind()', 'mvupnxtwind()' to also return failed-motion status,
	  for consistency (window.c)

	+ made new function 'forwchar_in_line()' to do the vi "l" command,
	  dissociating it from the internal motion-command (basic.c, cmdtbl).

	+ made 'backhpage()', 'forwhpage()' motion-commands (cmdtbl).

	+ make failed quit-commands return false (main.c).

	+ make version-command show UNIX or VMS executable's date (main.c)

	+ corrected behavior of 'histbuff()' when user simply toggles with the
	  "_" command.  This did not handle the case in which the alternate
	  buffer was temporary, and thus had no number (buffer.c).

	+ introduced new buffer-attribute 'b_lim_left', macro
	  'w_left_margin()', ifdef'd with OPT_B_LIMITS, use this to control
	  cut/paste selection in [Registers] (basic.c, buffer.c, csrch.c,
	  display.c, random.c, region.c, window.c, x11.c).

	+ modified 'execute_named_command()' to recognize register name and
	  line-count for commands such as ":yank", making it handle cases such
	  as ":5>6", ":y a 6", ":10,20y b" (exec.c, input.c, line.c).

	+ modified ":put" command to report the number of lines added (line.c).

	+ split out 'version.c' because main.c got too large for apollo lint
	  (main.c, makefile*, vms_link.opt, link.msc).

Changes for vile 3.59: (released Wed Aug 18, 1993)
(pgf)
	+ added VIEWOK flag for functions that execute macros.  it says
	  it's okay to execute them in view mode, even though they have the
	  UNDO bit set.  this fixes not being able to run @, :map'ed, or
	  ^X-& macros in view-only buffers.

	+ made the xterm-mouse mode available in xvile as well as vile, to
	  make it easier to share .vilerc between the two versions.  the
	  alternative is to insist that people put ~force set xterm-mouse
	  in .vilerc, to override the error they'll get in xvile from the
	  mode not being present. (input.c, modes.c, estruct.h)

	+ changed default value of "xterm-mouse" to off, to make vile behave
	  like it used to, and like other character applications, by default.
	  (main.c)

	+ turned off support for the "working..." message for builds that
	  define USG, since they probably have non-restartable system calls.
	  (estruct.h)

	+ accept any TERM variable that ends in "xterm" to be an xterm.
	  (tcap.c, vile.hlp)

	+ fixed "uninitialized variable 'req'" when compiling without REVSTA
	  defined. (display.c)

	+ fixed missing closing double quote in "make all" help output.
	  (makefile)

	+ bumped the maximum row count from 100 to 200.  i personally can't
	  read more than about 70 lines on a 19" mono monitor, but maybe
	  i need glasses. (tcap.c, x11.c)

	+ took out extraneous trace.h include from x11.c

	+ corrected 'col2offs()' to make it easier to position the mouse on a
	  tab character (display.c).

Changes for vile 3.58: (released Fri Aug 13, 1993)
(pgf)
	+ added "sys$login:" to VMS file search path for vile.rc

(tom)
	+ refined 'imworking()' to get rid of leftover working-message
	  (display.c, file.c).  Make working-message show up only when 'terse'
	  mode is off (the default).

	+ added code to support xterm mouse-clicking (to move dot), with
	  additional code for later use with highlighted selections.  Made this
	  a mode (xterm-mouse) because it does not implement cut & paste yet
	  (basic.c, display.c, input.c, main.c, modes.c, tcap.c).

	+ added calls to 'TTkopen()' and 'TTkclose()' to termio.c so that (for
	  all systems) we call these within 'ttclean()' and 'ttunclean()'
	  (termio.c, tcap.c).

	+ optimized display of 'ruler' (display.c)

	+ use 'displaying' as a semaphore rather than true/false flag, as a
	  guard against interrupt by 'imworking()' which modifies ttcol and
	  ttrow (bind.c, display.c, main.c, tcap.c, x11.c).

	+ make ":=" command accept address (like vi) to show arbitrary address
	  value (cmdtbl, estruct.h, exec.c, random.c).

	+ don't let 'write-til' move dot (cmdtbl).

	+ modified 'doindent()' to trim leading whitespace (like vi) from the
	  portion of the line after dot (insert.c).

	+ modified insert-code to treat the combination of repeat-count and
	  newline like vi, causing the repeat count to apply only to the
	  insertion-string before a newline.  (edef.h, input.c, insert.c)

	+ corrected handling of '.' repeat-count for r,R commands (insert.c)

	+ modified user-variables to make them dynamically-allocated, and to
	  remove the restriction on the length of their names (mktbls.c,
	  estruct.h, eval.c, main.c).  Also corrected treatment of newline in
	  prompt for user-variable name.

	+ used 'strncpy()' to copy return-values from 'kbd_reply()', just in
	  case macro-tokens are too long (input.c).

	+ don't expand '%' or '#' in 'kbd_reply()' if it would be the name of
	  an invisible buffer (input.c).

	+ added universal-modes 'expand-chars' to list the characters to expand
	  in 'kbd_reply()', and 'expand-path' to control whether %/# are shown
	  as full, or shortened paths (modetbl, input.c, main.c).

	+ modified X-windows config to allow processing of events when the
	  working-message code is executed (display.c, x11.c).  This makes the
	  screen refresh and keyboard handling work better.

	+ added 'animated' buffer-mode to control whether vile updates
	  scratch buffers when their contents would change (e.g., the buffer
	  list), made this work for buffer-list (buffer.c, display.c,
	  estruct.h, modes.c, modetbl).

	+ revised the 'killbuffer()' code to work properly with the animated
	  mode (buffer.c).

	+ modified mktbls to check for illegal mode-names (mktbls.c).

	+ linted with SMALLER set (to get rid of unused functions), introduced
	  new ifdef with OPT_EVAL to simplify (basic.c bind.c buffer.c cmdtbl
	  estruct.h eval.c insert.c line.c lint.out modes.c npopen.c proto.h
	  window.c).

Changes for vile 3.57: (released Fri Aug 06, 1993)
(pgf)
	+ the bug check for b_ulinep pointing at a newly inserted line is
	  no longer valid, since we can now insert a line, make changes (which
	  will set b_ulinep), undo those changes, and then undo the insert.
	  we now just null out b_ulinep when we remove the line it references.
	  (undo.c)

	+ changed name of setmode() to avoid library conflict with djgpp, and
	  changed the other del/setg/delg versions as well.  (cmdtbl, modes.c,
	  proto.h)

	+ took out #define USG 0 since djgpp uses an #ifdef on this in a header
	  (estruct.h)
(tom)
	+ whitespace in basic.c

	+ corrected definition of ScratchName macro for apollo SR10.2
	  (estruct.h) and a compiler warning (in glob.c).

	+ corrected gcc warnings about 'signal()'-arguments for SunOs.

	+ use new macros ACTUAL_SIG_ARGS, etc., instead of ACTUAL_SIGNAL so
	  that the tag-file can find the signal-handling procedures (estruct.h,
	  display.c, file.c, main.c, proto.h, spawn.c, x11.c).

	+ customized the c-suffix default values for VMS, MSDOS and UNIX.

	+ VAX/VMS C does not allow continuation-lines in ifdefs (mktbls.c).

	+ VAX/VMS C may incorrectly set ferror() when feof() is true (fileio.c)

	+ VAX/VMS C 'rewind()' does not work correctly (fileio.c)

	+ added code to show "working..." message for time-consuming operations
	  (display.c, npopen.c, vmspipe.c), and to allow 'slowreadf()' to show
	  its progress (file.c, fileio.c).

	+ linted calls on 'signal()', (main.c, display.c, spawn.c, termio.c).

	+ linted calls on 'firstnonwhite()' (basic.c, exec.c, insert.c, line.c,
	  opers.c, region.c, spawn.c, word.c).

	+ use new functions 'end_named_cmd()', 'more_named_cmd()' for clarity
	  (exec.c, file.c, map.c, oneliner.c)

	+ added new mode 'ruler' (to display line+column in a window on the
	  modeline), and new window-flag WFSTAT to support it (by allowing
	  non-modal information to affect the modeline).  (display.c)

	+ corrected error I introduced into 'reframe()', and in 'row2window()'
	  while adding 'linewrap' mode (display.c).

	+ corrected code that frees buffer's fname-field for the special case
	  of out-of-memory (buffer.c, random.c).

	+ added new command 'tagstack' to show the contents of the tag-stack.
	  Modified 'tags()' to use module-level 'tagname[]' rather than local
	  copy of tag-string.  (tags.c)

	+ always update the modtime-at-warn buffer field when prompting
	  for the check-modtime mode (file.c).

	+ removed (obsolete) code for DEC Rainbow (estruct.h, display.c,
	  termio.c).

	+ modified 'line_no()' to return values in the range 1..MAX+1
	  instead of 0..MAX (random.c).

	+ corrections to make X11 version work with 'number', 'linewrap' modes,
	  to guard against selection extending outside a window, to highlight
	  only the actual text within a window, and to use 'yankregion()' to
	  save the paste-text.  (basic.c, display.c, window.c, x11.c)

	+ modified 'typahead()' to know when X-windows is pasting, and the
	  paste-init code to supply an escape to end insert-mode, and to use
	  TBUFF's so that nulls can be inserted (termio.c, x11.c).

	+ put the repeat-count in 'map_proc()' back the way Otto Lind had it
	  (map.c).

Changes for vile 3.56:	(released Tue Jul 27, 1993)
(pgf)
	+ after a confirm substitute operation, we now mlerase the confirm
	  prompt (oneliner.c)

	+ be sure the [vileinit] buffer is marked as scratch while doing the
	  bprintf into it, so undo record-keeping will be suppressed. (main.c)

	+ rearranged calls to chg_buff and ldelnewline in ldelete, so that
	  the buffer will still be marked clean on first toss/copy/tag to
	  undo.  unmodified state is now restored correctly after a :g/^$/d is
	  undone. (line.c)

	+ In regular expressions, \s and \S are now true atoms.  they both
	  must now be followed by * or + to match more than one.  also, \s
	  no longer matches BOL or EOL (thanks to alistair and eric for
	  pointing out and fixing) (regexp.c)  In practice this means that
	  one should use \s* or \s\+ where one used to use just \s.  also,
	  if a match against ^ or $ is necessary, it must be done explicitly,
	  e.g. /\(^\s*\|\s\+\)word/ instead of /\sword/

	+ adjusted paragraph/section/comment/sentence regexps, with help
	  from eric, to reflect change to \s and \S

	+ make the #ifdef USE_TERMIO version of ttclean() be a no-op under
	  X11, as it is in the other cases.  eric's right -- termio.c needs
	  a rewrite.  (termio.c)

	+ don't pass the (0) to getpgrp if we're POSIX and ANSI -- the
	  library is probably the right one, and there's a high probability
	  of a prototype conflict if we _do_ pass it.  (spawn.c)

	+ When looking up X defaults, the old code checked the class first,
	  then the specific program name.  This is backwards since if the
	  class value exists, there is no way to override it with the -name
	  option.  (x11.c)

	+ AIX and pyramid think we have non-constant case expressions (eval.c)

	+ There is no requirement in ANSI C for SCRTCH_LEFT and SCRTCH_RIGHT
	  to be expanded before the ##.  Some preprocessors do and some don't.
	  However, the other #define using just #s and string concatenation
	  seems to work everywhere.  (estruct.h)

	+ clarified usage of &sin function, which searches its first argument
	  for an occurrence of the second.  (vile.hlp)

(tom)
	+ renamed UCHARAT to UCHAR_AT; added defs for UCHAR USHORT, UINT and
	  ULONG for easier linting/reading (bind.c, dirstuff.h, estruct.h,
	  file.c, history.c, ibmpc.c, input.c, isearch.c, line.c, oneliner.c,
	  proto.h, tbuff.c, vmalloc.c, vmsvt.c, x11.c, z_ibmpc.c)

	+ make 'prc2kcod()' return an int again, some optimization of 'token()'
	  (bind.c, file.c).

	+ clean-compiled/tested X11 + DEBUGM + OPT_MAP_MEMORY with gcc
	  (basic.c, edef.h, exec.c).

	+ disable filename-completion when OPT_MAP_MEMORY is enabled.

	+ added mode 'newline', set to true when reading files that have a
	  trailing newline (the normal vi-convention), modified (file.c,
	  buffer.c, random.c).

	+ fixed place where ":ww" garbages the screen before reporting
	  "wrote 0 buffers" (buffer.c).

	+ simplified 'writereg()' and 'ffputline()' (fileio.c, file.c) to allow
	  'newline' mode to control whether a trailing newline is written to
	  output files.

	+ modified 'kifile()' so that it does not insert the trailing newline
	  if it wasn't present in the file.

	+ made 'ldelete()' return from one point (line.c) to simplify 'report'
	  mode.

	+ added mode 'report', to specify the number of changes before a
	  message is emitted:
		NN lines deleted		6dd
		NN more lines			u
		NN fewer lines			u
		NN fewer lines			:g/^$/d
		NN lines yanked			"a8yy
		NN substitutions on MM lines	:%s/x/XX/g
		NN substitutions		:%s/x/X/
	  (globals.c, line.c, undo.c, oneliner.c, random.c, region.c)

	+ corrected unnecessary screen-update in 'substline()' (oneliner.c)
	  introduced in confirm-changes.

	+ added 'linewrap' mode (basic.c, buffer.c, display.c, windows.c).

	+ corrected cursor movement for large repeat counts with 'H' command
	  (basic.c).

	+ ifdef'd 'screen_string()' to handle apollo compiler warning when
	  testing SMALLER configuration.

	+ added stubs for modes 'popup-msgs', 'popup-choices'.

Changes for vile 3.55: (released Mon Jul 19, 1993)
(pgf)
	+ new routine, mlquickask(), which prompts for and returns a single
	  key answer from a user.  use this when getting a confirm from a
	  user for a substitute command. (input.c, oneliner.c, proto.h)

	+ documented the 'c' for confirm (vile.hlp)

	+ the token() routine now expands numeric escape codes, like \nnn and
	  \xNNN where nnn are octal and NNN are hex digits.  this may affect
	  vilerc files that have \ sequences in them.  support for mapping
	  to key-sequences like 0xNN is gone -- use \xNN instead.  this will
	  make it easier to do multi-char maps in the future.

	  note that \000 will cause internal problems, since things are null-
	  terminated, and the sequences "", "", and "^C" are all
	  problematic when multi-char sequences come around.

(alistair)
	+ added highlighted confirm to ":s" command.  (oneliner.c, display.c)

(tom)
	+ modified 'makebindlist()' (in bind.c) to format using tabs rather
	  than spaces.

	+ many mods to map.c (and bind.c) to eliminate redundancy between it
	  and bind.c

	+ modified 'prc2kcod()' to look for only one prefix, but allow
	  hexadecimal code in form 0xff.

	+ corrected a recursion bug in 'install_map()' (file map.c)

	+ modified ":map" (file map.c) to show show mappings if no values are
	  given.

	+ fix strict gcc warnings in x11.c, consolidated some initialization
	  code and corrected font-ascent value (so 9x15 works properly).

	+ added "on" and "off" to literals in 'stol()' (file eval.c) to use
	  this in x11.c

	+ modified 'killbuffer()' in buffer.c to recognize a repeat-count
	  (e.g., allows ^X-k within the buffer list to remove a succession of
	  buffers).

	+ fix strict gcc warnings in ansi.c

	+ make command-history record properly for bind-key and map commands
	  (files bind.c and map.c).

	+ modified 'engl2fnc()' (in bind.c) to allow unique abbreviation (so
	  that scripts don't have to be spelled out), added "se" symbol to
	  cmdtbl for vi-compatibility.

	+ modified 'docmd()' (file exec.c) to allow leading ':' in scripts
	  for vi-compatibility.

	+ corrected logic in modes.c to (re)allow trailing whitespace on
	  the end of set-commands.

	+ merged files makmktbl.tbc and makvile.tbc into makefile.tbc

	+ eliminated 'VIDEO *' arguments from 'updateline()' in file display.c
	  because the 'row' argument already provides this information.

	+ added 'offs2col()' to correct position of highlighting when
	  confirming substitutions.

Changes for vile 3.54: (released Fri Jul 09, 1993)
(pgf)
	+ will now call setvbuf instead of setbuffer if USG defined in the
	  POSIX version of ttopen.  this to support SVR4 (well, solaris)
	  (termio.c)

	+ took out the more stringent prototype warnings (-Wstuff) from the
	  gcc OPTFLAGS, since we don't pass them yet (someday, alistair).
	  (makefile)

	+ mode and variable symbol names generated by mktbls are now of the
	  form "s_name__" instead of "s_name", to be more unique.  (there
	  was a conflict with a (naturally named) typedef of signed char to
	  "s_char".)  (mktbls.c)

	+ upped the max number of screen columns for x11.c.  was 150, now is
	  200.  reduced the max rows number from 200 to 100.  the screen
	  buffers should be made re-allocatable, so we wouldn't eat the space
	  unless necessary.  made the normal (tcap.c) maximums match these.
	  (tcap.c x11.c)

	+ applied Tuan Dang's fixes for my merging of his watcom and djgcc
	  patches.  Thanks Tuan!  (makefile.wat, ibmpc.c, estruct.h, path.c,
	  mktbls.c)

	+ turn DOS mode on by default for DOS versions of vile. (main.c,
	  vile.hlp)

Changes for vile 3.53: 	(released Thu Jul 07, 1993)
(pgf)
	+ stop core dump on file completion (":e fi") by making sure
	  BFSIZES bit is cleared when building MyBuff

	+ in rtfrmshell(), there was a "curwp->w_flag = WFHARD" statement,
	  with a comment asking if it was needed.  in fact, it's wrong, so
	  i took it out.  it was tromping other flags, like WFMODE, for that
	  window only (spawn.c).

	+ in update(), don't add nu_width to screencol if the buffer is empty,
	  since there is no line number in that case. (display.c)

	+ fixed bug when undoing the first insertion into an empty buffer.
	  the value of dot was being restored to the inserted (and now gone)
	  line.  (line.c)

Changes for vile 3.52:
(pgf)
	+ added a couple of tweaks to tom's check-modtime changes -- prompts
	  are not suppressed if you're writing the buffer out, and running
	  a shell only checks visible buffers for modtime changes, rather
	  than all buffers. (mostly file.c, estruct.h, random.c)

	+ changed name of "timeout-value" to "timeoutlen", to match some
	  versions of vi.  (modetbl, vile.hlp)

	+ applied patches from Tuan DANG (dang@cogit.ign.fr) to support
	  DJGCC v1.09 (display.c, estruct.h fileio.c ibmpc.c main.c mktbls.c
	  modes.c path.c random.c spawn.c termio.c)

	+ consolidated TURBO, WATCOM, MSC, ZTC, and GO32 under a new,
	  presumptuous #define, called NEWDOSCC. (mostly same files as djgpp
	  changes)

	+ fixed calloc macro (estruct.h) in RAMSIZE ifdef

	+ added map.c/map.obj source file for VMS (descrip.mms, vms_link.opt)

	+ removed bogus dbgwrite in exec.c, where linespec returns a value
	  for "toline" which can be null.

Changes for vile 3.51:
(pgf)
	+ added a couple of tweaks to tom's check-modtime changes -- prompts
	  are not suppressed if you're writing the buffer out, and running
	  a shell only checks visible buffers for modtime changes, rather
	  than all buffers.

	+ added regexp metacharacter "index" in margin of vile.hlp.

	+ renested some limit setting in scanner(), so I can understand it
	  again. (search.c)

	+ changed name of ABS macro to ABSM to avoid namespace conflict
	  on OSF/1. (cmdtbl, exec.c estruct.h)

	+ made :map to SPEC key-sequences work (map.c insert.c)

	+ undo now preserves current column as well as row (undo.c estruct.h)

	+ changed name of "naptime" to "timeout-value"  (main.c modetbl
	  vile.hlp input.c)

	+ added new variable $mode, which is the name of the user-mode we
	  e're in: "command", "insert", "overwrite".  the value is set
	  when we enter insertmode, and restored when we leave.  this lets
	  macros invoked from within insert mode find out if they should
	  enter insertmode.  (eval.c, modetbl, insert.c, proto.h, vile.hlp)

	+ prc2kcod will now accept literal control chars, and also will
	  accept hex specifications.  so now key-sequences can be specified
	  as follows:		(bind.c map.c vile.hlp)
	  	an optional prefix:
			^A	(one char)
			^A-	(three chars)
			^X	(one char)
			^X-	(three chars)

		followed by an optional "function" prefix:
			FN-	(three chars)
			M-	(two chars)
		    (these two are synonymous)

		followed by a character:
			C	(one char)
			^C	(one char)
			^C	(two chars)
			0xNN	(four chars)
			0XNN	(four chars)
				(five chars)
				(four chars)


	+ removed old BEFORE ifdefs (input.c insert.c)

	+ better error checking on parsing of key-sequences in exec'ed files.
	  (bind.c)

	+ if dobuf() encounters an error, it switches to that buffer.  but
	  until now, this error propagated back through nested dobuf()'s,
	  and we ended up looking at the 'source "filename"' line in the
	  outermost buffer.  now we only switch on the most deeply nested
	  dobuf().  also, we no longer set file buffers that we're executing
	  to view-mode.  (exec.c)

	+ if we get an error on startup, we skip right to the editing loop,
	  so the user gets confronted with the error right away.  (main.c)

	+ gave adjustmode a real return value -- used to always return TRUE.
	  (modes.c)

	+ when looping backwards backspacing, check if the input char was
	  killc or wkillc before checking isbackspace(c), since otherwise
	  if killc is DEL, we'll treat it as backspace first.  (this is
	  because ^H and DEL are both assumed to be backspacers initially)
	  (insert.c input.c)

	+ implemented new universal mode, "naptime", which is the number of
	  milliseconds to delay before accepting a lone ESC character,
	  rather than as the start of a function key sequence.  also added
	  boolean arg to catnap(), which controls whether detection of user
	  input will abort the catnap delay.  the default for this mode is
	  500 milliseconds.  the old value was 50, which was fine for fast
	  local displays, but didn't work well for serial terminals or
	  rlogin sessions.  (which surprises me somewhat -- 9600 baud
	  translates to roughly 1 character per millisecond -- why is a
	  delay of 50 ms not enough for the second character of a function
	  key generated by a terminal?) (proto.h fences.c input.c random.c
	  modetbl vile.hlp main.c)

	+ applied patches for Watcom C/386, from Tuan DANG (dang@cogit.ign.fr).
	  I haven't had a chance to try them yet. ( mktbls.c cmdtbl estruct.h
	  dirstuff.h ibmpc.c main.c fileio.c random.c termio.c display.c
	  glob.c npopen.c path.c proto.h spawn.c makefile)

	+ renamed turbo makefiles, to be more similar to the watcom makefiles.

	+ fixed insert-string to really insert instead of overwrite.

(tom (3.51))
	+ added buffer-mode 'check-modtime' to check if the disk-file is newer
	  than the buffer when reading, writing or popping a window (adapted
	  from a patch by Randy Winney, modifies (files file.c, fileio.c,
	  buffer.c, random.c, spawn.c).  Note that moving the cursor between
	  buffers does not perform this check.

	+ use macro 'for_each_line()' in some more places (files: buffer.c,
	  globals.c, random.c, spawn.c, vmalloc.c).

	+ use new function 'SetCurrentWindow()' in file window.c.

	+ added checking in 'SetVarValue()' (file eval.c) to guard readonly
	  buffers from modification.

	+ added checks in file mode.c to prevent major-mode changes to scratch
	  buffers (and corrected the settings of WFMODE in file modetbl).

	+ tested/augmented RAMSIZE configuration option (files main.c,
	  display.c), made a mode 'showram' to control it.

	+ merged field that shows major-modes in the modeline (e.g.,
	  "view-only"), and added "cmode" when it is active.

	+ added buffer-flag BFSIZES; use it in 'bsizes()' to compute byte/line
	  counts only when buffer has been changed.  Also, added function
	  'add_line_at()' to merge file-reading logic which initializes the
	  byte/line counts (files: buffer.c, file.c).

	+ if dos-mode is set on a buffer, trim carriage-returns from files that
	  are inserted into it (file file.c).

	+ renamed macros in file buffer.c that test BUFFER.b_flags, added
	  macros for setting/clearing these flags, moved the macros to
	  estruct.h to use in files bind.c, buffer.c, file.c, history.c,
	  modes.c, random.c, spawn.c, tags.c, undo.c.

	+ corrected size shown for buffer-list within the buffer-list display
	  (file buffer.c).

	+ use window-colors for modelines rather than global values (file
	  display.c).

	+ disable ":p" command from within buffer-list display (oneliner.c)

Changes for vile 3.50:
(pgf)
	+ finished (yeah, right) the changes for infinite undo. implemented
	  mode to control how many changes are stored (called "undolimit").
	  the modified bit (BFCHG) now gets reset if the right number of
	  undos is done.  (estruct.h main.c modetbl undo.c buffer.c vile.hlp)

	+ rearranged calls to copy_for/tag_for/toss_to_undo and chg_buff
	  so that the BFCHG flag is unmodified before the first call to
	  preundocleanup().  this gives undo the true state of BFCHG.
	  (line.c region.c)

Changes for vile 3.49:
(pgf)
	+ implemented infinite undo, on keys ^X-u (undo) and ^X-r (redo).
	  probably affected location of cursor after some undo operations --
	  don't if this will be significant or not -- i doubt we matched
	  vi before in this regard anyway.  (undo.c, cmdtbl, buffer.c, proto.h
	  estruct.h, vile.hlp)

	+ use an explicit %s when printing lone filename, to protect against
	  filenames with % in name. (display.c)  (eric krohn)

	+ don't allow kbd_putc to print to last column of display, since if
	  the terminal autowraps, this causes a scroll.  this should check
	  the :am: capability, but we're at the wrong layer to do that, and
	  it doesn't seem worth adding to the TERM struct to make that info
	  available (unix-pc behavior pointed out by eric krohn).

	+ added Otto Lind's initial :map implementation (map.c, main.c,
	  cmdtbl, makefile, proto.h)  This is a good start, but has the
	  following limitations:  1) no string to string maps.  only simple
	  keysequences are mappable.  2) not integrated with the keyboard
	  macro routines -- this would make sense, and allow for recursion
	  to be detected more properly.  but the keyboard macros are pretty
	  tied into the named registers, which are stored in KILLREGS,
	  which doesn't seem right for the :map'ed things.  perhaps we could
	  dispense with the KILLREGS, and replace them with tbufs.  then some
	  small changes the layering of start/finish_kbm and kbm_started
	  could allow the :map code to share those routines.

	+ added alistair crooks' lint stuff and change for the NeXT. (proto.h,
	  mktbls.c)

(tom)
	+ modified file undo.c so that changes to scratch buffers can be
	  undone.

	+ modified 'imply_alt()' in file buffer.c so that the top/current line
	  numbers are propagated into the alternate buffer.

	+ changed environment variable 'directory' to 'cwd' so that 'directory'
	  can be used for vi-compatible directory variable (used to control
	  where the temp-file is written).

	+ implemented environment variable 'directory' (files modetbl, eval.c)
	  and used it to control temp-file location (npopen.c, tmp.c).  This is
	  set by the environment variable TMP.

	+ changed logic that opens/closes temp-file in tmp.c to use 'tempnam()'
	  to derive the filename; added entrypoint 'tmp_cleanup()' to remove
	  the temp-file on exit, and 'exit_program()' to file main.c to make a
	  single exit-point from which to call 'tmp_cleanup()'.

	+ Use macro 'ExitProgram()' to hide whether we call 'exit_program()' or
	  'exit()' (files main.c, display.c, ibmpc.c, spawn.c, vmsvt.c, vt52.c,
	  termio.c, termcap.c, file.c, window.c, x11.c).

	+ modified 'mktbls.c' to generate definitions for 'nemode.h' in a
	  form that allows modes to be conditionally compiled.

	+ added a column to 'modetbl' to ifdef out modes that are not used.

	+ made 'crypt', 'fcolor' and 'bcolor' modes ifdef-able (files main.c,
	  modes.c, modetbl).

	+ simplified 'promptpattern()' and 'expandp()' in file isearch.c

	+ corrected USE_D_NAMLEN ifdef in 'expand_pattern()' (file glob.c)

	+ corrected behavior when user inserts a newline into an empty buffer
	  (file line.c).

	+ moved environment variable definitions from cmdtbl to modetbl to
	  ensure that name-completion table for modes+vars is updated in one
	  place.  Sorted the environment variable names in modetbl and vile.hlp

	+ include "nevars.h" within main.c to allow common name-completion
	  table (without introducing lots of extra string-pointer variables).

	+ modified mktbls.c to put the environment-variable names into the
	  'all_modes[]' array in nemode.h (to support common name-completion).

	+ modified 'listvars()' in file eval.c to optionally show all modes
	  and environment variables in one list (if the user supplies a numeric
	  argument before the "show-variables" command).

	+ modified 'gtenv()' in file eval.c to recognize mode-names as well as
	  environment names, and logic in file modes.c to recognize environment
	  names.  Thus, for example, the commands
	  	":setl dos" and
		":setv $dos=true".
	  are equivalent.

	+ changed use of 'sprintf()' to 'lsprintf()' (files buffer.c, modes.c)

	+ use macros 'FreeAndNull()' and 'FreeIfNeeded()' to simplify code
	  (buffer.c, eval.c, file.c, filec.c, main.c, modes.c,
	  npopen.c, oneliner.c, search.c, random.c, x11.c)

	+ changed case-statements for EV-variables to if-then-else-if in
	  file eval.c because VAX-C cannot handle constant-expression
	  OFFSETOF as case-values.

	+ added 'tempnam()' to file vms2unix.c (to support testing of
	  mapped-data configuration).

Changes for vile 3.48:
(pgf)
	+ added FILEC_PROMPT flag to mlreply_file call in writeregion, to
	  make ^W file-writing operator work.

	+ folded some long lines (opers.c filec.c file.c)
(tom)
	+ corrections to make undo work properly with mapped-memory option
	  (files buffer.c and tmp.c).

	+ use symbol 'null_ptr' to tidy up references to '(LINE *)0'
	  (files buffer.c fences.c line.c main.c undo.c)

	+ changed LINE.l_size to SIZE_T (to make it lintable)

	+ corrected "poison" code in 'lfree()' (file line.c)

	+ added logic to finderr.c to handle lint output on apollo.

	+ added logic to handle line truncation (files buffer.c, file.c,
	  line.c, tmp.c)

	+ added function 'l_region()' to file tmp.c; use this (with some
	  reorganization) in files file.c, oneliner.c, region.c, word.c to
	  track LINEPTR adjustments in REGION structs.  (Converted most of the
	  calling procedures to single-return to clarify this).

	+ moved options-logic in 'substreg1()' (file oneliner.c) down to make
	  this simpler (and avoid unnecessary goto).  (This procedure has too
	  much logic to convert to single-return).  Also fixed a place that
	  should have used 'end_string()'.

	+ used macro 'same_ptr()' to compare LINEPTR's directly (a bit more
	  efficient).

	+ implemented page-swapping logic in file tmp.c

	+ modified ifdefs in files bind.c, eval.c, finderr.c to get rid of
	  compiler warnings when SMALLER, REBIND and APROP ifdefs are turned
	  off.

	+ used 'memcpy()' and 'memset()' in files buffer.c, line.c to simplify
	  loops copying text into LINE's.

	+ modified interfaces of functions that may modify 'LINE *' pointers
	  (or, equivalently, cause swapping of a LINE to a different address)
	  to use LINEPTR arguments (for example, 'line_no()' can iterate over
	  all lines, causing swapping).  Also modified functions (especially in
	  files line.c and undo.c) to use LINEPTR variables where they call
	  lower-level functions that may page-swapping.  Affects files
	  buffer.c, display.c, exec.c, file.c, filec.c, input.c, line.c,
	  oneliner.c, random.c, region.c, search.c, vmalloc.c, word.c

	+ replaced call on 'lalloc()' in file exec.c with 'addline()' (only
	  difference is that the latter also sets b_dot).

	+ converted several functions in file undo.c to static (to simplify
	  tinkering with LINE/LINEPTR tradeoffs).

	+ modified calls on 'lalloc()' in file undo.c to use special codes for
	  l_used member directly.

	+ added options -Wconversion -Wstrict-prototypes -Wmissing-prototypes
	  to gcc flags in makefile; addressed these warnings (except for
	  'signal()' arguments, which cannot be fixed) on sunos.  Modified
	  files bind.c, file.c, filec.c, fileio.c, glob.c, insert.c, line.c,
	  path.c, random.c, region.c, spawn.c, tcap.c.

	+ corrected ifdef in 'string_has_wildcards()' (file glob.c) for VMS.

Changes for vile 3.47:
(tom)

    (part a)
	+ introduced 'l_ref()' and 'l_ptr()' functions, rippled-through changes
	  to support mapped data (files basic.c buffer.c csrch.c display.c
	  estruct.h eval.c exec.c fences.c file.c filec.c finderr.c globals.c
	  history.c insert.c line.c oneliner.c path.c proto.h random.c region.c
	  search.c spawn.c tags.c tmp.c undo.c window.c word.c)

	+ added logic to file tmp.c to allocate LINE structs from a pool of
	  pages (note that deallocation isn't done, nor is swapping to a
	  tmp-file as yet).

    (part b)
	+ added code to test return-value of 'glob()' in file eval.c

	+ corrected 'get_recorded_char()' (file input.c) to reset 'buffer'
	  variable after 'finish_kbm()' makes it obsolete.

	+ provided more useful defaults for TERMCAP, IBMPC and COLOR
	  definitions in file estruct.h

	+ corrected value of MK in 'FreeBuffer()' (file buffer.c), which caused
	  multiple frees of the same LINE struct.

	+ supplied initialization for wp->w_dot.l and wp->w_line.l in
	  'reframe()' (file display.c) to handle the case when vile is invoked
	  with no filename parameters.

Changes for vile 3.46:
(pgf)
	+ suppress attempts at reading a null file into the [vileinit]
	  buffer (main.c)

	+ don't require the d_namlen field in a DIRENT struct -- some systems
	  don't have it, and most of those that do null terminate the name
	  anyway.  (dirstuff.h, filec.c, glob.c, path.c)

	+ changed compile flags for uts, on user suggestion (makefile)

	+ in ffread(), after doing read(), do an fseek to sync up.  this
	  keeps some stdio implementations from not bothering to seek back
	  to the start in case we have to discard the read and resort to
	  slowreadf() due to long lines. (fileio.c)

	+ avoid realloc(ptr,0) when long lines are encountered in quickreadf()
	  (file.c)

	+ make M and L commands take account of too few lines in window (i.e.
	  do the right thing when end of file is on screen). (basic.c)

	+ even if the global dos-mode is on, empty (new) buffers should come
	  up as non-dos.  (file.c)

	+ fnc2engl() now tries to return a longer, meaningful name for a
	  function (i.e. "exit" rather than "Q"). (bind.c)

(tom)
	+ test-compiled VMALLOC, DEBUGM options on apollo.

	+ introduced 'set_lforw()' and 'set_lback()' macros to use in mapped
	  memory option.  Added stubs in new file 'tmp.c'.  Modified files
	  buffer.c exec.c file.c filec.c line.c undo.c, verified mechanically.

	+ added definition of LINEPTR and 'lsync()' to files estruct.h, proto.h

	+ fixed a memory leak in 'glob()', and changed interface to
	  'glob_free()' (files filec.c, glob.c, glob.h).

	+ revised logic in ibmpc.c that sets screen resolution ($sres) to
	  make it more table-driven.

	+ corrected 'forwline()' in file basic.c (repeated movement down
	  sometimes reset the cursor to column 1 unlike vi).

	+ added prototypes to 'mktbls.c'.

	+ modified file main.c so that if the standard input isn't a terminal
	  then vile reads it into a buffer and reopens /dev/tty (unix only).

	+ modified files main.c and epath.h to allow (for unix systems) vile
	  to find vile.hlp even if vile isn't in the path.

Changes for vile 3.45:
(pgf)
	+ got rid of LOOKTAGS mode, and all of its ifdefs (filec.c, main.c,
	  modetbl, proto.h, tags.c)

	+ got rid of NeWS ifdefs (basic.c, bind.c, buffer.c, edef.h,
	  estruct.h, exec.c, file.c, input.c, isearch.c, main.c, modes.c,
	  spawn.c, termio.c)

	+ resolved vile.hlp modes documentation and modetbl (vile.hlp)

	+ added missing mlreply call in goto-named-mark processing, to
	  allow "goto-named-mark a" to be used in a command file. (basic.c,
	  proto.h)

	+ added man page (don't get excited -- it's short), and turbo makefiles
	  vile.mak, mktbls.mak.  (makefile)

	+ fix to ins/inschar/istring to correct for bad backspace limiting
	  (insert.c)

	+ fixed off-by-one bug for column count under X. (x11.c)

	+ turned off typahead detection for X11.  updates were being held
	  off incorrectly. (termio.c)  related change, possibly unnecessary:
	  reordered initial mlforce() and initial update() in main, because
	  xvile was not starting up properly.

	+ no longer set _bspace bit in _chartypes[backspc], and isbackspace()
	  macro tests backspc directly.  will make rebinding of backspace
	  simpler. (estruct.h, termio.c)

	+ some changes to set-terminal stuff -- took out the keys that can
	  be rebound with bind-key, i.e. those that have effect only in
	  command mode.  added help.  (bind.c, vile.hlp)

	+ no longer strip the SPEC bit in ttgetc, so a meta key can be used
	  to generate "function keys"  (termio.c, vile.hlp)

	+ updated README

Changes for vile 3.45:
(tom)

	+ more fixes for long/int complaints from TurboC (files tags.c spawn.c
	  random.c main.c display.c bind.c).

	+ added logic to fileio.c so that (MSDOS only) overwriting a file
	  saves the old version renamed to ".bak" suffix.

	+ simplified argument processing in file main.c; reduced size a little.

	+ reorganized code that uses tungetc so that it isn't used as often.
	  This also makes 'tpeekc()' obsolete.  Moved extern-defs for 'tungotc'
	  to edef.h (files input.c, exec.c, globals.c, oneliner.c, termio.c).

	+ modified 'setvar()' in eval.c to show warning message if attempt is
	  made to modify a readonly variable, or if for some other
	  reason an environment variable cannot be set.

	+ modified 'ibmcres()' in ibmpc.c to allow user to reset using value of
	  CDSENSE as argument.

	+ corrected inequality-test in 'newscreensize()' (file display.c) that
	  prevented user from correctly setting $sres back to VGA in IBMPC
	  config.

	+ renamed entrypoints in file crypt.c to 'ue_setkey()' and 'ue_crypt()'
	  to avoid confusion with unix crypt(3) (files fileio.c, file.c
	  crypt.c, main.c, cmdtbl).

	+ corrected core dump when using encryption from command line by
	  splitting out 'ue_makekey()' from 'ue_setkey()'; used this from
	  'resetkey()' in file.c

	+ corrected handling of -k (crypt option); added a global 'cryptkey'
	  which is used to set the encryption key only in files listed as
	  command arguments (files edef.h, main.c, buffer.c).

	+ overwrite -k parameter value in main.c (for those systems where this
	  has an effect, it changes the value shown in a "ps" command).

	+ made 'quickreadf()' decrypt file.

	+ corrected 'resetkey()' so that it doesn't automatically use crypt key
	  for files that aren't the same as the buffer.

	+ The prompt added to 'resetkey()' also required moving some calls on
	  'ttclean()' (file.c).  Simplified some of the ttclean code using
	  CleanToPipe and CleanAfterPipe macros.

	+ corrected 'resetkey()' so that if no password is provided (at least
	  for pipes), the operation will proceed properly (i.e., read/write
	  without encryption).

	+ modified 'modeline()' in display.c to show if the current buffer is
	  encrypted.

	+ made NAMEC and TESTC define to variables name_cmpl and test_cmpl,
	  which can be modified at run-time (files estruct.h, edef.h).

	+ added commands "set-terminal" and "show-terminal" to set/show special
	  characters (including NAMEC/TESTC values!).  Put this into file
	  bind.c (reusing pieces of 'bindkey()').

	+ make '#' (special prefix-key) rebindable, like cntl_a-prefix.

	+ make display-routines in bind.c show the actual characters to which
	  CTLA and CTLX are bound (function 'kcod2str()').  Note that
	  'prc2kcod()' still assumes that CTLA and CTLX are bound to control
	  characters.

	+ changed argument type of TERM.t_cres to 'char *' to allow consistent
	  usage of variable 'sres[]' (files tcap.c, ibmpc.c, z_ibmpc.c).

	+ changed values recognized by ibmpc.c for "$sres" to be the names
	  that it returns (e.g., "VGA") and the number-of-lines (from main.c's
	  arguments).

	+ finished off 'npopen()' for MSDOS (allows write-pipes) and
	  implemented 'inout_popen()'; used in file spawn.c for filter-region
	  command.

Changes for vile 3.44: (pgf)
	+ fixed indentation if openup used in cmode, with a single word on
	  the current line -- indentation was coming from the _next_ line,
	  instead (insert.c).

	+ finderrbuf() now remembers its last argument (finderr.c)

Changes for vile 3.44:
(tom)
	+ corrected file descrip.mms; the vms_link.opt file no longer applies
	  to mktbls.exe; also fixed 'clobber' rule.

	+ corrected file glob.c (don't treat '$' as a wildcard on vms).

	+ correction: moved call on 'global_val_init()' before
	  'expand_wild_args()', to make wildcard globbing work on vms and
	  ms-dos (file main.c).

	+ corrected logic of 'kbd_reply()'; last_eolchar was not being set
	  properly when NAMEC wasn't space (file input.c).

	+ modified 'kbd_engl_stat()' in file bind.c so that if NAMEC is not
	  bound to space, then name-completion for :-commands is turned on.

	+ added option KBD_NULLOK to 'kbd_reply()' and used it in function
	  'kbd_engl_stat()' to re-allow commands to be empty (files bind.c,
	  input.c, estruct.h), needed after decoupling NAMEC and space.

	+ corrected 'slowreadf()' in file file.c so that dos-mode files are
	  read properly.  (The code stripped CR's even when dos-mode wasn't
	  set).

	+ implemented 'npopen()' and 'npclose()' for MSDOS; used this to make
	  MSDOS logic for ^X-!  the same as on UNIX (modified files fileio.c,
	  npopen.c, spawn.c).

	+ modified 'makename()' to yield essentially the same result for
	  MSDOS as for UNIX (in file.c), because 'npopen()' works similarly.

	+ added tests in 'ffropen()' and 'ffwopen()' to prevent accidentally
	  opening a directory-file.

	+ corrected handling of FIOFNF in 'readin()'; made this work on MSDOS
	  as well as UNIX (files file.c, fileio.c, display.c).  The value of
	  'errno' was not being saved to report in the error message.  Added
	  'mlerror()' to display.c to encapsulate the error reporting better.

	+ moved 'errno' declarations into 'estruct.h' (files display.c, file.c,
	  npopen.c, termio.c).

	+ added function 'set_febuff()' to encapsulate the 'febuff[]' and
	  'newfebuff' variables; moved these to finderr.c (files file.c,
	  finderr.c, spawn.c).

	+ corrected test in 'filename()' (file.c) for ":f" command.

	+ corrected test in filec.c for pre-existing file (don't prompt if it
	  is a pipe-command).

	+ corrected tests in filec.c for prompt for re-read (didn't look for
	  abort-status).

	+ test-compiled CRYPT, VMALLOC configuration flags on TurboC.  Modified
	  files crypt.c, estruct.h, vmalloc.c

	+ began addressing TurboC warnings for conversion between long/int.

	+ deleted obsolete defines in file estruct.h (CLRMSG, CTRLZ).

	+ added 'set_rdonly()' to encapsulate the places where an automatically
	  created buffer is made read-only.  This makes them more consistent.
	  Files: bind.c, exec.c, main.c, oneliner.c, random.c, spawn.c

	+ modified 'update()' in file display.c so that '.' commands don't
	  redisplay if VISMAC is configured (previously, only keyboard macro
	  redisplay was suppressed).

Changes for vile 3.43:
(pgf)
	+ changed NAMEC from SPACE to TAB (estruct.h).  changed eolchar arg
	  passed to kbd_reply in kbd_engl_stat from NAMEC to ' ', to
	  compensate.  added check against command term'ed with ' ' in
	  execute_named_cmd() (exec.c).

	+ added check for iswild() when scanning for wildcard chars in glob.c

	+ allow nulls as well as newlines to separate filenames in glob-pipe
	  output.

	+ added finderrbuf() routine (command is "error-buffer" or "find-next-
	  error-buffer-name"), to set the name of the buffer to scan for errors.
	  (finderr.c, proto.h, cmdtbl, vile.hlp)

	+ fixed pathname bug when scanning output that contains Entering/
	  Leaving pairs.  We no longer just keep a pointer to where we
	  found the directory name, but now malloc space for it.

	+ horizontal scrolling moves by half screens by default (window.c,
	  display.c)

	+ added AIX to machines that need sys/ioctl.h (termio.c, display.c)

	+ further fix to repeat counts and the '.' command, so that all cases
	  ( 6dw , 3d2w , etc.) work.

	+ support for letting a named register on a '.' command override
	  what was originally typed:  "adw"b.  will put one word in register
	  a and the nex in register b.  (input.c line.c exec.c)

(tom)
	+ corrected define in dirstuff.h to make TurboC compile again.

	+ corrected logic of 'makename()' in file.c for MS-DOS.

	+ added type CMASK to correct use of _chartypes[] array on MS-DOS
	  (e.g., in 'screen_string()' in input.c).

	+ deleted VMS-DCL file 'vile.com', since this causes conflict on
	  MS-DOS.

	+ lowercased color names in file modes.c

	+ modified ibmpc.c to get true white and yellow colors (had gray and
	  brown).

	+ modified files ibmpc.c and display.c to allow MS-DOS version to do
	  scrolling.

	+ removed unused assignments from file insert.c

	+ substituted all l_fp references to lforw macro, l_bp references to
	  lback macro, verified mechanically.

	+ make special case in 'dotcmdplay()' to allow (like vi) the repeat
	  count on '.' command to replace that on the replayed command.

	+ modified logic of 'writereg()' to allow its call on 'imply_alt()' to
	  correctly set the 'copy' parameter (only if a whole file is written).

	+ introduced new function 'same_fname()' to correct places where
	  matches between a filename and the buffer's filename broke (either
	  because it was not in canonical form, or because VMS version numbers
	  were not stripped).

	+ modified fileio.c to read/write binary files on MS-DOS to avoid
	  truncating files at ^Z.  This does not make ^M visible however.

	+ ifdefd out contents of 'dot_replays_macro()' in input.c to avoid
	  side-effects

	+ corrected logic of 'tungetc()' in file input.c; this had broken
	  replay of keyboard macro "iX/Y^MaZ".

	+ split out 'expand_wild_args()' from main.c into a new file glob.c,
	  which contains globbing code.  Moved 'glob()' from path.c to glob.c
	  also.

	+ moved function 'is_directory()' from filec.c to path.c; made it
	  public.

	+ added function 'no_memory()' to encapsulate the more common places
	  that vile/msdos runs out of memory; use this in several places to
	  simplify error reporting.

	+ added universal-mode "history", to allow turning that function off,
	  and instrumented history.c to automatically turn logging off if vile
	  runs out of memory.  (It is annoying to get out-of-memory errors on
	  _every_ command).

	+ modified display.c to fill in the long space before program & version
	  identifier for the scratch buffer (on the mode line).

	+ added option to 'mlreply_file()' to allow expansion of wildcard to
	  multiple files.  Use this in file.c (for ":e" and ":view" commands).

	+ modified files descrip.mms and vms_link.opt because (with new module
	  glob.c) the link-command line got too long.  Other mods to file
	  descrip.mms to make file vile.com generated (to avoid leaving it
	  around for ms-dos configuration), and the 'clean' and '.last' rules
	  (to make them less noisy).

	+ corrected 'ffronly()' in fileio.c; on VMS this caused some files to
	  be touched.

	+ implemented scrolling in file vmsvt.c

	+ implemented 'glob' mode to control how wildcards are expanded
	  (affects files main.c, modes.c, glob.c) and the corresponding piped
	  commands for glob-mode.

	+ added logic to 'makename()' to handle embedded blanks in filenames.

Changes for vile 3.42:
(pgf)
	+ added routine tb_stuff() (tbuff.c), which is roughly the
	  converse of tb_peek(), to allow simple replacement of a character
	  in a tbuff.

	+ used tb_stuff() to increment the buffer number when referencing
	  the numbered buffers -- i.e. "1p becomes "2p in a '.' command.
	  (input.c)

	+ backed out change to 'get_recorded_char()' (input.c) that caused
	  dd..."1P... to continue deleting lines after the P operation.

	+ added horizontal scrolling mode, to cause whole screen to shift
	  instead of just one line when cursor goes "off screen".  this
	  mode ("set hs", or "set horizscroll" is now the default. (display.c,
	  vile.hlp, main.c, modetbl, proto.h)

	+ allow cursor to rest in last column, if line is just that long, to
	  prevent extra horizontal scrolling. (display.c)

	+ split up the ins() function, to provide an inschar() function that
	  istring could use.  istring() now called by insstring() and
	  overwstring(), which are bound to "insert-string" and new
	  "overwrite-string" commands.  all this to allow "insert-string"
	  to take advantage of autoindent, cmode, wordwrap, etc.  will
	  need tweaks later when tty chars are rebindable (^U, ^W, etc.)

	+ compiled with "-Wmissing-prototypes", which turned up a bunch of 'em.
	  (proto.h)

	+ some linux gcc cleanup, mostly just including some more headers
	  (display.c file.c main.c)

	+ ifdefed out the onamedcmd() function, and it's binding (cmdtbl,
	  exec.c)

	+ took out the extern declarations of getpwnam and getpwuid that i
	  put in recently.  they seem to be causing more problems than they
	  were fixing.  in general, providing prototypes for system routines
	  is a real pain.  i wish there were an "ifnprototype" construct.

Changes for vile 3.41:
(tom)
	+ ifdef ioctl.h for APOLLO (note: you shouldn't use '"'-form for system
	  includes, since that could pick up files in the current directory,
	  and also because it does weird things to the include-path).

	+ moved code to support USE_LS_FOR_DIRS from filec.c to path.c, making
	  it look like unix-style directory routines.  Added ifdef for
	  OLD_STYLE_DIRS just in case...

	+ modified 'slowreadf()' in file.c so that piped input scrolls from the
	  bottom of the window, rather than the middle.

Changes for vile 3.40:
(pgf)

	+ the makefile no longer supplies any -I options.  this will cause some
	  machines to not find "ioctl.h" where it's in the sys subdirectory,
	  but I just spent a day tracking a bug caused by picking up the wrong
	  system headers (i needed the gcc "fixincludes", and they had moved).

	+ now honor LINES and COLUMNS in getscreensize (display.c)

	+ now handle searching multiple tags files specified in "set tags"

	+ bugfix to fences.c, which fixes indentation when inserting '}'

	+ added firstnonwhite() calls to godotplus, so we can publish it as
	  "whole-lines" (files basic.c, cmdtbl).

	+ added 'setjmp()' code to files main.c, input.c to handle ^C with
	  BSD-style signals.

	+ added define USE_LS_FOR_DIRS to files dirstuff.h and filec.c to
	  accommodate systems w/o a 'readdir()' function.

	+ corrected $pagewid (was returning length instead of width) in file
	  eval.c

	+ use lsprintf to form [Macro nn] names (file exec.c)

(tom)
	+ corrected 'ffwopen()' in fileio.c so that write of current buffer on
	  VMS works properly (forgot to strip version number).

	+ made 'flook()' work properly for vms (file bind.c)

	+ moved 'dname[]' table into file exec.c and 'cname[]' table into file
	  modes.c; did this to get rid of 'comma' macro, which does not work as
	  intended on Turbo-C (the comma got evaluated too soon).

	+ to prevent redefinition error in Turbo-C, removed redundant includes
	  for ,  and  (already in file estruct.h)
	  from the ".c" files: ansi.c at386.c basic.c bind.c buffer.c crypt.c
	  dg10.c display.c eval.c exec.c file.c globals.c hp110.c hp150.c
	  ibmpc.c input.c isearch.c line.c main.c modes.c npopen.c oneliner.c
	  regexp.c region.c search.c spawn.c st520.c tcap.c termio.c tipc.c
	  vmsvt.c vt52.c window.c word.c wordmov.c x11.c z309.c z_ibmpc.c

	+ moved macro 'P' from file proto.h to estruct.h, adjusted definitions
	  in file 'estruct.h' to allow use of 'P' macro in CMDFUNC definition.
	  Added definition of type 'CmdFunc' for the actual pointer-type.

	+ use P-macro for TERM struct definitions (and added TTscroll),
	  modified files estruct.h and display.c

	+ corrected logic of 'dot_replays_macro()' in file input.c (for the
	  special case of macro "@w" followed by "dd" command, I noticed that
	  '.' replayed both commands).

	+ compiled with Turbo-C, turned on warning if function was called w/o a
	  prototype.  Added prototypes (including those for static procedures)
	  to get rid of these and other compiler warnings.  Doing this found an
	  error in eval.c and one in history.c (files modified: bind.c buffer.c
	  display.c eval.c exec.c fences.c file.c fileio.c history.c ibmpc.c
	  input.c insert.c main.c mktbls.c modes.c npopen.c opers.c path.c
	  random.c regexp.c region.c spawn.c tbuff.c window.c).

	+ corrected MSDOS-specific pathname translation in files path.c and
	  random.c

	+ corrected d_namlen value supplied in readdir function for VMS (file
	  vms2unix.c)

	+ implemented first version of filename completion for VMS.  (Directory
	  names are not completed; there are still some ambiguities between
	  scratch buffer names and VMS directory paths).

	+ added option KBD_UPPERC to input.c; use this to force prompts for VMS
	  filenames to uppercase.

	+ removed redundant declarations for 'getenv()'; it is already in file
	  estruct.h

	+ added new file 'vmspipe.c' which provides a piped-read facility
	  'vms_rpipe()'.

	+ modified file finderr.c to recognize lint output on SUNOS; also
	  corrected it to ensure that sscanf doesn't scan past the string
	  limits (no EOS was formerly on each line).

	+ added/used new functions 'pathleaf()' and 'pathcat()' to file path.c
	  to hide vms/unix pathname differences.

Changes for vile 3.39 (from Tom Dickey):

	+ corrected error in 'get_recorded_char()' (file input.c) that caused
	  command "ix^[j.j.j.j." to not repeat properly.

	+ corrected prompt-string in 'ShellPrompt()' (file spawn.c)

	+ corrected behavior of filename completion (file filec.c) so that
	  internal names and shell names can have blanks in them.

	+ provided a last-replay value for 'execfile()' in file exec.c (it was
	  defaulting to the current buffer, which is wrong).

	+ corrected pointer test in 'tb_sappend()', which was null in the
	  special case of a ":w" command before any ":e" or other read.

	+ simplified MSDOS-drive translation (untested) in file random.c to
	  accommodate changes made for VMS in other files.

	+ modified 'cd()' procedure in file random.c to chdir to home directory
	  on systems that have one.

	The following are changes to support VMS:

	+ added new files (shown in makefile and descrip.mms): dirstuff.h,
	  vms2unix.c, vile.com

	+ use new file 'dirstuff.h' for definitions in filec.c and path.c

	+ corrected some dependencies in descrip.mms

	+ corrected logic in 'imply_alt()' (file buffer.c) that lost the
	  original filename argument (replaced it with the lengthen-path).

	+ corrected logic in 'getfile()2' (file file.c) to account for the
	  distinction between buffer-names and file-names.  Simplified
	  'getfile()' and 'getfile2()' because of modifications to
	  'shorten_path()' and 'lengthen_path()'.

	+ corrected logic of 'ffread()' (file fileio.c); on VMS a single read
	  does not necessarily read an entire file.

	+ corrected definition of macro 'isready_c()' for VMS.

	+ modified 'shorten_path()' (file path.c) to provide the "./" prefix
	  that was added in files buffer.c and display.c; also absorbed the
	  test for MSDOS device prefix (e.g., "c:") there.  This was needed to
	  allow VMS port to show native pathnames.  The equivalent of "./" on
	  VMS is "[]".

	+ use VMS function 'fgetname()' and 'getname()' to determine the
	  fully-resolved path in 3 cases: after writing a file, after reading a
	  file, and in 'lengthen_path()' (files file.c and path.c).  This makes
	  it know the current version number of each file.

	+ modified 'makename()' (file file.c) to account for VMS pathnames.
	  Note that DecShell names (which the C runtime library accepts as
	  arguments to fopen, etc.) look much like unix filenames.

	+ added new function 'is_internalname()' to file path.c; this serves
	  the same purpose as the (now obsolete) macro isScratchName.  This
	  makes a better check (to keep VMS paths distinct from scratch buffer
	  names) than the macro.

	+ deleted macro isScratchName from file estruct.h; changed macro
	  isInternalName to use function 'is_internalname()'.  Adjusted other
	  macros in estruct.h and display.c to make VMS port work properly.

	+ added new function 'non_filename()' to file path.c; use this in files
	  bind.c and random.c to encapsulate the program+version string.  Use
	  'non_filename()' in 'is_internalname()'.

	+ corrected logic of 'screen_string()' (file input.c) to handle the
	  distinction between "[" and "]" used to delimit pathnames on VMS, and
	  to indicate scratch-buffer names.

	+ corrected wildcard, path and scratch-buffer characters for VMS (file
	  main.c).

	+ corrected/modified file path.c so that the functions therein support
	  VMS filenames.  Added several new functions to do this.

	+ corrected code for 'catnap()' (file random.c) for VMS.

	+ corrected several 'exit()' arguments (file termio.c)

	+ corrected VMS's ttgetc function (its interaction with 'typahead()'
	  was wrong; also 'typahead()' was not really implemented (file
	  termio.c).

	+ ifdef'd out a redundant 'ttclean()' call (which caused the output on
	  VMS to be closed more than once, which is really an error).

	+ guard 'vtinit()' (file vmsvt.c) against t_mcol or t_mrow too small

Changes for vile 3.38:
(pgf)
	+ cleaned up internal naming and help for alt-tabpos mode.
	  alt-tabpos on implies emacs-style, and it's off by default

(tom)
	+ corrected status-check in 'ffclose()' (in fileio.c) that generated
	  spurious 'Error on close' message, visible when nothing was read from
	  a pipe.  (Also eliminated redundant defs for 'npopen.c' in fileio.c
	  and proto.h).

	+ corrected place in 'globals.c' where (if the buffer was readonly),
	  the '/' delimiter after an s-command was not eaten.

	+ modified loop-limit in "show-registers" command to display the
	  numbered registers.

	+ corrected file fences.c, allowing C preprocessor lines to have
	  leading whitespace before '#'.  The cursor may be on any character
	  from the first column through the '#'.

	+ rewrote procedure 'cpp_fence()' in file fences.c, allowing it to
	  recognize "elif" keyword.  Added 'nextchar()' to file basic.c to
	  support this.

	+ modified procedure 'ShellPrompt()' in file spawn.c to eliminate the
	  ": " before prompts for ^X-!.

	+ corrected 'kbd_reply()' in file input.c to invoke 'tgetc()' directly
	  when ^V is used to escape a character.

	+ corrected 'kbd_kill_response()' in file input.c; ^W is not supposed
	  to trim blanks before a word.

	+ corrected 'update()' in file display.c; the VISMAC define does not
	  apply to "." command.  This fix allows showmatch to work with "."
	  command.  Also, in 'fmatch()' in file fences.c; test return-value of
	  'update()' to avoid catnap when update fails.

	+ corrected 'insert()' and 'insertbol()' in file insert.c; the cursor
	  was not being advanced after repeated insertions like vi.

	+ corrected file input.c so that it can handle a "." command within a
	  keyboard macro.  The macro was "iA^[l2." (for testing).

	+ modified file input.c (new procedure 'dot_replays_macro()' so that
	  the "." command after defining or executing a keyboard macro causes
	  the macro to be (re)invoked.

	+ split 'kcod2prc()' in file bind.c into 2 parts; the new one (i.e.,
	  'kcod2str()') is used to support 'dot_replays_macro()'.  Also use new
	  function 'fnc2kcod()'.

	+ added new function 'kbm_started()' to file input.c to get rid of then
	  non-recursive variable 'kbdplayreg'.

	+ save/restore "." repeat counts in 'start_kbm()' and 'finish_kbm()' so
	  that repeat works properly for keyboard macros.

Changes for vile 3.37:
(pgf)
	+ works on osf/1 alpha now, with hacks applied to termio.c and
	  display.c
(tom)
	+ added files 'descrip.mms' and 'vms_link.opt'; compiled on VAX/VMS
	  (but did not make it run) (tom dickey)

	+ pathname tracking fixes (calling shorten_path() correctly everywhere)

Changes for vile 3.36 (from Tom Dickey):

	+ supplied initial value for dirc-mode

	+ guarded 'mlreply_file()' against missing curbp->b_fname (for use in
	  .vilerc startup).

	+ corrected logic in 'kbd_reply()' (file input.c) that caused backspace
	  to be treated as a command-delimiter.

	+ corrected logic in 'kbd_reply()' (file input.c) that caused '/'
	  character in complex substitutions to be eaten, e.g.,
		:g/pattern/s//newpattern/g
	  broke after the 's'.

	+ corrected calls (broke in 3.35) on 'mlreply_file()' from 'insfile()'
	  and 'operwrite()' (mods to files estruct.h, filec.c, file.c and
	  opers.c).  The ^R and ^W commands always prompt for name, rather than
	  taking it from the screen.

	+ corrected end-of-line logic in 'do_a_mode()' (file modes.c).  This
	  had allowed history scrolling to display keywords that were separated
	  by blanks; fixed this by testing for both space and "=" characters.

	+ added calls to 'hst_glue()' in 'unqname()' and 'getfile2()' to add
	  blank in command history before the responses these functions solicit
	  from 'mlreply()'

	+ added macro 'char2int()' to file estruct.h, use this in fileio.c and
	  tbuff.c to hide byte-masking.

	+ changed data in TBUFF to 'char' (unsigned char does not buy that much
	  conciseness); absorbed macros 'tb_values()' and 'tb_length()' into
	  file tbuff.c as functions.

	+ corrected logic of 'tb_leaks()' (file tbuff.c); I had only exercised
	  this at the end of execution.

	+ removed unused define for TMPSTOP

	+ recoded handling of keyboard macros in file input.c to use TBUFF
	  structs (so there is no limit on length of keyboard macros).

	+ modified 'execkreg()' to remove length-limit on macros there as well
	  (file line.c)

	+ modified 'execkreg()' to allow invoking registers 0-9 (file line.c)

	+ modified files input.c and line.c so that "." and @-commands can be
	  invoked from within a keyboard-macro (i.e., ^X-&).

	+ modified files insert.c and input.c so that repeated "." command
	  works properly for i,I,R commands (the cursor must appear at the end
	  of the insertion).

	+ modified so that ^Z (job suspension) works properly on apollo sr10.3
	  (files termio.c and spawn.c).

	+ modified 'ttgetc()' in file termio.c so that (for apollo) it reads in
	  raw-mode.

	+ added flag to 'tgetc()', allowing it to suppress the conversion of
	  intrc to abortc (files basic.c csrch.c eval.c exec.c input.c
	  insert.c).  This change also lets users quote ESC characters.

	+ corrected unused args in 'globber()' (file globals.c)

	+ corrected special case in use of 'canonpath()' on apollo (user could
	  type in path beginning with "/", which was not getting "//" portion
	  of pathname prepended.

	+ renamed "vitabpos" mode to "alt-tabpos" mode, avoiding conflict with
	  "view" mode.

	+ added "implybuffer" (ib) mode to use in splitting out vi-style
	  buffer-implication from 'autobuffer' mode (files modetbl and main.c).

	+ added "samebangs" (sb) mode to allow the ^X-!!  and :!!  commands to
	  be optionally the same.

	+ Corrected logic of 'imply_alt()' so that it works with files read, as
	  well as written (files buffer.c and file.c).

	+ split out the pathname functions into file path.c

	+ added function 'is_appendname()' to path.c to better encapsulate the
	  isAppendToName macro's knowledge of the ">>" length (files path.c,
	  filec.c, fileio.c, random.c).  Used this to make functions
	  'canonpath()', 'lengthen_path()', 'shorten_path()' and
	  'is_pathname()' work properly with ">>" prefix.

	+ added code to 'path.c' to resolve "~" as user's home-directory.

	+ corrected code in 'makebufflist()' that caused b_bfname member to
	  be modified (file buffer.c).

	+ moved MSDOS drive-logic from 'ch_fname()' into 'lengthen_path()'
	  (files random.c and path.c)

	+ added procedure 'copy_val()' to modes.c to encapsulate the make-local
	  and make-global macros.  This fixes a case in which memory could be
	  freed more than once: if the user had done 'setl' commands for two
	  different buffers.

	+ made variables 'doslines' and 'unixlines' local to the procedures
	  'slowreadf()' 'readin()' in file.c; initialized these so that
	  successive reads of a set of files will treat the dos/unix line
	  counts separately.

	+ added command "set-dos-mode" to force the current buffer to be
	  in DOS-mode (trimming CR's).

Changes for vile 3.35 (from Tom Dickey):

	+ addressed compiler warnings from gcc 1.36 on apollo sr10.3.  (I know
	  it is old, but it gives useful warnings).  This required some minor
	  adjustments to defines/includes in files estruct.h, proto.h, main.c,
	  fileio.c, npopen.c, random.c to accommodate order-of-definition
	  problems in stdio.h and signal.h

	+ tested with gcc 1.40 on sunos 4.1.1

	+ tested compiling with SMALLER=1; fixes to files eval.c, input.c,
	  mktbls.c, npopen.c, proto.h, random.c (On my machine, this only cuts
	  about 10% from the binary).

	+ added EOS at mismatch-point in 'fill_partial()' in file bind.c, fixes
	  bug that caused incorrect display after repeated name completion and
	  query operations.

	+ guarded 'kbd_complete()' against embedded nulls in its buf-argument,
	  by testing for nulls before completion logic in file input.c

	+ added a flag 'kbd_expand' to make calls on 'kbd_putc()' via
	  'mlforce()' and related functions show tabs as a space.  This
	  modifies files bind.c, edef.h, display.c to fix a problem I
	  introduced in 3.32

	+ use 'kbd_expand' flag in file input.c to fix non-displaying ^M; other
	  fixes include quoting and backslash fixes, as well as correction to
	  wkillc handling.

	+ modified finderr.c to make the embedded tabs as "\t" digraphs, so
	  they are visible.  Added pattern to use with apollo C compiler.

	+ corrected logic in 'updpos()' (file display.c) so that vile displays
	  cursor location just-like-vi for tabs and control characters.

	+ made 'wordcount()' code (file word.c) work properly.

	+ corrected 'join()' (file word.c) so that blanks are not inserted when
	  joining after a space, or joining a blank line.  Also (like 'vi'), if
	  there is trailing whitespace on the first line, don't modify it.

	+ corrected flags for join-lines in file cmdtbl so that the region-
	  oriented code can work.

	+ made join-lines work with regions (files opers.c, word.c).

	+ restored GLOBOK flag for join-lines-til (regions work now).

	+ interchanged order of calls on 'toss_to_undo()' and 'lremove()' in
	  'ldelnewline()', since this was causing incorrect cursor placement
	  after an undo.  (The particular case arose in the rewritten
	  join-lines, when joining a blank line to a non-blank line).

	+ modified 'edithistory()' in file history.c to ifdef out the ESC code
	  (with new symbol KSH_HISTORY), merge the loops to use 'escaped' flag
	  to avoid redundant logic, and pick up control chars (e.g., ^N and ^P)
	  for scrolling.  This also modified files input.c and exec.c

	+ corrected logic in history.c (from 3.34) that uses the function
	  'WillExtend()' to modify/macroize !-commands.  The code did not
	  provide for the case in which the user would modify the text after
	  scrolling to it.

	+ corrected call on 'hst_flush()' in file pipecmd.c (it was not called
	  if the pipe-command failed).

	+ revised 'tgetc()' in file input.c to make it use a single return
	  point (simplifies testing and debugging).

	+ corrected file modes.c so that user can abort from a set command.

	+ deleted code for unused global 'lineinput' (files bind.c, input.c,
	  edef.h).

	+ renamed ifdef for LAZINESS to (global mode) TAGSLOOK, added an entry
	  to modetbl for "looktags" to test/update this code.  Note that this
	  is turned off by commenting out the "LookTags" line in modetbl.  This
	  affects also files main.c, file.c modes.c and tags.c

	+ added file 'filec.c' to perform filename completion.  Moved code that
	  was ifdef'd LAZINESS there, and recoded so that it stores paths
	  normally (not reversed!).

	+ created function 'mlreply_file()' in filec.c, used this to
	  consolidate prompting for filenames in file.c (Note that now all
	  filename prompts can get data from the screen).

	+ made most of the calls on 'mlreply_file()' default to the current
	  filename; this is simpler than the last name given to the command.

	+ moved check for writing view-only buffer from 'filewrite()' as new
	  local function 'writable()', before calls on 'writereg()' This
	  affects 'filewrite()', 'filesave()', 'imdying()' and 'writeregion()'
	  implicitly.

	+ use 'mlreply_file()' in 'execfile()' (file exec.c)

	+ use 'mlreply_file()' in 'operwrite()' (file opers.c)

	+ added 'no_such_file()' to file.c; use this in 'execfile()' so that
	  ":source" will report an error if the file is not found.

	+ created function 'mkreply_dir()' modeled after 'mlreply_file()' in
	  filec.c, used this to allow pathname completion in 'cd()' in random.c

	+ added mode "dirc" to file modetbl, to support directory name
	  completion.

	+ added l_number to LINE struct, b_bytecount to BUFFER struct (file
	  estruct.h) to use in caches for # of bytes and lines displays.

	+ added macro 'for_each_line' to file estruct.h

	+ added procedure 'bsizes()' to buffer.c to compute values for l_number
	  and b_numchars, b_numlines values.  Will later get this to cache
	  results to speed up 'line_no()' and related code.

	+ corrected column-splitting in file modes.c (error in 3.34 changes)
	  which caused dos-mode to not be shown.

	+ corrected flag in 'modetbl' for dos-mode: this makes dos-mode show in
	  the status-line.

	+ added new entrypoints to tbuff.c: tb_copy, tb_scopy, tb_bappend

	+ merged code in 'spawn1()' and 'pipecmd()' (file spawn.c) so that
	  !-commands and !!-commands work consistently.

Changes for vile 3.34 (from Tom Dickey):

	+ modified mktbls.c to use 3rd column of modetbl (window-flags).  Moved
	  window-flag defines in estruct.h to allow their use in nemode.h

	+ in modes.c, moved the code that updates window hints-flags from the
	  'adjustmode()' to 'adjvalueset()' procedure so that it can use the
	  new window-flags entry in nemode.h

	+ modified mktbls.c (and estruct.h, edef.h) to support global modes.

	+ added to modes.c: 'new_regexval()', 'free_regexval()', and
	  'free_val()'.  Use these in main.c and modes.c to simplify
	  leak-testing.

	+ added to estruct.h defines to use in testing memory leaks using both
	  dbmalloc as well as apollo-specific traces.

	+ added to main.c ifdef for NO_LEAKS; used this in testing for
	  permanent memory leaks (freeing data also finds specific types of
	  allocator corruption).  Added test-code for this purpose to:
	  buffer.c, display.c, line.c, regexp.c, tbuff.c, window.c

	+ plugged memory-leak in 'getfile()' in file.c by splitting it after
	  the temporary-buffer allocation, making tbp a static value, and
	  deleting the line that set the tbp.b_fname pointer to null.

	+ revised the value-checking in 'adjvalset()' (file modes.c) so that
	  unnecessary changes are ignored.

	+ further modified file modes.c so that typing ' ' (except after string
	  or pattern values) will continue the prompting for further set-modes,
	  as in noninteractive use.

	+ put the TTputc for '\r' back into 'kbd_putc()'; omitted this when
	  taking code for 'mlmsg()' from display.c

	+ added new function 'GetEnv()' to eval.c to guard against
	  null-return from 'getenv()'.

	+ added new command (to file line.c) "show-registers" to show the
	  contents of kill-buffers and registers.

	+ added new module 'history.c'.  This implements up/down scrolling in
	  an invisible buffer "[History]", which logs all :-commands.

	+ coded-around apollo sr10.3 optimizer-bug in 'execkreg()':
		kbdend = &kp->d_chunk[i];
	  resulted in kbdend == kp->d_chunk.

	+ moved autobuffer and c-suffixes modes to global-table.  Deleted 'cwd'
	  mode.

	+ modified mktbls.c so that each table will be sorted by name (not by
	  type&name).  Modified modes.c to take advantage of this and display
	  the modes sorted in columns (more like 'vi'), except for long strings
	  (which are deferred to the bottom of the display, still).

	+ make modes.c show the actual color name in addition to the index.

	+ rewrote 'kbd_string()' to interface it with 'edithistory()'.  Split
	  out entrypoint 'kbd_reply()' to support integration of history with
	  'namedcmd()'.

	+ redefined 'kcod2key()' in terms of N_chars; added macro 'isspecial()'
	  to estruct.h

	+ revised 'kbd_engl_stat()' and 'namedcmd()' to use the 'kbd_reply()'
	  entrypoint so that user can scroll through history of any portion of
	  commands.

	+ modified 'search.c' to log history for '/' and '?' commands.

	+ modified x11.c to use memcpy rather than bcopy (for consistency).

	+ made x11.c compile properly on apollo sr10.3 (there is a conflict
	  between prototypes in  and ).

Changes for vile 3.33:

    	* many: cleanup for gcc-2.3's -Wall warnings

    	* bind.c: added new function, insertion_cmd(), which returns char
	that gives us simple insert mode.  used in x11.c and input.c, for
	pasting and for insert-mode arrow keys

    	* estruct.h: don't redefine "const" on linux

    	* makefile: added aix warnings, changed name of ENV to ENVIR, due
	to name conflict with linux make

    	* random.c: add include of sys/select.h for AIX

    	* x11.c: added code to support arrow keys and function keys from
	Phil Rubini

Changes for vile 3.32 (from Tom Dickey):

	* modified estruct.h, proto.h and display.c to compile vile on HP/Apollo
	  SR10.2 (CC 6.7).  Added new definitions ANSI_PROTOS and ANSI_VARARGS
	  to simplify this.

	* modified 'mktbls.c' to produce nemode.h; use these definitions
	  to replace buffer/window mode definitions in estruct.h and edef.h
	  (note that this obsoletes symbol MAX_STRING_W_VALUE, reordered
	  window int-modes).  Further modified 'mktbls.c' to only create
	  ".h" files for the cases where it has data (so that I can split
	  modetbl off from cmdtbl, avoiding unnecessary recompiles).

	* supplied an ifdef (at least for APOLLO!) in termio.c so that ^C
	  and ^U work properly.

	* added buffer-mode 'wrapmargin' to file insert.c (which overrides
	  wrapwords iff it is set to nonzero).

	* added new module 'tbuff.c' to manage dynamic buffers in places
	  where local static buffers exist now.

	* modified 'ins()' in insert.c so that it reallocates 'insbuff[]',
	  allowing arbitrarily-large re-inserts.

	* modified 'input.c' to dynamically allocate 'tmpcmd' and 'dotcmd'
	  buffers.  This allows arbitrarily-large commands to be repeated
	  with '.'.

	* guard 'lengthen_path()' in file.c against shell/pipe/internal names.

	* added variable "$shell" (files cmdtbl and eval.c) to override
	  environment-variable "SHELL" in pipe-commands.

	* made 'show-vars' (file eval.c) show leading '$' or '%' to be
	  consistent with the way the user must type them.

	* suppress 'show-vars' (file eval.c) ERROR values (these correspond to
	  unimplemented variables)

	* corrected error in nextbuffer/swbuffer (file buffer.c) that allowed
	  vile to crash if "set noautobuffer" was specified in .vilerc

	* corrected display in 'show-vars' (file eval.c) of "$kill" (reference
	  to volatile data).

	* made new function 'kbd_complete()' (file bind.c) to allow keyboard
	  completion in tables other than NTAB.

	* modified logic in new function 'kbd_complete()' to show permissible
	  completions in response to '?'.

	* consolidated logic in exec.c, display.c, bind.c, input.c with new
	  procedures 'kbd_putc()', 'kbd_puts()', 'kbd_erase()', 'kbd_alarm()'
	  These hide random use of 'ttcol'.

	* make 'kbd_engl_stat()' (file bind.c) recognize word-delete character.

	* eliminated redundant unget/get (files bind.c, exec.c) in the interface
	  of 'kbd_engl_stat()'; this caused an infinite loop in the call from
	  'namedcmd()'.

	* modified bug-test in 'updpos()' (file display.c); I had a process hang
	  in that loop for some reason.

	* collapsed expand/dobackslashes args of 'kbd_string' (file input.c)
	  into one mask.

	* modified 'mktbls.c' further to produce table 'all_modes[]', to use
	  this for name-completion of mode.

	* modified 'mktbls.c' to recognize color-types so I could get rid of
	  upper/lower case kludge in modes.c

	* modified 'modes.c' to use color-types.  The interactive behavior now
	  uses 'kbd_string()' to split the input at the '=' mark (if given).

	* added option-flag KBD_LOWERC to 'kbd_string()' (file input.c) so that
	  things that are forced to lowercase will be shown in that way on
	  input.

	* modified 'token()' (file exec.c) to handle the 'eolchar' for
	  non-interactive calls on 'kbd_string()'.

	- modified 'eval.c' to recognize '=' as a separator between
	  variable-name and value, as in 'modes.c'.

	- modified 'eval.c' to perform name-completion for environment
	  variables (i.e., those beginning with '$').

	- modified 'modes.c' to accept vi-style multiple assignments in a ":set"
	  command (this works non-interactively).

	- corrected 'imply_alt()' in buffer.c; ensure that the fname-argument is
	  non-null.  If called via 'filterregion()', it will be null.

Changes in 3.31:  (Tom Dickey)

	* corrected test in 'find_alt()', which caused the %/# toggle to work
	  incorrectly in noautobuffer mode.

	* updatelistbuffers after 'cd' command

	* added 'chg_buff()' & 'unchg_buff()' to encapsulate logic to update
	  buffer-list after buffers are modified.  The function 'lchange()'
	  is replaced by 'chg_buff()'.

	* modified 'histbuffer' to toggle according to 'find_alt()'

	* make the filename/buffer/number change for 'killbuffer' apply to
	  'usebuffer()'

	* corrected handling of repeat-count in 'C' command.

	* updated vile.hlp

	* revised 'mktbls.c':

		* filter out redundant ifdef's
		* tab-align data items for readability
		* modify 'nefunc.h' to use prototypes rather than K&R style
		  definition, also split the extern-definitions from the
		  data items for readability.
		* make procedures static, linted
		* modified so that 'evar.h' definitions are automatically
		  generated, so that "show-variables" can show a sorted
		  list of variables.  The new filename is "nevars.h".

	* corrected window refresh flag for 'U' (lineundo) command.

	* added an apollo-specific code in 'imdying()' to generate a walkback
	  for debugging.

	* corrected an error in 'zotwp()': reference to data that had been
	  deleted.

	* corrected an error in 'onlywind()': it did not delink window-pointer
	  after freeing it.

	* noticed that references to 'dfoutfn' weren't reentrant:  I did a
	  ":show-var" from the buffer-list and got only part of the heading.
	  Reorganized display.c to ensure that it is reentrant by using a
	  local copy of 'dfoutfn'.  Note that I didn't add 'dfoutfn' as an
	  argument to 'dofmt()' to avoid complications with varargs.

	* corrected 'dfputli()': it didn't do hexadecimal.

	* corrected 'updateline()': it sometimes failed to highlight the ends
	  of the mode-line.

	* corrected (my last change) to 'vtset()' so that "^J" is shown in
	  list-mode.

	* moved 'writeall()' from main.c to buffer.c; it belonged there, and
	  I used local macros for simplifying it.

	* remove SIGHUP handler before normal call on 'exit()' to avoid
	  vile-died messages when running it in an xterm.

	* corrected VMS definition of exit codes; added def of BAD-macro.
	  modified main.c, display.c, window.c accordingly.

Changes in 3.30, mostly from Tom Dickey:

This is lots of changes, mostly in buffer.c:

	* lint-clean: buffer.c

	* linted also: file.c, modes.c (though I left size_t alone for now).

	* added "list-vars" & "show-vars" to show the current variables

	* modified 'killbuffer' so I could add binding ^X-k to point to
	  a buffer-name in the buffer-list and kill it.

	* also modified 'killbuffer' to recognize filename if buffer-name is
	  not found, also buffer-number.

	* modify buffer.c so that the number shown by '_' and '*' is consistent

	* fixed ^X-o and ^X-O so they update buffer-list, as well as some
	  other places I missed before.

	* make some functions static (where they are really private), because
	  my per-module lint library got too large.  (I believe there are
	  too many externals).  In modes.c, this involved reordering, since
	  my practice is not to have forward-refs on static functions, to
	  make this work with some awful compilers.  This meant that I
	  deleted lines from 'proto.h'.

	* introduced new macro 'isreturn()', used this in correction in
	  'histbuff()'.  I used it in one bug fix & also where I could find
	  explicit compare for \r, \n.

	* added mode 'autobuffer':

		* the default is 'autobuffer' (the vile lru buffering)
		* curbp no longer is necessarily equal to bheadp
		* added members b_created, b_last_used, b_relink to support
		  the autobuffer/noautobuffer mode.
		* if "noautobuffer" is set, ":rewind" and ":n" apply only
		  to the original command-line files.

	* added macros SCRTCH_LEFT, SCRTCH_RIGHT, ScratchName, IsInternalName
	  to encapsulate use of '[' in names.

	* added macros SHPIPE_LEFT, isShellOrPipe to encapsulate use of '!' in
	  names.

	* added function is_pathname to encapsulate tests for pathnames
	  beginning with '.'.  This fixes the display of ".vilerc" from the current
	  directory as "./.vilerc".

	* added new char-types _scrtch and _shpipe to support killbuffer from
	  screen.  Use these types in new macro 'screen_to_bname()' which uses
	  modification of 'screen_string()'.  Used 'screen_to_bname()' to
	  make ^X-e and ^X-k "correctly" parse the bname, fname columns from
	  buffer-list.

	* fixed the error you mentioned in modeline (the position of col-80 mark
	  taking into account sideways and number modes).

	* supplied a missing TTflush in input.c

	* modified 'makebufflist()' to show only the flags actually used in the
	  footnote.

	* modified 'makebufflist()' to show '%' and '#' by the corresponding
	  buffer/filename.

	* added macros 'for_each_buffer()' and 'for_each_window()' to simplify
	  code as well as to keep visible references to bheadp & wheadp
	  confined to buffer.c and window.c respectively.

	* added/used macro SIZEOF

-------------------------------------------------------------------------------

Changes in 3.29:
-----------------

(fixes supplied by tom dickey, eric krohn, and willem kasdorp)

buffer.c: changes for keeping the buffer list more up to date when
	on screen
fences.c: allow match of fence that is first char. in buffer
file.c: avoid inf. loop when choosing unique name for buffers that have names
	containing "x" in the NBUFN-1 position and allow ":e!" with no file
	to default to current file
globals.c: implemented 'v' command
isearch.c, line.c, display.c: ifdef of some unused code
main.c: added .C, .i to cmode suffixes, for C++ and cpp output files
makefile, install target: test for presence of vile in destdir before
	trying to move it to ovile
oneliner.c: don't allow pregion to be used if the plines buffer is current,
	and set the WINDOW list mode, not the BUFFER list mode, so :l works
	again, and fix for s/.//g bug
regexp.c: fixes for interaction of BOL and \s etc.
spawn.c: lint cleanup  mostly casting strcXX() to void.
tcap.c: hack to supply CS or SR for scrolling region control, missing
	from some xterms
termio.c: added missing fflush in two of the ttclean() routines
word.c: fix for counts on 'J' command

------------------------------------------

The rest of the changes lister here are grouped only roughly, and represent
the delta of version 3.28 from vile version three.  -pgf Dec 30 1992

------------------------------------------------------

VI COMPLIANCE:
===============

- made ^N, ^P, and ^T do exactly what they do in vi.  (next line,
	previous-line, and tag-pop) Use ^X-o to switch windows, and ^X-2 to
	split them.

- ANSI style arrow keys now work from either command or insert mode.  Any
	ANSI function key of the form ESC [ c can be used as a command
	key -- the binding is FN-c

- the '#' key may now be used to force the following character to be treated
	as a function key.  Thus #1 is now equivalent to FN-1.

- some modes/values have changed names: aindent is now autoindent, swrap is
	now wrapscan, exact is now noignorecase, and they all have the vi
	shorthands (e.g.  tabstop is the same as ts, ic is the same as
	ignorecase).

- the "paragraphs" and "sections" values are now implemented, but as
	regular expressions -- they look pretty ugly, but I think they
	do what vi does.

- the sentence motions ')' and '(' now work.  they may not do exactly what
	vi does, but they're close.  they're controlled by regular
	expressions that find the ends of sentences -- then they move
	forward to the start of the next one.  The regular expressions are
	set in the new "sentences" value setting.

- "showmatch" mode now works, and momentarily shows the previous matching '('
	or '{'.

- "magic" mode, or rather "nomagic" mode, now works more like vi:  special
	characters are still available by escaping them in nomagic mode.

- there is a new mode, settable as "set terse" and "set noterse", which will
	suppress some of the extra messages that vile prints, reducing
	traffic for slow terminals.

- the '%' command now scans forward for a fence character if you're not on
	one to begin with (thanks to Dave Lemke).  I also added '^X-%', which
	scans backward instead.

- the ":&" command now works, and repeats the last ":s" or '^X-s'
	substitution.  it re-uses trailing p and l options, which vi does
	not.

- the '&' now works, and repeats the last ":s" or '^X-s' substitution.

- replacement sub-expressions work (\( and \), \1, etc.), as do \U \L \u \l

- there is a new operator, '^A-&', which is similar to '&' but acts on a
	region.  I expect that if you want it, you'll probably rebind it to
	something else (like '&') since typing it is awkward, to say the least.

- ^W and ^U are now both read from the tty settings, and they work in both
	insert mode and on the : line.  There is a "backspacelimit" setting
	that controls whether these (and regular backspacing (^H or DEL)
	will backspace past the insert point in insert mode.

- The '@' command can now be used to execute the contents of a named register,
	as if it were entered at the keyboard.  Thus @k executes register k.

- The "keyboard macro" obtained with ^X-( and ^X-) can be saved into a named
	register with the ^X-^ command.  This lets you record a keyboard
	macro and save it for use with the new '@' command.

- And, along to further complement the '@' command, it is possible to pre-load
	the named registers with the "load-register" command.  In a .vilerc
	you can say:
		use-register a load-register ihello^[
	(where ^[ is really an ESC entered with ^V-ESC), and then from
	within vile you can execute '@a', and the word "hello" will be
	inserted.

- the H, M, and L commands are now absolute motions

- insert mode now takes a repeat count, so '80i=ESC' inserts 80 '=' chars

- two new functions, to make normal motions more vi compliant --
	forward-character-to-eol and backward-character-to-bol, which won't
	move past the boundaries of the current line.

- you can no longer backspace from the beginning of a line to the end of
	the previous.  (rebind 'h' and '^h' from "backward-character-to-bol"
	to "backward-character"

- a motion caused by an undo is considered absolute, and the "last dot"
	mark is reset.

- added 'vi +/searchstring file.c' invocation syntax

- you can now specify a count to the ~ command.

- backslashes now have a protective effect on the : line -- they guard
	against expansion of #, %, :, and \.

- a lone ":f" without filename now gives same info as ^G

- 'x', 's', 'r' will no longer delete a line if used on an empty line.

- after a ":e!" command, the buffer name changes to match the filename, as
	if this were a new file read.  It used to just suck a new file into
	an old buffer, and the names didn't match.

- there is now a "taglength" setting, and the name of the tags file is in
	the "tags" setting.

- the "cd" and "pwd" commands now work

- shiftwidth has been implemented, so ^T, ^D, '<', and '>' all do pretty
	much what they do in vi

- there is a separate c-shiftwidth, used when in cmode, much as c-tabstop
	replaces tabstop when in cmode.

- ": args" is now similar in spirit to the vi command of that name


MISCELLANEOUS
===============

- reading files in general is _much_ faster, unless the file contains lines
	longer than 255 characters, in which case things slow down again.

- regular expressions are more powerful and much, much faster than they
	were.  vile now uses Henry Spencer's regexp code.  This has the
	side effect of making '\|' a new metacharacter, for alternation
	of expressions.  '\+' and '\?' are also new, and stand for "one
	or more" and "zero or one" occurrences.  they can be used from
	the I-search commands as well.

- in addition, \< and \> find beginnings and ends of words, and \w, \s,
	and \d find "word" characters, "space" characters, and digits.
	\W, \S, and \D find the converse

- related to the above change, replacement metacharacters now work, so you
	can use '&' and '\1' through '\9' in the replacement string, and
	you'll get the right thing.

- Dave Lemke contributed code to support vile under X windows -- including
	support for cutting/pasting, etc.  Thanks Dave!

- the '%' command will now find matching #if/#else/#endif sets.

- the '%' command will now find matching C comment sets.  Yes, it does
	the (non-)nesting correctly.

- tabstops can now be set to any value, and there is a separate value for
	tabstops in C mode.  (c-tabstop)

- there is now some support for horizontal scrolling, using ^X-^R and ^X-^L

- the ! filter command for running text through an external filter now
	works

- quite a bit of code cleanup, at least I think so -- it has ported pretty
	easily to a R6000, linux, 386bsd, Sony NeWS, NeXT, and the UNIXPC.
	it's close to lint-free, and Saber has very few problems with the
	code.  it'll now use prototypes if __STDC__ is defined, and it
	passes gcc -Wall -Wshadow with no warnings, if you ignore implicit
	declarations of system calls and lib routines.  the code should now
	be more portable, to various compilers and systems.  there are new
	targets in the makefile to make building on various platforms
	easier.  the makefile even supports microsoft C.

- the code now builds and runs under DOS, using (at least) Microsoft C 6.0.
	Peter Ruczynski has done a great job porting vile to DOS -- he
	calls that version "pcvile".  He has used the Zortech compiler in
	the past -- I didn't try to break that, but you never know.
	NOTE THAT THE DOS CODE IS KNOWN TO BE MUCH BUGGIER THAN THE UNIX CODE!

- quite a few bug fixes, including all (I think) of those reported by users

- the "last dot" mark, accessed with the names ' and ` doesn't get reset
	needlessly as often -- that is, if an absolute motion results in no
	move (e.g.  a failed search or tags operation, or an undo) then the
	"last dot" mark is unchanged.

- the "source" ("execfile") command now does globbing on the file being run
	-- be sure to put it in quotes, as in :source "$HOME/.vilestuff"

- entab, detab, and line-trim are now all operators (^A-tab, ^A-space, and
	^A-t)

- "make install" installs to /usr/local/bin or $HOME/bin, whichever is
	writable

- the english names of functions, particularly new ones, have been
	"rationalized", hopefully making it easier to remember their names.

- if you invoke a substitute command with ^X-s, it will always act globally
	across lines.  (i.e.  it behaves like "s/s1/s2/g", not like
	"s/s1/s2/")

- a QUIT signal will no longer cause core dump unless built with DEBUG on

- the display optimizes scrolling if possible when the window scroll
	commands ^E and ^Y are used.

- values/modes have been reworked.  Some are now attached to buffers, some
	to windows.  By default, all values use the global settings of
	those values, and will track changes to the global settings.  If a
	local setting is specified, it breaks the link between the local
	and global value, and the local value will no longer track the
	global value.  ":set all" is now more informative.

- the "set list" value is now attached to a window, not a buffer, so a
	single buffer can be displayed in two windows, "list"ed in one but
	not the other.

- reading from other processes into a buffer is now _much_ faster

- it is no longer legal to write out the contents of a buffer that has view
	mode set.

- the format region command (^A-f) now restarts with each fresh paragraph,
	so you can format an entire file at once, without collapsing it all
	into a single paragraph.  It also knows a little bit about C and
	shell comments, so you can now reformat blocks of commentary text.
	(There can't be any non-commentary stuff in front of the comments.)

- the position of the cursor within a window (the framing) is now preserved
	while the window if "off-screen" -- it no longer reframes when made
	visible again.

- there is now a mode indicator on the modeline: I for insert, O for
	overwrite, and R for replace-char.

- a line starting with '#' won't shift-right if the buffer is in C mode.

- :s/s1/s2/5 now works, to change the 5th occurrence on a line

- there are new commands to write all buffers: :ww is a synonym for
	"write-changed-buffers", and :wwq is now a synonym for
	"write-changed-buffers-and-quit"

- it is now legal to "kill-buffer" a displayed buffer

- there are new variables, $word, $pathname, and $identifier, which return
	the appropriate type of string from the cursor's location

- all of the variables, and the functions and directives of the extension
	language have been documented, and most have been tried, if not
	tested

- two new functions: &rd and &wr, return whether a file is readable or writable

- a new mode, "tabinsert", has been created to fill the needs of the
	"I hate tabs" camp.

- filenames are now put into canonical form -- this keeps "junk", "./junk",
	"./somedir/../junk" from appearing as different files to the editor.

- there is a new mode, "tagsrelative", which, when set, causes filenames
	looked up via tags to have the directory name of the tags file
	prepended to them before being accessed.  This allows one to cd into
	a build tree from within the editor, to facilitate a grep or a local
	build, and have tags lookups continue to work.

- the find-next-error code now honors the "Entering/Leaving directory"
	messages that GNU make (and others?) puts out.

- job control now works right

IMPLEMENTORS NOTES:
===================

- internally, most pointers into the buffer, consisting of a LINE * and an
	int offset are now represented with a MARK structure -- in the
	nineties, it's time to start using structure assignment.

- the set of values that are frequently handed about between buffers and
	windows, or windows and their "children" are now grouped into
	B_TRAITS and W_TRAITS structures, for easier bookkeeping.  There
	are lots of macros to hide the added data structure depth.

- if you add a new setting that should be inherited by and selectable
	on a per-buffer or per-window basis, add it to the W_VALUES or
	B_VALUES structs.  Otherwise, if its just a global value, like the
	X font, make it a variable.  I intend to merge the setting of
	variables in with the other values one of these days.

- there is now a generic printf facility built in, which is layered under
	mlwrite() for the message line, bprintf() to print into a buffer,
	and lsprintf() to print into a string

- LINE structures can now have NULL l_text pointers -- empty lines don't
	have memory associated with them (except for the LINE struct
	itself)

- line text is now "block malloc"ed -- now for most files there is are two
	mallocs and a single read, no copies.  previously there were two
	mallocs per line, and two copies (stdio's and ours).  This change
	implies that LINE structures and their text should not be moved
	between buffers -- the space they occupy may have come from the big
	chunks attached to the buffer structure, and not from the malloc
	pool directly.  So lfree() and lalloc() now take a buffer pointer
	argument.

- there is "line poisoning" code, in line.c, which trashes the contents of
	freed lines and LINE structs, to make it easier to find bad usage.

- do_fl_region() is a convenient wrapper for writing operator commands that
	work on full lines -- there isn't yet a similar wrapper for partial
	line operators.

- use mlwrite() for informative messages that terse mode will suppress,
	mlforce() for messages that _must_ be seen, and mlprompt() for
	messages that need a response from the user unless they're in a
	command file.

vile-9.8v/CHANGES.R4000066400000000000000000003632411415556424100140160ustar00rootroot00000000000000
NOTICE: This change log is officially (sez me) closed.
	All further changes documented (hopefully) in "CHANGES".  This
	file was renamed from "CHANGES" to "CHANGES.R4" on Wed Jan 11, 1995. 	

Changes for vile 4.13 (released Thu Dec 22, 1994)
(pgf)
	+ fixed typo in glob.c which caused compile failure on VMS.

	+ added PATCH_AGAINST environment variable to dpatch target.
	  (makefile.in)

	+ cleaned up selection ifdefs.  no more USE_SEL_FUNCS.  use
	  OPT_SELECTIONS to ifdef references to r_attr_id.  (select.c
	  region.c, estruct.h)

	+ the strings  and  conflict with the new choice for
	  "buffer variable" indicator.  so i'm getting rid of them.  and
	  i'm adding support for \s (and \a, while i'm at it) to the
	  tokenizer. (exec.c, bind.c, macros.doc, vile.hlp)

	+ don't depend on a possibly null abbr_map pointer to decide to
	  reverse the lhs of a map string.  this caused the first mapping
	  of any type (:map or :map!) to be reversed.  i missed this
	  because my first mapping was of a single character.  (map.c)

	+ wrappers provided for TTgetc and TTtypahead because at least one
	  pcc-based compiler balks at passing them as a function pointer. 
	  (map.c)

	+ operators act from pre_op_dot to DOT.  so set pre_op_dot when done
	  sweeping, in case some other motion set it.  fixes 'dqf(%%q'.
	  (select.c)

	+ change _IOLBF flag to _IOFBF on setvbuf call, to turn off
	  line buffering.  we don't need it, since we flush properly
	  anyway, and it slows down output, particularly on an xterm.
	  (most systems used to use setbuffer() anyway, until autoconf)
	  (termio.c)

	+ correct yet _another_ typo made during the great strncpy()
	  conversion.  sheesh.  (bind.c)

	+ readability improvements and editorial corrections to the older
	  sections of README and README.CFG.

	+ moved processing of @cmdfile startup file down to where
	  we normally run .vilerc, to make sure all conditions are the
	  same for both.  this should make running 'vile @.vilerc' and
	  'vile' exactly equivalent.  running a command file caused
	  a core in 4.12 due to NULL curwp.  (main.c)

	+ include text of manpage.rc in vile.hlp, for installations that
	  discard the source directory. (vile.hlp)

	+ revisions to help and man page sections on startup. (vile.hlp,
	  vile.1)

	+ install the man page as xvile.1 when installing xvile. (makefile.in)
	 
(tom)
	+ pick up slash right after a drive designator to fix problem
	  with DOS globbing in the root directory.  (glob.c)

	+ corrected define, so that VMS version builds display-driver
	  (descrip.mms, vmsbuild.com).

(kev)
	+ line.c (put):  Don't set suppressnl when only putting newlines.
	  Note: We may want to visit ldelnewline() and fix it so that the
	  line structure doesn't get hosed when DOT is set to the buffer
	  header.  The circular structure is apparently maintained, but the
	  buffer header is now bypassed.  Suppose there're three lines.  We
	  should have something (roughly) like this:

	  	bufhead -> line1 -> line2 -> line3 -> bufhead

	  But I think that after ldelnewline with DOT as described above,
	  we end up with (again assuming three lines):

	  	bufhead -> line1 -> line2 -> line3 -> line1

Changes for vile 4.12 (released Fri Dec 16, 1994)
(pgf)
	+ clear up section of man page dealing with vile-manfilt. (vile.1)

	+ don't let a mouse click change the current window if we're
	  sweeping.  serious lockup results.  (basic.c)

	+ fix various places that needed to be made more or less aware of
	  the occurrence of sweeping.  quoted motions now never include
	  their endpoint, except in a few mostly "on one line" kind of
	  motions: e, E, f, t, and %.  (csrch.c, edef.h, exec.c, fences.c,
	  main.c, select.c, wordmov.c, vile.hlp)

(kev)
	+ display.c (modeline): For case 'f' and 'F' in the format string,
	  do not display the pathname if it is the empty string.  This seems
	  to be the case for the [unnamed] buffer.

Changes for vile 4.11 (released Thu Dec 15, 1994)
(pgf)
	+ changed order of #includes in x11.c, so that our headers come
	  first.  since we no longer define VMS at all, we'll be okay on
	  most systems.  i hope this doesn't break other systems.  if so,
	  estruct.h and edef.h should be moved after the last X11 include,
	  until we can figure something out.  (x11.c)

	+ changed leading character of so-called "buffer-variables" from
	  a '#' character to '<' character.  the '#' conflicts with
	  the # function key prefix.  THIS MAY BREAK OLD MACROS.  i'm
	  sorry about this, but the choice of '#' as the function key
	  prefix is not really negotiable...  (eval.c, vile.hlp)

	+ fixed buffer-reading examples in macros.doc to reflect the above
	  change.  (macros.doc)

	+ fixed "WRITEABLE" case of the non-HAVE_ACCESS case of ffaccess.
	  the sense was inverted.  (fileio.c)

	+ implemented autowrite mode.  unlike vi, will only save files when
	  suspending or running a shell command, since saving on any buffer
	  switch seems a little silly.  (buffer.c, cmdtbl, main.c, modetbl,
	  proto.h, spawn.c, vile.hlp)

	+ fix OPT_LCKFILES as per johan rosman's suggestion, to make
	  multiple edits by the original locker work correctly.  also fix
	  behavior when file is renamed.  (buffer.c, main.c, file.c)

	+ put in kev's suggested change to allow xvile to grow its screen
	  more gracefully, albeit somewhat delayed. (eval.c)

	+ fixed (for the last time, i hope) the sequence of messages that
	  appear with ":w", ":wq", ":ww", ":wwq", and 'ZZ'.  Now, the "press
	  return to continue" only happens if you're _not_ quitting, you
	  haven't suppressed it with an argument, and something was actually
	  written. (buffer.c, main.c, vile.hlp)

	+ the "modeline-format" setting is now a variable rather than a
	  "setting".  so 'set modeline-format "...."'  must change to
	  'set-variable $modeline-format "...."' in .vilerc files. (edef.h,
	  eval.c, display.c, main.c, modetbl, vile.hlp)

	+ make sure getregion() assigns a unique attr_id to regions
	  it creates, so find_release_attr() doesn't find spurious
	  matches.  this keeps selections from disappearing when an
	  unrelated delete (killregion()) occurs. (region.c, select.c,
	  proto.h)

	+ fixed bug in trimline() which caused it to leave DOT at end
	  of line, if there was trimming to do.  this caused a bug
	  where if two newlines were inserted into a line ending with
	  whitespace, and autoinsertion occurred, then the newlines
	  would insert incorrectly, one correctly, and one _after_ the
	  line that had been broken.  trimline now preserves DOT if
	  possible.  (region.c)

	+ rearrange multimotion() to ensure regionshape is set to exact
	  when we begin a normal quoted motion. (select.c)

	+ the xterm-mouse code is now a proper motion, so that you can
	  use it to follow an operator.  that is, hit 'd', point with
	  the mouse, and click button 1 to delete to the mouse position.
	  x11 code now forces execution of a null motion routine, to
	  make this to work in xvile as well.  (basic.c, cmdtbl, tcap.c,
	  proto.h, x11.c, estruct.h, vile.hlp) [hitting '.' after doing
	  this in the xterm version is interesting, since the motion is
	  relative to the edges of the screen, not to the buffer.  in
	  xvile, the motion that is repeated is null, so nothing happens]

	+ mask off VAML and VAMLFOC bits when comparing attributes in
	  tcap.c, since it doesn't know how to deal...

	+ reset insertmode and set WFMODE if we abort out of replacechar().
	  (insert.c)

	+ rearranged X resource section of help file slightly, to group
	  all resources and subresources more closely together. if we
	  split out all the scrollbar resources into sub-resources, this
	  presentation might make less sense.  (vile.hlp)

	+ modified configure.in to support "--with-CFLAGS=", and turn -O
	  on by default.  it can now be suppressed with '--with-CFLAGS=" "'.
	  is it possible to give the configure script a usage message?
	  (configure.in, configure, README.CFG)

	+ eliminated usage of the return value of strncpy(), since it's
	  broken on at least one version of AIX, and there's no big
	  gain in using it, other than aesthetic value, which, although
	  subjective, really is a fact. :-)  (bind.c, buffer.c, eval.c,
	  filec.c, glob.c, spawn.c)

	+ eliminated all uses of the ScratchName macro, since it getting hard
	  to write it portably.  all vile-created buffer names are now
	  defined as char arrays in edef.h, and they all have the suffix
	  "_BufName", e.g. "HELP_BufName" and "OUTPUT_BufName". (bind.c,
	  buffer.c, edef.h, estruct.h, eval.c, exec.c, filec.c, finderr.c,
	  history.c, line.c, main.c, map.c, modes.c, msgs.c, oneliner.c,
	  spawn.c, tags.c)

	+ eliminated the CPP_xxx checks that were used to help create the
	  ScratchName macro. ( aclocal.m4, configure, configure.in)

	+ fixed bogus cut-n-paste'd help messages for Macro buffers.  (cmdtbl)

	+ rearranged utime()/utimes() code so that utimes is now favored
	  over utime if both are present.  we think that systems with bad
	  utime() implementations are the ones that have utimes(). 
	  (fileio.c)

	+ eliminate funky structure assignment "structthing = {foo, bar}".
	  (ntconio.c) 

	+ mention -O flag on by default, and necessity of working
	  VPATH support in make program.  (README.CFG)

	+ xvile does not need to (and shouldn't) attempt to reopen /dev/tty
	  when stdin is a pipe.  the prevented xvile from starting from
	  anywhere but the command line.  ifdefed code on DISP_X11. (main.c)

	+ change make_backup() to correctly check boolean return code from
	  ffexists() when deciding whether to back up a file.  (fileio.c)

	+ changed rcsdiff commands to use unified diff format. (makefile.in)

	+ fix bug in BUG check in mapped_c() -- was not clearing NOREMAP
	  bit before comparing to poundc.  this caused arrow keys (probably
	  all function keys not mapped by user) to appear to fail when
	  noremap mode was set. (map.c)

	+ blankline() was incorrectly de/entabbing its region, even when it
	  wasn't rectangular.  (region.c)

	+ implemented ":abbr" command.  ( CHANGES, README, cmdtbl,
	  insert.c, map.c, proto.h, vile.hlp)

	+ added "show-system-mapped-keys" command to show the mappings
	  for the function keys.  this replaces passing numeric arg hack in
	  :map and :map!.  (map.c, cmdtbl)

	+ added "populate" admin target to makefile.in.

	+ wording changes to vile.hlp and vile.1.

	+ added "show-bindings" to cmdtbl, to match claims made in
	  vile.hlp.

	+ turned region formatting back on.  lost OPT_FORMAT in final
	  merge for 4.10. (estruct.h)

	+ changed shorten_path to not return NULL unless arg was NULL.
	  this prevents possible core dump (or ugly display) when doing
	  "show-tagstack" after "vile -t tagname". (path.c)

	+ change getfile() to return FALSE if getfile2bp() returns NULL,
	  and prevent a core dump.  this can happen, for instance, if the
	  bp->b_fname is the result of non_filename(), which can happen if
	  a tag lookup is done from a listbuffer, and a subsequent tag-pop
	  command is done which tries to return there.  (file.c)

	+ change tags() to push the buffername rather than the filename
	  if we're tag'ging from an internal buffer.  this improves our
	  chances of getting back to it.  (if it's gone from the screen,
	  you still won't be able to get back)  (tags.c)

(kev)
	+ x11.c (x_setfont): Call XSetFont() for all of the newly added
	  GC's.

	+ x11.c (display_cursor): Draw the little rectangle with the cursor
	  color instead of the normal text color when the window loses focus.

	+ proto.h (x_resize): Declared.

	+ eval.c (SetVarValue): Call x_resize() for EVPAGELEN and EVCURWIDTH.

	+ x11.c (x_resize): New function.  Call it from x_configure_window().

	+ vile.hlp: Documented new color cursor and modeline capabilities.

	+ estruct.h (VACURS, VAMLFOC, VAML): New attributes.

	+ display.c (modeline): Set VAMLFOC and VAML attributes as
	  appropriate.

	+ x11.c (x_preparse_args, flush_line, struct _text_win): Added new
	  code for changing the color of the cursor as well as the
	  modelines.

	+ x11.c (update_scrollbar_sizes): Make grips the same color as the
	  background of a modeline which does not have focus.  It's too
	  much work to make the grip color always match the color of the
	  modeline.

	+ estruct.h (OPT_FORMAT): Added back in after being lost in
  	  the shuffle.  Also checked the other "OPT_" features occurring
  	  in cmdtbl to make sure that no others were also lost in the
  	  shuffle.


(tom)
	+ corrected a null-pointer reference in 'getfile()' (file.c).

	+ modified 'pathcat()' to (on VMS) ensure that the result is a valid
	  pathname (path.c).

	+ adjusted autoconf tests for cpp substitutions (aclocal.m4, estruct.h).
	  [but that stuff's gone.  i've preserved these changes on an RCS
	  branch (cpp_stuff) in case we need it.  -pgf ]

	+ supplied missing DISP_VMSVT setting (estruct.h).

	+ added FL_EXECABLE, FL_WRITEABLE, FL_READABLE flags to 'flook()' call
	  to use in 'access()' call (estruct.h, bind.c, eval.c, exec.c, filec.c,
	  fileio.c, main.c, tags.c, version.c).

Changes for vile 4.10 (released Mon Dec 05, 1994)
(pgf)
	+ changed keystroke8() and keystroke_raw8() to loop and
	  beep until a simple 8-bit char is typed.  no SPEC prefixes
	  allowed. (input.c)

	+ tuned kev's changes to mapped_c().  new routine called
	  mapped_keystroke_raw() which calls mapped_c in such a
	  way that function keys will expand to #c, but no further.
	  used when getting a :map lhs from the user. (map.c, input.c,
	  proto.h)

	+ fix lint warnings from "questionable" pointer practices,
	  rationalized names of routines called by liststuff() (now all
	  makeXXXlist()).  (bind.c, buffer.c, eval.c, line.c, map.c,
	  modes.c, proto.h, random.c, region.c, tags.c)
	  
	+ removed no-doubt obsolete ifdefed "overlay" statements (window.c,
	  region.c)

	+ lint: removed unused assignment in desfunc().  (bind.c)

	+ change the temp storage of unmatched chars in maplookup()
	  from char to int, to prevent loss and subsequent extension
	  of sign information. (map.c)

	+ added short on-line help for all commands.  ifdefed on
	  OPT_ONLINEHELP.  shows up in describe-bindings and apropos
	  listings.  adds 13.5K. (bind.c, cmdtbl, mktbls.c, estruct.h)

	+ added "list-motions" and "list-operators" commands, which show
	  their respective subsets of the commands. (bind.c, proto.h,
	  vile.hlp)

	+ added "describe-function" command.  added "appendit" argument
	  to liststuff, to let the contents of popups (like Binding List)
	  be grown incrementally.  the "describe-key" now describes the
	  function the key is bound to as well.  (bind.c, buffer.c, cmdtbl,
	  eval.c, line.c, map.c, modes.c, proto.h, random.c, tags.c,
	  vile.hlp)

(kev)
	+ map.c (mapped_c): Minor changes to make quoted spec characters
	  generate pound sign sequences.  This is important for interactive
	  mapping of function keys.  Example: Try ":map  h" prior to
	  this fix and afterwards.  Also try "a^V".   denotes
	  a press of the F1 function key.

	+ x11.c (kqdel): Took out call to char2int() which I had put in
	  a few days earlier..

	  (x_key_press): Don't convert function and arrow keys to a
	  sequence of bytes via kcod2escape_seq().  Leave them in the SPEC
	  form instead.  This was causing # sequences to be displayed
	  in insert mode and it also broke command line history (as well
	  as a bunch of other stuff, I suspect).

	+ vile.hlp: Fixed a few typos.

	+ map.c, x11.c (maplookup, kqdel): Judiciously call char2int() in
	  order to strip off sign extension.  These fixes are in response
	  to the use of the META key being broken.

(tom)
	+ added autoconf-test for getpgrp().  (aclocal.m4, configure.in)

 	+ reduced timeout to 30 seconds on MSDOS to avoid overflow (main.c)

	+ various nits/fixes for VMS, CLIX, IRIX, TurboC (descrip.mms,
	  estruct.h eval.c, glob.c, ibmpc.c, makefile.tbc, region.c, termio.c,
	  vile.hlp, x11.c)

Changes for vile 4.9 (released Tue Nov 29, 1994)
(pgf)
	+ changed all OS #defines to SYS_xxx.  like SYS_UNIX, SYS_MSDOS,
	  etc.  changed all compiler #defines to CC_xxx.  like CC_LATTICE,
	  CC_TURBO, etc.  changed all screen #defines to DISP_xxx.  like
	  DISP_TERMCAP, DISP_X11, etc.  changed all feature #defines to
	  OPT_xxx.  i think you see the pattern.  eliminated some ifdefs
	  around things that we've never turned off, or that can't be
	  turned off without severely breaking vi compatibility.  got rid
	  of some old "ifdef NEVER" kind of stuff.  (this affected most
	  source files)

	+ catnap() now checks for tty input at least periodically on all
	  platforms.  the nap is broken into .1 second increments, and
	  typahead() is called in between each one. (random.c)

	+ new mode, "maplonger", which controls whether vile favors the
	  longer or shorter of two nested mappings.  (modetbl, map.c)

	+ new mode, "remapfirst", which controls whether vile will remap the
	  first character of a mapping.  vi doesn't, vim does.  (modetbl,
	  map.c)

	+ rationalized (?) and documented (!) the various levels of character
	  input routine.  see top of input.c.

	+ renamed typahead() to tttypahead() to match ttclose() et al, and
	  added typahead entry to the TERM struct.  (termio.c and others)

	+ all former callers of tgetc() now call one of the keystroke()
	  variants instead.  (many files)

	+ all former callers of tungetc() now call unkeystroke() instead.
	  (many files)

	+ when creating backup files, ifdef check of matching dev and inode
	  on UNIX only.  it doesn't work under watcom (DOS), and i don't
	  know where else it will.  (fileio.c)

	+ show offending errno when it's out of bounds in mlwarn(). (display.c)

	+ added itbuff.c/o/obj to the rest of the makefiles ( descrip.mms,
	  makefile.djg, makefile.in, makefile.tbc, makefile.wat,
	  makefile.wnt, vms_link.opt, vmsbuild.com)

	+ removed mapchars.[ch] from distribution, and removed references
	  to them.  (makefile.in, cmdtbl, main.c)

	+ ifdefed out some more unused code.  also made multimotion()
	  yank the selection as a side-effect, to be more like ^A-s.
	  (select.c)

	+ ran lint on Solaris (i think.  maybe it was SunOS).  (display.c,
	  fileio.c, input.c, itbuff.c, map.c, select.c, tbuff.c, tcap.c,
	  undo.c)

	+ cloned and modified tbuff.c to create itbuff.c.  the routines
	  there work on "integer tbuffs".  use these routines, and
	  the corresponding ITBUFF data structure everywhere user keyboard
	  input is accumulated.  this allows us to store wide keycodes,
	  and greatly simplifies keystroke playback and :map implementation.
	  (tbuff.c, itbuff.c, makefile, input.c, insert.c, line.c, map.c,
	  estruct.h, edef.h, proto.h)

	+ added new routines to tbuff.c/itbuff.c:  [i]tb_unnext() to undo
	  tb_next, itb_seek() to change the itb_last pointer, itb_delete()
	  to remove N elements from middle of an ITBUFF, itb_insert() to
	  insert a new element in the middle.

	+ changed :map implementation to support "user" and "system"
	  timeouts, and to support controllable remapping via "set
	  [no]remap" and vim-style ":noremap" commands.  (map.c, modetbl,
	  main.c, vile.hlp, proto.h)

	+ moved xterm-mouse functionality to tcap.c.  it's now driven
	  by a system :map of ESC [ M, which is bound (indirectly) to the
	  old xterm_button() routine. (input.c, tcap.c, cmdtbl, proto.h)

	+ promoted '#' to be a regular peer of the ^X and ^A prefixes, and
	  defined a set of "standard" #-key bindings, which are in turn
	  available from system function keys (see vile.hlp).  screen
	  driver modules may use the new header "nefkeys.h" to access this
	  standard list.  i may have lost some of the linux-specific
	  bindings from cmdtbl -- should they be reintroduced, they
	  should go in tcap.c, as an ifdef'ed addtosysmap() call.  (bind.c,
	  input.c, vile.hlp, main.c, cmdtbl, mktbls.c)
	  
	+ collapsed kcod2pstr() to rely on kcod2escape_seq().  (bind.c,
	  input.c, proto.h)

	+ changed names of "dummy" binding functions: cntl_a_func(), 
	  cntl_x_func(), unarg_func(), esc_func(), poundc_func(). (main.c,
	  input.c, proto.h)

	+ added footnotes to the ":map" listing to denote whether mappings
	  are remappable or not.  system maps (i.e. function keys) may
	  be viewed with "1:map". (map.c)

	+ moved system-specific function key mappings to tcap.c and ibmpc.c.
	  removed them from cmdtbl.  use standard defines for the SPEC
	  bindings. (ibmpc.c, tcap.c, x11.c, x11simp.c, cmdtbl)

	+ the lhs of map sequences may now contain null characters.  the UI
	  still doesn't support entering them.  necessary since ibmpc
	  function keys start with a 0 character.  (map.c, ibmpc.c,
	  proto.h)

	+ changed alignment of settings in the [Settings] buffer so that
	  the characters by which the names are sorted are vertically
	  aligned. (modes.c)

	+ changed a bunch of whitespace in modetbl for better alignment.

	+ don't bother attempting to catnap for 0 time.  (random.c)

	+ added '#' to the name in the short history list that
	  corresponds to previous buffer. (noautobuffer mode only) (buffer.c)

	+ improved description of buffer lists wrt autobuffer mode.

	+ attempted to rationalize some of the informational commands and
	  added text to help file.  (cmdtbl, vile.hlp)

	    new command names:		synonymous with:
		show-bindings		describe-bindings
		show-help		help
		show-buffers		list-buffers
		show-mapped-chars	map
		show-mapped!-chars	map!
		show-tagstack		tagstack

	    changed command names:	old name was:
	       show-terminal-chars      show-terminal    
	       list-variables           list-vars        
	       show-variables           show-vars        

	+ prevent shrinkwrap() from claiming more than 3/4 of a windows
	  rows when popping up a new window.  (window.c)

(tom)
	+ corrected missing b_last_used values for invisible buffers which
	  caused buffers to be delinked when toggling autobuffer mode
	  (buffer.c).

	+ modified logic of 'modeline_modes()' to make it compile on vms
	  (display.c).

	+ modified auto-config for 'utime()' for solaris, vms compiles
	  (estruct.h, aclocal.m4, configure.in)

	+ corrected ifdef for "backup-style" mode (main.c).

	+ modified 'find_user()' to use $HOME if 'getpwuid()' fails (path.c).

	+ improved #/% toggle so that it doesn't toggle into invisible buffers
	  (buffer.c).

	+ corrected some ifdef combinations (cmdtbl, file.c, tcap.c, wordmov.c)

	+ modified ifdef for incremental searches to use symbol OPT_ISRCH
	  (cmdtbl, isearch.c, proto.h).

	+ modified ifdef for find-error to use symbol OPT_FINDERR
	  (cmdtbl, file.c, finderr.c, main.c, spawn.c, proto.h).

	+ modified ifdef for advanced-editing features to use symbol OPT_AEDIT
	  (cmdtbl, opers.c, random.c, region.c, proto.h).

	+ corrected error in globbing that caused incorrect list to be built
	  for expressions such as "*/foo" (glob.c).

	+ modified logic of 'flook()' to allow search of $PATH only, so that
	  the lookup in version.c can find the correct executable, i.e., not
	  necessarily the copy of vile in the current directory (bind.c,
	  fileio.c, version.c).

	+ modified logic of 'filefind()', which implements ":e" command to load
	  only the first buffer matched in a wildcard, and to make all matches
	  treated as command-arguments so that ":n" applies to them (buffer.c,
	  file.c, main.c, random.c)

	+ corrected 'namebuffer()', prohibiting blank buffer-names (buffer.c).

	+ added function 'mktrimmed()' to support correction to 'namebuffer()',
	  as well as new macro function "&trim" (eval.c).

	+ modified "error-buffer" command to accept filenames as well as buffer
	  names (buffer.c, finderr.c).

	+ animated [Tag Stack] buffer (tags.c).

	+ modified 'gettagsfile()' to check modification-times of tags files,
	  and re-read as necessary (tags.c).

	+ corrected a conflict between foreground/background colors (tcap.c).

	+ fixed some errors shown by Purify (display.c, regexp.c, window.c).

(kev)
	+ insert.c (nextindent): Get the indent of the first character on
	  the line after advancing a word when there was no first
	  character.  This fixes a core dump which may be reproduced as
	  follows: Get into vile, making sure that autoindent is set.  Put
	  about five or so blank lines in the buffer.  Now go to the top of
	  the file and type 'cc' (change line).  This will cause a core
	  dump.  A core dump will also be produced if there are a number of
	  blank lines and then a non blank line.  The key here is that the
	  indentation level (indicated by fc) was determined to be -1 and
	  was not reset to a kosher value for the code below.

	+ display.c (offs2col): Declare local variable length as an int
	  instead of as SIZE_T.  (Remember that SIZE_T is unsigned on a lot
	  of machines.) Also adjusted test which is used for determining
	  which character that we're on.  This fixes a bug which (prior to
	  this fix) may be reproduced as follows: Get into vile and enter
	  the following: "ahere is a blank line".  Select the word
	  "is".  Type "u" for undo.  Note that the selection highlighting
	  remains even though the line is blank.  Then type "o" to open up
	  a new line.  It is at this point that a core dump occurs.

	  Note that this fix does nothing to solve the problem of the
	  highlighting sticking around.  It just makes that code more
	  robust so that it doesn't core dump when the line length is
	  less than zero (which can happen for empty lines).

	+ undo.c (repointstuff): Always repoint marks.  I've #if'd out the
	  lines which used to check to see whether or not the suggested new
	  pointer was valid or not.  Paul should check this stuff over and
	  make sure that it's ok.  In any event, it seems to (with one
	  exception) fix the other half of the problem described above.  It
	  also seems to make the behavior of marks wrt undo work more like
	  real vi.  Don't know whether this is an argument for or against,
	  just an observation...

	+ aclocal.m4: Added missing dnl to last line of file.

	+ buffer.c (sortlistbuffers): Don't forget to keep the unused
	  buffers when rebuilding the buffer list.


Changes for vile 4.8 (released Mon Oct 31, 1994)
(pgf)
	+ changed name of SIZEOF macro to TABLESIZE, to avoid conflicts
	  with X11 headers.  (buffer.c display.c estruct.h fences.c
	  ibmpc.c line.c mktbls.c modes.c tcap.c version.c vmspipe.c x11.c
	  x11simp.c)

	+ incorporated patches from Johan Rosman for simple file locking
	  protocol.  it's not rigorous, which he freely admits, but it
	  solves their problem, so i'm including the code, though turning
	  it off by default.  ( buffer.c display.c estruct.h file.c main.c
	  modes.c proto.h modetbl makefile.in and new file lckfiles.c)

	+ fixed code in filename() which allowed one to rename a file
	  to the null string by backspacing out of the "Name:" prompt.
	  (file.c)

	+ added mask with XtIMXEvent to all calls to XtAppPending(), to
	  prevent spurious returns due to non-events (timers). (x11.c)

	+ massaged the distribution targets in the makefile, so i
	  can more easily produce a tar.gz file, and not make
	  people unpack the shar anymore. (makefile.in)

	+ changed all places where we check a char against abortc
	  to check against intrc, and check interrupted() as well.
	  this lets us not translate intrc to abortc in tgetc(),
	  which fixes some bugs where interrupts are treated like
	  escapes.  this only showed up when ESC was being used for
	  something other than aborting -- like completion.
	  (csrch.c estruct.h eval.c exec.c history.c input.c insert.c
	  isearch.c select.c spawn.c window.c)

	+ turned off filter() for UNIX and DOS, since the filterregion()
	  code is superior and better tested. (spawn.c)

	+ added support in exec_named_command() for detecting a trailing '!'
	  on a command name, and if the BANG flag is set for its function
	  entry, passing a special argument so the function can know it was
	  invoked with a "xxx!" form.  (estruct.h, exec.c, cmdtbl)

	+ implemented support for ":w!" to override failed writes of the
	  backup file.  detect the special argument (see above) in
	  filesave() and filewrite(), and pass "forced" flag down through
	  writeout(), writereg(), and ffwopen(). (fileio.c, file.c, proto.h,
	  vile.hlp)

	+ created mode to control file backups, and implemented ~-style
	  backups in addition to the existing .bak style.  new mode is
	  "backup-style", and takes values "off", ".bak", and "tilde". 
	  code is ifdefed on OPT_FILEBACK, and is turned off for VMS,
	  since i don't know what's appropriate.  also, left (minimal)
	  hooks to someday implement emacs-style numbered backups.
	  (estruct.h fileio.c main.c modes.c modetbl vile.hlp)
	  
	+ added link(), utime(), utimes() to the list of system
	  calls to check for, and for whose declarations to check. 
	  (configure configure.in proto.h)

	+ implemented 'q' command, for doing "quoted motion", for lack
	  of a better mnemonic.  (cmdtbl display.c proto.h region.c
	  select.c vile.hlp wordmov.c x11.c)

	+ fixed bad "set" line in vile.hlp, in the my_cd_action example.
	  It said "set $foo=$bar" syntax; which can be either "set foo=bar"
	  or "setv $foo=$bar".

	+ changed dos-mode behavior yet again.  with global dosmode set, we
	  were stripping carriage returns at the same time we were deciding
	  whether a buffer was doslike or not.  this led to the deletion of
	  CR's even if we decided the file was unixlike.  the correct
	  behavior, which unfortunately involves another pass through the
	  buffer, is to figure it out (i.e.  count lines ending in CR), and
	  then, only if it _is_ doslike (more CR lines than lines without)
	  then go through and strip them.  i discovered the bug when i had a
	  command file containing a few :map commands that ended in ^M.  the
	  ^M's were being silently discarded.  (file.c)

	+ added double-quote as commenting character in the macro language.
	  for vi compatibility, this should act as a comment everywhere
	  except shell commands and map commands, but we only currently
	  honor it at the beginning of line.  (exec.c)

	+ fix behavior of commands which behave differently when not
	  given arguments, when used in an executed file.  :map and :f
	  were both ignoring their arguments when sourced in a file
	  interactively. fix was in end_named_cmd() and more_named_cmd().
	  (exec.c)

	+ new routine, macliteralarg(), which returns the rest of a command
	  line literally as a single token.  used for the  of :map.
	  (exec.c)

	+ call new macliteralarg() from map_common() when getting the ,
	  if cline is true.  (map.c)

	+ removed "if (did_tungetc()) tgetc()" from readpattern() -- it
	  was obsolete, and only screwed things up when executing a :map.
	  (search.c)

	+ always do full update() in mlyesno() and mlquickask(), since
	  they may be invoked from a command file, and we want the
	  display as current as possible. (input.c)

	+ use mlforce() rather than mlprompt() to force appearance of
	  the questions in mlyesno() and mlquickask(), in case discmd is
	  false. (input.c)

	+ line length reformatting in oneliner.c

(kev)
	+ aclocal.m4, configure.in (VC_SYS_ERRLIST): Check for presence of
	  sys_errlist[].

	+ estruct.h (sys_errlist): Only declare if HAVE_EXTERN_SYS_ERRLIST
	  is not defined.

	+ manpage.rc: Set noview prior to calling
	  attribute-cntl_a-sequences-til.  Set view afterwards.

	+ display.c (vtalloc): Allocate space for rows in vscreen[] and
	  pscreen[] when the height changes.  I was getting core dumps
	  in xvile when resizing vertically.

	+ makefile.in (manfilt): New target which should not be necessary,
	  but is due to the lameness of certain `make' programs.

	+ termio.c (ttopen): ifdef'd IUCLC which doesn't exist on all
	  systems.

	+ msgs.c (popup_msgs, msg_putc): Don't save/restore DOT unless
	  curwp has been initialized.  Lack of this check was responsible
	  for core dumps when executing "xvile @~/.vilerc".

	+ buglist: Deleted items which have been satisfactorily dealt with.

	+ display.c (PutMode, vtprintf): Deleted these functions.

	  (modeline): Rewritten to use a format string for outputting the
	  mode lines.

	  (mlfs_prefix, mlfs_suffix, mlfs_skipfix): New modeline() helper
	  functions.

	+ modetbl (ModeLine-Format, MLFORMAT): New string mode.

	+ main.c (global_val_init): Initialize format string for mode lines.

	+ modes.c (adjustmode): Adjusted "#if OPT_WORKING ... #endif" pairs
	  for the case where OPT_WORKING is disabled.

	+ x11.c (x_open): Initialize term.t_mcol and term.t_mrow.

	+ eval.c (SetVarValue): Call mayneedundo() for EVCURCHAR and EVLINE
	  ($char and $line) variables.

	+ x11.c (x_key_press): Call char2int() when putting characters
	  in the queue as integers in order to prevent sign extension.

	+ map.c (maplookup): Call char2int() when returning first unmatched
	  character in order to prevent sign extension.

	+ vile.hlp: Removed vile-manfilt compilation / installation
	  instructions.  vile-manfilt is now built and installed as part
	  of the default installation procedure.

	  Also removed note concerning selections; this note said that the
	  selected area includes all highlighted chars except for special
	  case in which the last highlighted character is the first
	  character on a line.  This is no longer true or necessary since
	  we now permit selections to select the end-of-line character.

	  Added documentation concerning scrollbar and selection
	  subresources.  Also added some sample .Xdefaults entries.

	  Reformatted paragraphs which had lines too long for an eighty
	  column display.

	+ map.c (struct maprec): Documentation.

(tom)
	+ added OPT_VMS_PATH to estruct.h, used this to ifdef the vms pathname
	  parsing (and also some test-code) on UNIX for off-line testing of the
	  VAX code (estruct.h, fakevms.c, file.c, filec.c, glob.c, input.c,
	  main.c, path.c, proto.h, vms2unix.c).  Now, VMS name-completion is
	  done internally using UNIX-style pathnames.

	+ other mods to support name completion on VMS, and off-line testing
	  (bind.c, file.c, filec.c, glob.c, path.c).

	+ mods to msgs.c to avoid struct init in declaration for SunOS K&R
	  compiler.

	+ added files fakevms.c, fakevms.h and vmsbuild.com

	+ added OPT_MSDOS_PATH symbol to simplify related ifdefs for parsing of
	  pathnames for MSDOS/WIN31/NT/OS2 (estruct.h, file.c, filec.c, glob.c,
	  main.c, path.c, proto.h).

	+ corrections to VMS version of 'shorten_path()' (path.c)

	+ some lint (bind.c, display.c, eval.c, input.c, insert.c, map.c,
	  region.c, select.c)

	+ fixes for SMALLER-ifdef (display.c, insert.c, map.c, window.c)

	+ added ifdef-symbol OPT_MLFORMAT for modeline-format (estruct.h,
	  display.c, main.c, modetbl)

	+ corrected handling of empty-.vilerc file: was hanging, not formatting
	  modeline correctly (display.c).

	+ added ifdef-symbol OPT_ENUM_MODES for the fixed-string modes
	  (estruct.h, bind.c, main.c, modetbl, modes.c)

	+ added logic to allow termcap-driver on Linux to display colors
	  (tcap.c, estruct.h)

	+ renamed REBIND to OPT_REBIND, modified logic for kbindtbl[] so that
	  an arbitrary number of key bindings can be stored.

	+ modified the TTrev() logic in the termcap driver to display video
	  attributes (i.e., bold, underline, reverse) when OPT_VIDEO_ATTRS
	  is set (tcap.c, display.c, estruct.h).

	+ modified flags of attribute commands so that they accept a range
	  as well as a repeat-count (cmdtbl).

	+ added binding ^A-N to allow reset of attributes on a region (cmdtbl,
	  select.c).

	+ corrected video-attribute highlighting for IBMPC driver (ibmpc.c).

	+ corrected ifdef'ing for 'kbindtbl[]' (mktbls.c).

	+ modified error-test in 'ffropen()' to avoid noisy error when vile
	  cannot find .vilerc in MSDOS filesystem from Linux (fileio.c).

Changes for vile 4.7 (unreleased Tue Sep 27, 1994)
(pgf)
	+ makefile.in: removed * chars from install complete message to
	  keep them from being shell-expanded, and make sure rw and list
	  use the right makefile (i.e.  makefile.in) since "makefile" may
	  not be built yet.

	+ off-by-one on strcpy() in bind.c (otto lind)

	+ added code to detect and honor new-style NeXT tags file format
	  in tags.c. (otto lind)

	+ rationalized setting of dos mode (too bad i didn't call this
	  "crlf" mode instead) so that for all internally generated, or non-
	  existent buffers, dos mode is set based on the OS's line-style.
	  otherwise, for existing files, empty or not, the lines vote on
	  the style for the buffer. (file.c, main.c, random.c, vile.hlp)

	+ added Home and End key support to x11.c, per user contrib. (x11.c)

	+ added line-percentage indication to ruler mode display, per user
	  contrib. (display.c)

	+ new command, "beep", implemented in function userbeep(), which
	  lets the user beep when they want to.  this intentionally does
	  not call kbd_alarm, but rather TTbeep directly.  (random.c, cmdtbl,
	  proto.h)

	+ new mode, "working", which enables/disables the working... messages.
	  i think i've got it set up so the signals themselves stop if
	  noworking is set.  (modes.c, display.c, main.c, vile.hlp)

	+ added shrinkwrap support for the [Help] window. (bind.c)

	+ fix core dump from giving arg of 1 to prevwind().  (window.c)

	+ create l_strtol, which also accepts 'c' constants.  use it
	  in eval.c whenever parsing user input to numeric functions. (eval.c,
	  proto.h)

	+ prevent core dump if ~endm given when not in macro definition
	  (exec.c)

	+ change "BOTTOM" and "TOP" in "Search reached XXX without matching..."
	  to "bottom" and "top". (search.c)

	+ added "[Search wrapped]" message to /, ?, n, N commands.
	  (search.c, oneliner.c, isearch.c, proto.h)

	+ fixes to swbuffer() to prevent coredump when errors encountered
	  when running the bufhook routine. (buffer.c)

	+ fix to dobuf() to prevent handling of a ~endm when execlevel is
	  non-zero.  if this is true, then the store-macro/store-procedure
	  won't have happened (due to the early return in docmd()), and it'll
	  look like an unmatched ~endm. (exec.c)

	+ in liststuff(), don't switch to the list unless it's its first
	  popup.  actually, switch (in popupbuff) and then switch back.
	  this guarantees that the last call to swbuffer is for curbp.
	  (buffer.c)  [ it would be better if popupbuff() didn't need
	  to do the swbuffer at all ]

	+ renamed CMASK to CHARTYPE to avoid name conflicts.
	  (edef.h estruct.h input.c line.c proto.h eval.c main.c)

	+ the screen is now resized dynamically, instead of having a
	  fixed maximum.  (display.c, x11.c)

	+ changed term.t_nrow and term.t_mrow to hold the actual number
	  of screen rows, rather than the highest index.  this makes it
	  a) symmetric with t_[nm]col and b) a whole lot easier to
	  remember how it works.  also introduced routine bottomleft() for
	  moving the cursor there.  (ansi.c, display,c eval.c ibmpc.c
	  isearch.c main.c spawn.c st520.c tcap.c termio.c vmsvt.c
	  win31drv.c window.c x11.c x11simp.c)

	+ some fixes for DEBUGM ifdefs (eval.c exec.c)

	+ gnu warning cleanup in vmalloc.c

	+ main.c: changed initial value of popup-choices to "delayed", to
	  match readline behavior

	+ convert ^M character in replacement pattern to a newline, for
	  vi compatibility.  (oneliner.c)

(kev)
	+ display.c (updupd): Don't permit typahead to be called for X11
	  from this function.  This caused some core dumps since x_typahead()
	  is basically another event loop.  When a timer event was set
	  (to blink the cursor), core dumps would occur due to the display
	  structures not being in an updated state.

	+ x11.c (x_getc, x_typahead): The recent addition of the
	  beginDisplay/endofDisplay pairs seems to have caused a plethora
	  of undesirable messages from imworking().  I've removed the
	  beginDisplay/endofDisplay pairs which I had added to both of
	  these functions.  x_getc() had already been protected from
	  imworking by the doing_kbd_read flag (set in tgetc() in input.c). 
	  But x_typahead() needs the same protection.  I've added some code
	  which sets the doing_kbd_read flag and restores its old value
	  prior to returning from x_typahead().
	  
	+ random.c (catnap): Ifdef'd for X11 to call x_typahead when called
	  with flag which indicates that the input queue should be watched
	  for user input.  We may want to restructure this code and the code
	  which calls catnap() somewhat to use Paul's idea for a timed read.

	+ x11.c, proto.h, termio.c (x_typahead): Now takes as a parameter the
	  time in milliseconds to wait for type-ahead to occur.

	+ x11.c (kqpop): Return character popped from end of queue, not
	  beginning.

	  (x_getc, x_typahead): Protect guts of function from imworking()
	  with beginDisplay / endofDisplay pairs.  I originally thought
	  that this was causing some problems in the mapping code which
	  seemed to be caused by the imworking interrupt.  Even though
	  the problem was with kqpop(), I'm leaving the beginDisplay /
	  endDisplay pairs in since the keyboard queue routines are
	  probably not reentrant.

	+ random.c (catnap): Changed argument to sleep call to allow
	  for catnaps longer than one second.

	+ termio.c (typahead): Call x_typahead instead of x_is_pasting.

	+ x11.c, proto.h (x_is_pasting): Deleted.

	+ x11.c, proto.h (x_typahead): New function.

	+ termio.c (typahead): Modified first version of this function to
	  match the second with regard to X11 code.

	+ random.c (catnap): Block SIGALRM signals while in select().

	+ configure.in (sigprocmask): Check for existence of this function.

	+ random.c (catnap): Use both tv_sec and tv_usec in the HAVE_SELECT
	  code.  This is necessary (on certain systems at least) in order to
	  sleep for longer than one second.

	+ input.c (tgetc): Added infinite loop detection.  Infinite loops
	  can occur as a result of mapping.

	+ map.c: Added new data structures and functions for dealing more
	  fully with map and map!.  Removed the old structures and functions
	  for dealing with a simple case of map.  

	+ input.c, proto.h (tungetstr): New function.

	+ main.c, insert.c (map_check): Removed calls to this function.

	+ map.c, proto.h (map_check): Deleted.

	+ map.c, proto.h, cmdtbl (map_proc): Deleted.

	+ proto.h, map.c (relist_mappings): Deleted declaration from proto.h.
	  Moved to map.c and declared static with new parameter.

	+ input.c (kbd_reply): Added code for KBD_NOMAP.

	+ estruct.h (KBD_NOMAP): New kbd_reply() option.

	+ map.c (addtomaps, addtomap, maplookup): New functions for dealing
	  with mapped keys and key sequences.  There is also a new data
	  structure (struct maprec) and a couple of global variables for
	  storing the maps.  [I discovered after I'd gotten this code
	  working that Tom had written some similar looking stuff which is
	  located in mapchars.h and mapchars.c.]

	+ input.c (kbd_key): Added call to maplookup.  Made small change
	  to the ANSI_SPEC stuff to avoid catnapping if we've already
	  catnapped in maplookup().  My initial inclination was to
	  remove the ANSI_SPEC stuff, but I've decided to leave it in
	  place for a while.  I don't yet understand the workings of
	  input.c well enough to muck about with it too much.

	+ tcap.c (keyseqs): Table associating function key capability names
	  (in terminfo/termcap) with the code which vile should use when
	  one of these sequences is received.

	  (tcapopen): map key sequences found in keyseqs[].

	+ input.c (tungottenchars, tungetc, tgetc): Use a TBUFF instead of
	  fixed size array for storage of ungotten characters.  tungetc()
	  will now cause ungotten characters to be stacked.  Previously,
	  only one keystroke (which may consist of multiple characters) could
	  be ungotten.  Now, multiple keystrokes may be ungotten.

	+ x11.c (x_key_press): Set the high bit (HIGHBIT) if one of the
	  Mod1 (Meta) keys are held down.

	+ x11.c (selgc, revselgc): New fields in struct _text_win.
	  
	  (x_preparse_args): Initialize selgc and revselgc.

	  (x_setfont): Set font in selgc and revselgc.

	  (x_scroll): Use selgc and revselgc to display selections.

	  (display_cursor): Call flush_line() instead of calling
	  XDrawImageString() directly.

	+ select.c, display.c (VASEL): Use instead of / in addition to
	  VAREV in certain places.

	+ estruct.h (VASEL): New preprocessor constant used for indicating
	  selections.

	+ select.c (extended_region):  Fixed a bug which manifested itself
	  when extending a selection with text before the selection.

	  (operattrital): Fixed message passed into operator().

	+ line.c (put): Rewritten somewhat to be faster for non-rectangular
	  regions.  Tests on a SPARCstation IPC indicate that the new code
	  is 8-16 times faster.  The old code may be reenabled by searching
	  for SLOWPUT in line.c and changing this preprocessor constant from
	  0 to 1.

	+ vile.hlp (popup-choices): Changed documentation regarding this global
	  value.

	+ main.c (global_val_init): Initialize GVAL_POPUP_CHOICES to immediate.

	+ modes.c (FSM_CHOICES, struct FSM, fsm_popup_choices, fsm_error,
	  fsm_tbl, fsm_idx, is_fsm, legal_fsm, fsm_complete): New stuff for
	  dealing with fixed string modes. (fsm stands for fixed string mode).

	  (adjvalueset): Call the fsm stuff.

	+ modetbl (POPUP_CHOICES): Made this a string mode.

	+ input.c (kbd_reply):  Conditionally compile call to
	  popdown_completions() based upon how OPT_POPUPCHOICE is defined.

	+ bind.c (fill_partial): Unconditionally call TTflush() since it is
	  needed to force the partial completion to be written out.

	  (kbd_complete): Changed logic yet again regarding the use of
	  cmplcol.  It is only used for scrolling now.  The completion
	  list is automatically displayed if no progress was made in
	  performing the completion.  This means that _something_ will
	  happen visually when you press tab.  Either the completion will
	  be wholly or partially successful, or the completion list will
	  pop up.

	+ filec.c (trailing_slash): Fixed problem (for unix systems at least)
	  where we were unable to get completions off of "/".

	+ filec.c (pathcmp): Wrote a simpler, faster, but possibly less
	  functional version.  Tom should look this code over to make sure
	  that I haven't broken something.  This new version seems to speed
	  things up quite a bit.

	  (makeMyList): This now takes as a parameter the name which is being
	  searched for.  We exclude from the list constructed those pathnames
	  which are in subdirectories below the directory in which name might
	  be found.

	  (bs_find): Took out calls which make copy of the pathname and
	  lengthened it.  If everything is done right prior to calling
	  bs_find, it should already be in canonical form.  I'm hoping
	  that this will increase the speed somewhat.

	  (makeString): Added length parameter in order to avoid calling
	  strlen.  Fixed all callers.

	  (makeString): Allocate an extra byte to be used as a directory
	  scan indicator.

	  (already_scanned): Use the scan indicator byte to see if directory
	  has already been scanned.  This should avoid rescanning directories
	  and it also fixes the problem of being unable to get completions
	  for directories which have already had a subdirectory scanned.
	  Scenario...	
	  	:set dirc
	  	:e /home/kev/GNU/
		Backspace so that just /home/ is showing.  Press .
		Type in kev/.  Only completion shown is GNU/.

	  (bs_init): Removed the flag parameter which indicates whether or
	  not to clear the buffer.

	  (bs_find): Removed the iflag parameter and fixed all callers.

	+ proto.h (bs_find): Nuke iflag parameter in declaration.

	  (bs_init): Removed flag parameter from declaration.

	+ bind.c (scroll_completions): New function called from kbd_complete.
	  
	  (cmplcol): Changed the way in which this variable is used 
	  for deciding whether to show or scroll a completion list.

	+ window.c (newlength): Fixed the off-by-one errors which were
	  causing xvile to exit with the X error "BadValue" for opcode
	  X_ConfigureWindow.  What was happening was the bottom window was
	  being left with size zero...this bug may be observed in ordinary
	  vile (in an xterm) by starting vile, splitting the [unnamed]
	  window and resizing the bottom window to one line.  Then use the
	  (X) window manager to resize the xterm window down in size by one
	  line.  You will then observe that there are two mode lines at the
	  bottom of the xterm one above the other with no buffer displayed
	  for the bottom-most one.

	+ window.c (wpopup): Don't let an error message be displayed when
	  we can't split a window.  Also permit curwp to be used if it's
	  the only window available.

	+ proto.h, buffer.c (zotwp): Moved delcaration from latter to former.
	  Also removed "static" from definition of zotwp in buffer.c.
	 
	+ input.c (kbd_reply): Call popdown_completions() to get rid of
	  the [Completions] buffer.

	+ bind.c (popdown_completions): New function for getting rid of
	  the [Completions] buffer.

	+ buffer.c (zotwp): Switch back to most recent buffer on buffer
	  list after deleting windows for the selected buffer.

	+ proto.h (shrinkwrap, popdown_completions): Declared these
	  functions.

	+ bind.c (show_completions): Call shrinkwrap() if completions buffer
	  is already popped and gets larger (in order to see as many
	  completions as possible).

	+ random.c (liststuff): Only call shrinkwrap() if buffer not already
	  popped up.

	+ x11.c (x_open): Don't call setpgrp() on bsd compat systems.  Also
	  added comment explaining why.

	+ random.c (liststuff): Call shrinkwrap().

	+ window.c (shrinkwrap): New function.

	+ bind.c (makecmpllist): Fixed line of code which was causing
	  completion list to be truncated.

	+ display.c (imworking): Took out the #if 0 which I used to remove
	  the two lines which I suspected of causing portions of the
	  "working..." message to hang around afterwards.  Instead, I
	  supplemented the test used to change the column to erase at.
	  It now checks to see if the message line is being read.

	+ bind.c (makecmpllist): Print completions sorted by column rather
	  than by row.

	+ bind.c (makecmpllist, show_completions): New functions.
	  
	  (GNU_COMPLETIONS): New feature test indicating GNU readline style
	  completions.  Define this to be 0 to get the old vile behavior.

	  (fill_partial): Don't beep when GNU_COMPLETIONS is enabled.

	  (cmplcol): New static global variable.

	  (kbd_unquery): Adjust cmplcol.

	  (kbd_complete): Adjusted logic to handle GNU readline style
	  completions.

	+ configure.in (AC_PID_T): Call this macro to make sure that pid_t
	  will be defined.

	  (CFLAGS): Only use -Wall when the --with-warnings option is used.
	  Otherwise, we get too many warnings due to missing extern decls.

	+ x11.c (display_cursor, x_preparse_args): Added casts in calls to
	  XtAppAddTimeOut and XtAddEventHandler which were causing warnings.

	+ configure.in (setpgrp, setsid): Check to see if these are missing
	  extern declarations.

	+ proto.h (setpgrp, setsid): Added prototypes.

	+ configure.in (setsid): Check for existence of this function. 
	  Also added comment about VC_SETPGRP being called by VC_KILLPG.

	+ x11.c (x_open): Call either setsid() or setpgrp() to break
	  association with controlling terminal.  This will prevent signals
	  from being sent back to the starting process.  I'm hoping that
	  this will fix problems reported concerning xvile crashing the X
	  server when control-C is pressed.  (I have never experienced this
	  problem).

	+ display.c (imworking): Removed (via #if 0) the two lines which
	  I suspect are causing portions of the "working..." message to
	  hang around afterwards.

	+ estruct.h (signal_pg): Tightened up conditions by which we will
	  permit getpgrp() to be called with no argument.  We still need
	  to design an autoconf test for this.  The more permisive conditions
	  were causing getpgrp() to be called improperly on SunOS. This
	  in turn made it impossible to use Ctrl-C in xvile to interrupt
	  lengthy processing.

	+ x11.c (x_set_watch_cursor): New function called from x_working()
	  and x_getc().  Also added field curs_watch to the TextWindowRec
	  structure.
	  
	  (x_working): Ignore certain types of events which could cause
	  us problem with reentrancy.  Other types of events are saved
	  in a queue for later processing.

	  (struct eventqueue, evqhead, evqtail): Declared saved event
	  queue structure and variables pointing to front and rear of
	  this queue.

	  (evqempty, evqadd, evqdel): New procedures for manipulating the
	  queue of events which must be processed, but not from x_working.

	  Note!!!  Not all of our reentrancy problems are solved.  The new
	  code which I wrote for saving events in a queue for later
	  processing calls malloc().  If it should happen that the
	  interrupt which got us into x_working() interrupted a malloc() in
	  progress, the results could be disastrous if malloc() is
	  non-reentrant.  So far as I know, most implementations of
	  malloc() are not reentrant.  malloc() is not the only call which
	  might get us into trouble.  Other library calls (particularly the
	  X11 and X toolkit functions) may well invoke malloc() or some
	  other non-reentrant library call.  The proper way (though not
	  easy) to implement all of this is to split imworking() up into
	  two parts; the signal handler and a display function.  The signal
	  handler will do very little; it will examine the state of a few
	  other flags (which already exist to implement the current version
	  of imworking) and then set the flag which will be examined by the
	  display function.  The display function is not invoked from the
	  signal handler.  It is called from various points in vile at
	  which it is possible to be in a lengthy process.  A good
	  candidate would be to call it from interrupted() as it is already
	  used for this purpose.

	+ estruct.h (sys/time.h, time.h): Moved includes for these files
	  ahead of include of sys/resource.h.  SunOS needs to have struct
	  timeval declared prior to including resource.h.  I'm beginning
	  to think that it might be better to nuke the include of
	  sys/resource.h and nuke the AC_AIX line from configure.in.

	+ configure.in (AC_HAVE_HEADERS): Added check for sys/resource.h,
	  which appears to be necessary to include prior to sys/wait.h in
	  order to keep gcc-2.6.0 from complaining on AIX.  It first appeared
	  that sys/m_wait.h in order to get union wait, but I believe the
	  bug to be in the "fixed" include files.

	+ estruct.h (sys/resource.h): Include prior to wait.h.

	+ makefile.in ($(TARGET)): Changed order of LIBS and X_EXTRA_LIBS in
	  link line.  X_EXTRA_LIBS now comes after LIBS.

	+ mktbls.c (main): Moved initialization of "section" to after the
	  call to setjmp() in order to avoid gcc warning.

	+ proto.h (fputs): Added declaration.

	+ configure.in (Makefile): Test for the presence Makefile instead of
	  makefile after calling xmkmf.  xmkmf creates Makefile, not
	  makefile.  This was preventing X_CFLAGS from getting set properly.

	  (with_warnings): Call AC_WITH to set this value.  We shouldn't
	  assume that autoconf will create a configure script which will
	  automatically create/set this variable.

	  (VC_MISSING_EXTERN): Split checks into two parts, one which is
	  enabled with --with-warnings (for type checking purposes), the
	  other which is mandatory.  This should speed up the configuration
	  process for non-developers.

	+ display.c (CLEAR_PLINE): Make sure that attributes get cleared too.

	+ x11.c (update_scrollbar_sizes -- NO_WIDGETS version): Created a
	  separate loop for drawing the new scrollbars which occurs after
	  the sizes have been changed.  Otherwise, the scrollbars don't always
	  properly update due to a lower bar covering an upper bar up prior
	  to being resized.

	+ x11.c (exposed): New field in TextWindowRec.
	  (x_preparse_args): Initialize cur_win->exposed.
	  (x_process_event): Set cur_win->exposed to true when an Expose event
	  is received.
	  (x_flush): Return immediately if no Expose events have been
	  received.  The reason for all of this is to prevent drawing to the
	  window prior to the display server being ready for us to send the
	  stuff.
	  (x_touch): Make sure the cell has something in it before marking it
	  as dirty.  The reason for this is that x_touch is called most of
	  the time to refresh a region of the screen which is clear (set
	  to the background color).   I'll handle the other cases by making
	  sure that the required area is clear...
	  (x_scroll): Don't call XFlush() unless visibility is partially
	  obscured.
	  (x_scroll): Call XClearArea() to clear area vacated by scrolling.
	  Should be faster because we won't have to clear portions of each
	  line individually.
	  (x_setfont): Added call to XClearWindow() before calls to x_touch().
	  (x_preparse_args): Use ButtonMotionMask instead of PointerMotionMask
	  when focus_follows_mouse is false.  Otherwise, too many motion events
	  are generated when moving the mouse through the vile window.  Folks
	  who want focus_follows_mouse will just have to live with the extra
	  motion events for the time being.

	+ display.c (CLEAR_PLINE): Don't mark cells in cleared line as dirty.

	+ select.c (pop_fake_win): fixed typo in comment.

	+ buffer.c (update_on_chg): Call b_is_temporary() instead of
	  b_is_invisible().  This matches the logic found in makebufflist().
	  (makebufflist):  Call update_on_chg() macro in order to help prevent
	  future inconsistencies.

	+ window.c (set_curwp):  Added a check at the beginning of the
	  function to return immediately if curwp is already set to the
	  window pointer to change to.  Among other things, this will 
	  avoid calling updatelistbuffers() which was responsible for
	  preventing us from being able to select (via the mouse) from
	  the [Buffer List] window.

	+ x11.c (modeline_resources, selection_resources): New array
	  which describes resources for modelines and selections.
	  (x_preparse_args): Get subresources for the modelines and
	  selections.
	  (modeline_fg, modeline_bg, modeline_focus_fg, modeline_focus_bg,
	  selection_fg, selection_bg): New fields in TextWindowRec.

	+ x11.c (char_descent): New field in TextWindowRec.
	  (query_font): Set char_descent field.
	  (flush_line): Use char_descent for determining where to write out
	  underlines.  This fixes a bug in which spurious underlines were
	  left around on the screen when displaying certain fonts.

	+ x11.c (scrollbar_resources): New array describing certain scrollbar
	  resources.
	  (cur_win_rec): Statically allocated TextWindowRec.  cur_win is
	  also statically initialized to point at this structure.  Needed by
	  scrollbar_resources in order to make the default foreground and
	  background for the scrollbars be the same as the already determined
	  foreground and background for the rest of the application.
	  (x_preparse_args): Get scrollbar subresources and use these as
	  appropriate in creating the scrollbar graphics context.
	  (x_preparse_args): Make sure that background and foreground pixel
	  values are different.  They can start out different in the resource
	  file, but get mapped to the same values on monochrome displays.

	+ region.c (yank_line): New code to yank the newline (if appropriate).
	  Used when yanking mouse selections.

	+ basic.c (setwmark): Don't permit dot to be set past end-of-buffer.
	  (setcursor): Removed comment saying that position may be set past
	  end-of-buffer.

	+ vile.hlp: Corrected some minor typos.

	+ display.c (hilite): Mark the vscreen row as changed when changing
	  the attributes in the OPT_VIDEO_ATTRS portion of this code.

	+ x11.c (x_preparse_args): Use 1 and 0 as the foreground and background
	  pixel values in the call to XCreatePixmapFromBitmapData().  I think
	  that this make sense since the depth is one.

(tom)
	+ autoconf-macro VC_SIZE_T fixes problem with size_t on CLIX and Ultrix
	  (aclocal.m4, configure.in).

	+ added autoconf tests for poll.h, setjmp.h (configure.in)

	+ some lint and compiler warnings/errors for SunOS, CLIX, IRIX (eval.c,
	  region.c, tags.c, version.c, x11.c

	+ make IBMPC the default driver for MSDOS (estruct.h)

	+ supplied definition for VMS to make ScratchName work (estruct.h)

	+ "#error" doesn't work on SunOS; changed this to "error" (estruct.h)

	+ corrected autoconf ifdef'ing of getwd/getcwd (estruct.h)

	+ corrected lint rule in makefile.in

	+ removed /Debug option when compiling vile on VMS (descrip.mms).

	+ corrected logic of 'is_vms_pathname()' to handle the case of rooted
	  logicals, e.g., "dev:[foo.][bar]name" (path.c).

	+ corrected error on VMS which left terminal in wrong state when
	  closing terminal (termio.c).

	+ corrected 'resolve_filename()'; the call to update the status line
	  had gotten lost somehow (file.c).

	+ ifdef'd 'get_modtime()' to handle VAX C's backwards treatment of the
	  st_mtime/st_ctime members of stat structure (file.c).

	+ commented-out X-Window libraries in VMS link options file
	  (vms_link.opt); (these should be autoconfigured :-)

	+ minor cleanup of directory scanning code for NT (path.c).

	+ modified kev's GNU choices to implement the "popup-choices" mode
	  (modetbl, bind.c, main.c).

	+ modified (for UNIX) the behavior of 'filter-buffer' so that filter
	  commands with pipes work (i.e., ":filter-buffer sort|uniq") (spawn.c).

	+ changed the yank-til command to use the same limits as delete-til, so
	  that "yW" will yank trailing spaces of a word (opers.c).

	+ implemented mode "popup-msgs" with new file 'msgs.c'.  This is mainly
	  useful in debugging macros; it forces a buffer [Messages] to be
	  popped up when multiple messages are generated by a single command. 
	  (display.c, main.c, msgs.c, estruct.h, modetbl, also makefile.* and
	  vms_link.opt).

	+ added mode 'errorbells' to control whether vile beeps (or flashes) at
	  all.  This relies on intercepting the TTbeep calls, which are all
	  done within 'kbd_alarm()' (mostly via 'mlwarn()') now (bind.c,
	  display.c, exec.c, fences.c, input.c, isearch.c, main.c, modes.c, opers.c,
	  search.c, undo.c, window.c).

Changes for vile 4.6 (unreleased Tue July 12, 1994)
(pgf)
	+ changed authorship in README, added credits in vile.hlp

	+ applied further OS/2 patches from Charles Moschel

	+ applied Windows/NT patches from Joe Greer.  don't get excited.
	  it's just console support.  :-)

	+ added admin targets to makefile.in.  these are all (?) useful
	  directly, with "make -f makefile.in ..." since they don't depend
	  on any of the config variables.

	+ minor wording changes to README.CONFIG and INSTALL.

    	+ eliminated global variable "slash", renamed macro "slashc()" to
	  "is_slashc()", use new define SLASHC in place of "slash".

	+ did a lot of hand merging of NT and WIN31 ifdefs (since they
	  both affected most of the same lines.   this note is really just
	  a heads-up, in case i missed/broke something.

	+ re-renamed manpage.vmc to manpage.rc, to avoid introducing yet
	  another file suffix.  changed CHANGES and vile.hlp to match.

	+ eliminated makefile.sav from the distribution.

	+ eliminated all "Log" keywords, added "Header" keywords everywhere.

(kev)
	+ manfilt.c (sys/types.h): Include this file so that size_t will be
	  defined on certain systems.

	+ x11.c (alternate_font): Added cast to second arg in call to
	  castalloc to avoid conversion warning.

	+ configure.in (fputs): Added this function to the missing check
	  list.  Not needed for vile, but for manfilt.c.

	+ manfilt.c: Converted from ANSI C to the style of C in which the
	  rest of vile is written in.

	+ buffer.c (makebufflist): Added cast to convert return value of
	  strlen to SIZE_T.

	+ filec.c (fillMyBuff): Added cast to second arg in call to bs_find().
	  Some platforms declare strlen to return int instead of size_t.

	+ estruct.h (realloc): Changed prototype declaration so that second
	  arg is unsigned.

	+ estruct.h, mktbls.c (malloc): Changed extern declaration so that
	  first parameter is an unsigned int rather than just int.  This
	  eliminates "conversion" warnings on some systems.

	+ mktbls.c (free): Added extern declaration with prototype.

	+ x11.c (estruct.h, edef.h): Moved includes of these files to before
	  the X11 includes.  I was having trouble on an SVR3 system in which
	  flock was getting declared twice.  It turns out that 
	  (which is included from  does a check to prevent
	  fcntl.h (from which flock is ultimately defined) from being
	  included twice.  In my opinion, the authors of the system include
	  files for this SVR3 system didn't do their job very well.  Rather
	  than propagate checks to see if a particular system include file
	  has already been included into estruct.h, I figured that a slight
	  reordering (in x11.c) would be better.  Let's just hope it doesn't
	  break something else.

	+ estruct.h (MISSING_EXTERN_REALLOC): Fixed my misspelling of this
	  (lack of) feature test.

	+ mktbls.c: Conditionally include config.h in order to use
	  configuration parameters for Unix systems.  Non-unix systems
	  should still compile as they did before (if I didn't botch
	  something).  I was having trouble with the fprintf extern on
	  certain systems.

	+ makefile.in (MKTBLS): Use CPPFLAGS to build the mktbls program.
	  This will cause HAVE_CONFIG_H to be defined.

	+ README.CFG: New file which describes the configuration process as it
	  relates to (x)vile.  I recommend changing the name of README to NEWS
	  and README.CFG to README to be more consistent with FSF software. 
	  I'll leave this up to Paul though.

	+ README (impatient?):  Changed message slightly.

	+ makefile.in (install, installdirs, uninstall, makefile,
	  config.status, mostlyclean, clean, distclean, realclean, TAGS,
	  tags, dist): These targets added or modified to conform to the
	  GNU standards document.

	+ mkdirs.sh, INSTALL, install.sh: New files copied from the GNU
	  autoconf distribution (mkdirs.sh renamed from mkinstalldirs
	  to simplify copying files to/from MS-DOS -- tom).

	+ config_h.in:  Renamed from config.d.in.  I really wish I could
	  use autoheader to generate config.h.in as the autoconf doc
	  describes.  Unfortunately, it isn't powerful enough (without
	  some rewriting) to do what I want.

	+ aclocal.m4 (VC_SETPGRP): New vile configuration macro.

	+ line.c (ksetup): Initialize kcharpending.  This lack of
	  initialization was responsible for the bug in which a newline was
	  sometimes being inserted before a yanked region when it shouldn't
	  have been.  Also moved definition of kcharpending so that it appears
	  prior to the definition of ksetup().  The bug may be observed as
	  follows: Create a buffer with a single line containing the
	  characters "foo".  Enter the command ":list-registers" in order to
	  view the registers.  Go back to the beginning of the newly created
	  buffer (containing "foo").  Type "yw".  "foo" will appear as the
	  unnamed register.  Type "yw" again.  The unnamed register will now
	  (prior to this fix) have the "foo", but also a newline in front of
	  it.

	+ configure.in (tcgetattr): Test to see if this function exists.

	+ termio.c (HAVE_TCGETATTR): Added this test to see whether or
	  not to define USE_POSIX_TERMIOS.  Also added commentary describing
	  reason for this.

	+ x11.c (x_flush): Removed all explicit calls to this function.  It
	  was being called after update() which is unnecessary since
	  update (indirectly) calls x_flush().  Calls to update() now
	  pass the force argument (the only argument) as TRUE to ensure
	  that the update will not be deferred due to type-ahead.
	  (resize_bar): Removed code for determining vertical positioning
	  involving XQueryPointer() and/or XTranslateCoordiates.  With a
	  little bit of care, we can get the vertical position accurately
	  without making a round trip server request.

	+ x11.c (repeat_scroll): Added call to XSync() in order to make sure
	  that repeated scrolling (via the timer) doesn't get ahead of display
	  of the scrolling. 
	  (resize_bar): Ifdef'd to try out XTranslateCoordinates() in place
	  of XQueryPointer().  This should work better since it will give
	  us the coordinates of the pointer at the time of the event instead
	  of the current pointer value.

	+ x11.c (visibility):  New field in struct _text_win.
	  (wait_for_scroll): Do not call x_flush().  Return only when
	  we're sure that all contiguous GraphicsExpose events have been
	  processed.  This code was previously returning after the first one.
	  (x_scroll, x_flush): Return immediately if window is fully obscured.
	  (x_scroll): Don't wait for the scroll if the window is unobscured.
	  (x_preparse_args): Initialize visibility.  Initialize
	  graphics_exposures field of cur_win->textgc.
	  (x_process_event): Added new case for VisibilityNotify which note
	  changes in the visibility of the window and modify cur_win->textgc
	  accordingly.

	+ x11.c (ISC):  Removed #undef of ISC.  Should not be necessary
	  any longer.
	  (X_PIXEL): Removed #define.  Not used anywhere.
	  (NPAUSE): Nuked.  Not needed.  Replace occurrence in term structure
	  with zero.  (This was supposedly the number of times to busy loop
	  in the catnap routine.
	+ x11.c (x_preparse_args):  Support for left scrollbars in OpenLook
	  added.
	+ basic.c, csrch.c (setnmmark, getnmmarkname, get_csrch_char): Changed
	  name of "stat" variable to "status" in order to avoid shadowing the
	  stat function.  This didn't actually cause any problem, it just
	  makes gcc shut up when used with Tom's preferred set of switches.
	+ proto.h (setvbuf): Prototype.
	+ display.c (updateline):  In OPT_PSCREEN version, return immediately
	  if v_flag for the row doesn't have VFCHG set.
	  (psc_putchar, psc_eeol): Set VFCHG flag on proper row.
	+ termio.c (ttputc, ttflush, ttgetc): Don't define these for X11.
	  Also got rid of calls to setbuffer, etc for X11.
	+ proto.h (getscreensize): Declare even when SIGWINCH is not
	  defined.
	+ estruct.h (malloc, realloc): Prototypes.
	+ main.c, fileio.c (fcntl.h): Removed include from here.  estruct.h
	  now includes it.
	+ estruct.h (time.h):  Included here.  Don't include both time.h
	  and sys/time.h if they conflict with each other.
	+ version.c: Removed include of time.h.
	+ proto.h: Reorganized prototypes for system calls to use the
	  MISSING_ test to determine whether an extern declaration needs
	  to be made.
	+ estruct.h (libc.h): Include this file (NeXT has hundreds of
	  prototypes declared here).
	+ termio.c (LINUX): Nuked ifdefs surrounding calls to tcdrain().
	+ estruct.h, random.c (sys/select.h): Moved inclusion of
	  sys/select.h from random.c to estruct.h (so that any types
	  declared in sys/select.h will be available for later inclusion of
	  proto.h).
	+ estruct.h (AUX2, AIX, OSF1, LINUX, V7, BSD386, UNIXPC): Eliminated.
	+ eval.c (AUX2, pyr, AIX):  Replaced in #if with
	  HAVE_LOSING_SWITCH_WITH_STRUCTURE_OFFSET.  I'm open to suggestions
	  on a better name for this.
	+ proto.h, estruct.h (fcntl.h, sys/wait.h):  Included from estruct.h
	  instead of proto.h.
	+ npopen.c (sys/wait.h): Removed include from this file.

	+ x11.c (start_selection):  Yank selection prior to releasing selection
	  when persistent_selections are disabled.
	  (x_process_event): Check to see if multiclick time has expired prior
	  to discarding motion event when cur_win->numclicks is greater than
	  one.  (If it's expired, we don't want to discard the event).

	+ display.c, termio.c (getscreensize): Moved from display.c to
	  termio.c.  This is a better place for it since we are invoking
	  ioctl.  (This also explains why it was necessary to include
	  the termios / termio / sgtty stuff in display.c.)
	+ estruct.h (SVR3, ODT, ISC, HPUX): Eliminated.
	+ termio.c (ttopen): Changed preprocessor feature test for
	  call to setvbuf.  Also added code to handle systems (old
	  SVR3 systems) which have the second and third arguments to
	  setvbuf reversed.
	+ main.c (catchintr): Always reinstate the signal handler regardless
	  of system.  The code should probably be revisited...
	+ spawn.c (rtfrmshell): Ditto.
	+ estruct.h (USE_BCOPY): Usage eliminated as it was never being defined
	  anywhere.
	  (SYSV_STRINGS): Eliminated since it was defined, but never
	  referenced.
	  (strings.h, memory.h): Included as per GNU recommendations.
	  (ULTRIX): Removed references to this unix variant.
	+ random.c (current_directory): Eliminated reference to POSIX and
	  reorganized preprocessor tests for how to get the current directory
	  a little bit.
	+ fileio.c: Eliminated reference to BERK.
	+ termio.c: Eliminated reference to BERK and other unix varieties.
	  We now use HAVE_TERMIOS_H, and company.  I also eliminated code
	  specific to OSF1.  If there's a problem with it, we should try
	  to deal with it elsewhere (such as the configuration script).
	+ dirstuff.h:  Added stuff for including obscure readdir headers.
	  Eliminated reference to BERK.
	+ estruct.h (SIGT): Wrapped an ifndef around the logic that defines
	  SIGT and SIGRET since they will be determined by the configuration
	  script.  Also removed tests for various specific varieties of UNIX
	  from this logic. 
	  (HAVE_SELECT, HAVE_POLL): Removed preprocessor logic for both of
	  these.  The configuration script now determines which of these
	  are available.  We do undef HAVE_POLL if HAVE_SELECT is defined
	  however.
	  (USE_INDEX, HAVE_GETHOSTNAME, signal_pg): Changed preprocessor logic.
	  (BERK): Eliminated all occurrences.
	+ display.c (termios.h, termio.h, sys/ioctl.h, ioctl.h, sys/types.h
	  sys/stream.h, sys/ptem.h):  Removed includes and ifdef logic
	  connected with these header files.  They don't appear to be used
	  anywhere in display.c (though I have no doubt that they were at
	  one time).
	+ makefile.in:  New file; a template for creating the makefile.  This
	  file was created by hacking the old makefile.
	+ configure.in:  New file for creating the configure script.
	+ config.d:  Template file for creating config.h.

(tom)
	+ modified 'mktbls' so it can be used as a function in a Windows 3.1
	  application (e.g., fixed memory leaks, top-level return).

	+ built with kevin's autoconf script on Linux (both termcap and
	  Xt versions), adjusted/corrected various files for autoconf and for
	  MSDOS filename compatibility (aclocal.m4, bind.c, cmdtbl
	  configure.in, edef.h, epath.h, estruct.h, file.c, fileio.c, glob.c,
	  ibmpc.c main.c, makefile.in, makefile.tbc, map.c, mktbls.c, npopen.c,
	  path.c proto.h, random.c, spawn.c, termio.c, x11.c).

	+ made a driver-stub for Windows 3.1, to get a clean compile/link.

	+ corrected 'ibmscroll()' function, which was broken in vile 4.4
	  (ibmpc.c).

	+ corrected reopening of stdin when a file is piped to vile; on Linux
	  this caused vile to hang (main.c).

	+ moved include of estruct.h after X Window includes in x11.c, since
	  the definition of VMS causes the compile to break otherwise.

	+ added new (some incomplete) files for Windows 3.1 port, map command
	  and debugging: commdlg.msg mapchars.c mapchars.h trace.c trace.h
	  win31drv.c win31drv.def win31tbl.c win31tbl.def win31tbl.h
	  win31tbl.rc

	+ modified 'gtfun()' and 'sindex()' to use single return points, to
	  ease debugging.

	+ added/used new macro 'window_b_val()' to handle the cases in which we
	  reference a mode value for the current window, e.g., when executing a
	  macro (estruct.h, isearch.c, oneliner.c).

	+ initialize VIDEO-struct in 'vtinit()' that Purify found (display.c).

	+ corrected globbing logic so that expressions such as `which script`
	  work properly when the glob mode is "on" (glob.c).

	+ added autoconf test VC_CPP_SUBS to make the ScratchName macro port.

	+ corrected :-command parsing so that repeated ":" at the beginning of
	  the line is ignored (exec.c).

	+ reset mouse position when changing the screen resolution to avoid
	  confusing users about its visibility (ibmpc.c).

Changes for vile 4.5 (released Wed Apr 27, 1994)
(pgf)
	+ backed out change to "set all" which switched to Settings buffer.
	  it didn't work, and was confusing in any case.  (modes.c)

	+ redid the variables that identify os and vile variant.  now the
	  $progname variable says "vile" or "xvile", and the new $os variable
	  says "unix", "dos", "vms", or "os/2".  (modetbl, eval.c, version.c,
	  proto.h, main.c, edef.h, vile.hlp, macros.doc)

(kev)
	+ vile.hlp: Documented manual page stuff.

Changes for vile 4.4 (not released April 26, 1994)
(pgf)
	+ fix for ": & 1" in empty buffer.  (exec.c)

	+ ensure that problems opening a file are correctly reported
	  at startup, by giving swbuffer() a real return value.  nextbuffer()
	  returns this, which lets main() do the right thing.  i hope
	  letting swbuffer() return readin() errors doesn't have too large
	  a ripple effect.  we'll see.  the return from swbuffer() is ignored
	  in many cases anyway.  (buffer.c, main.c)

	+ on file open errors in readin, continue with the routine, so the
	  buffer gets set up correctly.  cmode was wrong before, for instance.
	  (file.c)

	+ added select operator (bound to ^S) to do selections.  it yanks
	  by default.  (region.c, opers.c, cmdtbl, select.c)

	+ implement support (via new arg to scwrite, not yet put into other
	  "screens" that provide this routine) for OPT_VIDEO_ATTRS under DOS.
	  (display,c, ibmpc.c, proto.h)

	+ removed KBD_LOWERC from the DOS KBD_OPTIONS, as an experiment, even
	  thought tom told me not to.  i've seen no ill effects so far. 
	  there must be something, though...  (could this be compiler
	  (well, libc) dependent?) (filec.c)

	+ added proper dependencies to makefile.wat

	+ recalc kregwidth on last call to kinsertlater, since we may
	  never get a newline to force it.  (line.c)

	+ added mode "view-on-readonly" which causes view mode to be set
	  if file is read-only on first open. (modetbl, file.c, vile.hlp)

	+ implemented sel_motion() routine, that allows referencing the
	  selected region from an operator.  fixed various off-by-one
	  nits in various places to make this work right.  (basic.c,
	  opers.c, region.c, select.c, proto.h, cmdtbl, x11.c)

	+ cleaned up beeping.  too many double beeps.  (file.c, fileio.c,
	  basic.c)

	+ now preserve DOT during yank operations, so yy and Y don't cause
	  motion. (opers.c)

	+ added "haveregion" backdoor to getregion() -- if the "haveregion"
	  pointer is set, getregion just returns it as the region. see
	  select.c for uses of this.  (region.c)

	+ added #error statement to little/dis-used screen drivers, to
	  find out which are really used. (at386.c, hp110.c, st520.c,
	  z100bios.asm, z_ibmpc.c, dg10.c, hp150.c, vt52.c, z309.c)

	+ function lookup is now first match, rather than exact, to match
	  documentation.  (eval.c)

	+ fix core dump from referencing empty line for macro label goto.
	  (exec.c)

	+ eliminated unimplemented "target" variable. (modetbl)

	+ created doc for programmed macros, based on uemacs 3.10 doc.
	  (macros.doc, makefile)

	+ check all getregion() return values. (word.c, select.c)

	+ moved operselect() to select.c from opers.c.

	+ reset haveregion after use in getregion().  (region.c)

	+ sel_motion and operselect, if now used together in a single
	  command, can be used to extend a keyboard selection. (select.c)

	+ giving any argument to "shell-command" or ":!" now suppresses
	  the press-return prompt. (spawn.c, proto.h)

	+ added calls to update() if screen is garbage in mlyesno and
	  mlquickask, in case they are called after a shell-escape from
	  a macro. (input.c)

	+ fixed cursor position after ^B command (should rest at bottom
	  of window) (basic.c)

	+ fix ordering of kdone/kinsertlater stuff (kcharpending was being
	  reset by kdone called from kinsert) to fix problem where a yank
	  containing an initial blankline would not record that blank line.
	  (line.c)

	+ changed kcod2str, fnc2str, string2prc to deal in "p-strings", i.e.
	  binary strings with length stored in first byte.  needed this so
	  bindings involving null character could pass through everywhere.
	  the :map code in map.c still has problems.  (bind.c, x11.c,
	  x11simp.c, input.c, map.c, proto.h)

	+ separate target for Sony NeWS -- for sys/ioctl.h problem (makefile,
	  termio.c)

	+ patch from Michael Finken, to allow keeping the buffer name in
	  the window and icon names (x11.c, display.c, proto.h, vile.hlp)

	+ tungetc() now pushes back 16 bit keycodes using kcod2escape_seq()
	  to translate them to a user-typable sequence, and maintaining a
	  stack of pushed back chars.  it should still only be used for
	  one key's worth of pushback.  (input.c, some others?)

	+ insert mode now encodes SPEC keys (when recording them) as poundc
	  followed by poundc+1 followed by c.  real poundc chars are stored
	  as poundc followed by poundc.  there is no more "altpoundc".
	  (insert.c)

	+ merged OS/2 patches from Charles Moschel (ccm@cais.com).  reworked
	  them somewhat to use better ifdefs in many cases.   This touched
	  a lot of files.

	+ introduced routine strncpy0() which jams a '\0' into the last
	  copyable byte.  changed several of the most bug possibilities
	  to use it.  (bind.c display.c eval.c finderr.c input.c isearch.c
	  main.c makefile proto.h tags.c)

	+ eliminated #elif from x11.c, for HP users.

	+ reworked Charles Moschel's os2 screen driver into a "borland"
	  console i/o driver.  i can't test it on OS/2, but i think it's
	  the equivalent of his.  now there are separate ifdefs to control
		which os we want		MSDOS or OS2
		the pc keyboard			IBM_KBD
	  	the physical screen driver	IBMPC
		the console i/o driver		BORLAND
	  the Borland compiler is still represented with "TURBO", since
	  that's still predefined in Borland C++.
	  (borland.c edef.h estruct.h ibmpc.c main.c makefile.tbc spawn.c
	  termio.c version.c)

	+ split routine execproc() in two, to make it internally callable,
	  given the name of the procedure to run. (exec.c, proto.h)

	+ added cdhook variable, which is the name of a procedure which
	  is run when changing current directory.  (edef.h eval.c
	  exec.c modetbl proto.h random.c)

	+ added variable $ocwd, the previous directory (modetbl, eval.c,
	  random.c, proto.h)

	+ backed out changes that implemented the "keep buffer name in window
	  and icon title" resources.  this is better done with hooks. (x11.c,
	  proto.h, display,c, vile.hlp)

	+ apply patch from richard hussong to fix scrolling problem on some
	  video bios'es (ati ultra pro) (ibmpc.c)

	+ added more hook variables: read-hook, write-hook, buffer-hook,
	  exit-hook.  modified help file to describe procedures, and hooks.

	+ added new variable, $abufname, which is the "alternate buffer",
	  i.e. what you'd get if you type '#'. (modetbl, eval.c, vile.hlp)

	+ apply fix to map_proc from lee johnson -- :map g G followed by
	  1g didn't work, since 1 was considered default. (map.c)

	+ change macros BAD and GOOD to BADEXIT and GOODEXIT to avoid
	  conflicts on AIX.  (display.c estruct.h file.c ibmpc.c main.c
	  mktbls.c spawn.c tcap.c termio.c version.c window.c x11.c
	  x11simp.c)

	+ it is now possible to use forward-char-scan et al from a macro.
	  (csrch.c)

	+ "response variables", the ones that ask questions (e.g. @foo)
	  now remember a default response.  (eval.c)

	+ added support for using the ansi.c screen driver under MSDOS.
	  (ansi.c, termio.c, estruct.h, makefile.wat)

	+ added w!  and x!  as synonyms for w and x, since they are the
	  same under vile.  (cmdtbl, vile.hlp)

	+ added support for new GNU libio stdio pkg, for isready_c() macro.
	  (fileio.c)

	+ fix globber() so :g/foo/p leaves you in the p-lines buffer, which
	  is probably where you want to be.  (globals.c)

	+ fix problem in main that caused us to skip first file if noautobuffer
	  was set.  (main.c)

	+ now that there are so many modes, it's desirable to switch
	  to the ":set all" ("show-modes") window when it pops up. (modes.c)

(tom)
	+ warning/lint cleanup (bind.c buffer.c display.c edef.h estruct.h
	  eval.c fences.c insert.c line.c proto.h random.c region.c select.c
	  tags.c x11.c)

(kev)
	+ select.c (EFFICIENCY_HACK, attribute_cntl_a_sequences):  New code
	  which makes attributing regions with large numbers of attributes
	  much more efficient.

	+ x11.c (CLEAR_THRESH): Changed value and added explanation.
	  (NONDIRTY_THRESH): New constant.
	  (x_getc): Added inner loop for getting as many X events as possible
	  prior to returning in order to let the typeahead check in update()
	  do its job.

	+ manfilt.c (fatal_error): New function.
	  (INITIALSIZE): New constant.  Got rid of old constants which
	  hardwired the buffer sizes.
	  (line_in_size, line_out_size): New variables for keeping track
	  of the buffer sizes.
	  (getline): Rewritten so that input lines may be of arbitrary
	  length.

	+ display.c (update): Keep track of original row and column in
	  case we're reading the message line.  If we are reading the
	  message line, update the hardware cursor to the original row
	  and column instead of the current window.  I think that this
	  problem was evident only when the OPT_PSCREEN feature was enabled.

	+ estruct.h (do_mark_iterate): Reassert ownership of selection if
	  appropriate.

	+ proto.h, select.c (sel_reassert_ownership): New function.
	  
	+ display.c (reframe):  Fixed an off-by-one error which was causing
	  the cursor to be placed on the mode line after a reframe in a
	  one line buffer.

	+ input.c (kbd_reply): Fixed off by one error which was causing core
	  dumps on the NeXT.

	+ x11.c (x_get_selection, copy_paste): Added caste for third argument
	  in calls to tb_bappend.
	 (alternate_font): Removed debugging printf.

	+ x11.c (x_configure_window): New code for unmanaging / managing
	  the children of a motif form which will hopefully prevent the
	  problems with huge scrollbars. 

	+ random.c (line_count): Added null buffer check.  This lack of
	  check was causing core dumps on start up in xvile when $font was
	  being set from the .vilerc file to a value which caused a resize.

	+ cmdtbl, proto.h, select.c (operattrital): New operator for italics.

	+ x11.c (x_setfont, query_font): Cleaned up memory leaks, one stemming
	  from the fact that the XFontStruct structure pointed at by
	  the pfont field was never getting freed, the other concerning
	  allocation of memory for font names.
	 (starting_fontname): New field in the TextWindow structure.  This
	  field points to the initially requested font name. The fontname
	  field is reserved for holding the name of the font once it has
	  been successfully loaded.
	 (query_font): Attempt to find the fully qualified font name (rather
	  than an alias or template).  Also, free storage associated with 
	  new fields in struct _text_win (see below).
	 (FSRCH_BOLD, FSRCH_ITAL, FSRCH_BOLDITAL): New flags.
	 (fsrch_flags, pfont_bold, pfont_ital, pfont_boldital, left_ink,
	  right_ink): New fields in struct _text_win.
	 (alternate_font): New function.
	 (flush_line): New code for handling bold and italics.  Old code for
	  doing bold retained as a fallback position in the event that a
	  bold font is unavailable.
	 (x_get_font_atom_property): New function.
	 (x_flush): New code for cleaning up the mess sometimes left when
	  using monospaced fonts. [Glyphs in monospaced fonts sometimes extend
	  outside the bounding box associated with the font.  Thus when
	  a dirty cell adjacent to a non-dirty cell is updated, the non-dirty
	  cell also needs to be updated in the event that the character
	  previously written to the dirty cell extended outside of its
	  bounding box and into the non-dirty cell.]

	+ window.c (delwp):  Always set WFHARD on the receiving window
	  (instead of just when the current window pointer is the same as
	  the one being deleted).  This corrects a problem with the mode
	  line attribute sometimes not getting reset. [Scenario: Edit a
	  file.  Split the window.  Type '*'.  Move to a different window
	  than the "*" window.  Type '*' again.  Both vile and xvile leave
	  the line that the message line used to be on bold.]

	+ macros.doc: Fixed some minor typos.

	+ select.c (extended_region): Added prototype.

	+ manfilt.pl: New file. Perl script for filtering backspace sequences.
	+ cmdtbl (operattrcaseq): Replaces operattrbsseq.
	+ proto.h, select.c  (attribute_cntl_a_sequences, operattrcaseq):
	  Replaces attribute_backspace_sequences and operattrbsseq.

	+ random.c (getcol): Now works for empty lines where offs > 0.  This
	  is probably one of many functions which will need to be fixed now
	  that it is possible to position the cursor on the newline character.
	  (See Paul's changes.)
	  
	+ file.c (getfile2): Don't prompt user if noninteractive.  This
	  change prevents an infinite loop when executing my manual page
	  macro (or any macro which needs needs a buffer where there is a
	  name conflict.  Paul and Tom should look at this to make sure that
	  it doesn't break keyboard macros.

	+ display.c (updattrs): Garbage collect attributes which should
	  display something (i.e., have nonzero ar_vattr field), but refer
	  to an empty region.

	+ display.c (updattrs): Added a parameter to this function and
	  changed call in update() to reflect this change.  Also moved
	  placment of call from within update.  The result of all of this is
	  that the attributes will only be updated only when WFHARD or
	  WFEDIT is set for the window.  WFEDIT is needed in order to
	  display changed boundaries of the attributed text in the event
	  that the marks denoting the ends are moved as the result of an
	  editing operation.

	+ estruct.h (do_mark_iterate): Rewritten to be faster.  This improved
	  performance a lot when there are a large number of attributes.
	  A terminfo man page took roughly 14 seconds to attribute prior to
	  this change.  Afterwards, it took about 8 seconds.  (The terminfo
	  man page is somewhat unusual in that it has a large number of
	  underline and bold sequences).

	+ cmdtbl (operattrbsseq): New command for attributing sequences of
	  backspaces.
	+ select.c, proto.h (attribute_backspace_sequences, operattrbsseq):
	  New functions.  Also moved together the prototype declarations of
	  functions defined in select.c to one place.

	+ display.c (modeline): if insertmode is defined (as a macro), display
	  the modeline for each modeline instead of just the current window.

	+ display.c (updattrs): Make sure that start_col is not less than
	  zero.

	+ exec.c (execute):  In test to see if we're not in insert mode...
	  Short circuit the test with a test to see if curwp is NULL since
	  we get in trouble when insertmode is not a global variable and
	  is defined in terms of a window trait (see estruct.h).  (We were
	  getting core dumps when starting up with xvile @manpage.rc).

	+ cmdtbl, opers.c (operattrbold, operattrul): New commands for
	  attributing regions of text.
	+ edef.h (videoattribute): New variable for communicating with
	  attributeregion().
	+ select.c, proto.h (attributeregion): New function.
	+ select.c (selectregion): Took out checks to see if startbufp and
	  selbufp are NULL before calling detach_attrib as detach_attrib
	  already performs these checks.
	+ display.c (updattrs): Use logical or to set attributes other
	  than VAREV in order to allow overlapping attributes.  Use
	  exclusive or to set VAREV causing overlapping reversed regions
	  to reverse themselves (this is perhaps _too_ tricky; we might
	  consider just using logical or.  It would simplify the code
	  and it might actually be what the user wants.)  Previously, we
	  were just using assignment to set the attribute which cause
	  the attribute displayed to be the last attribute processed.
	+ x11.c (flush_line, x_flush): Modified to handle bold and underline
	  attributes in addition to reverse video.  Some work still needs
	  to be done on this to use a bold font for displaying bold if
	  it exists with the present code as a fallback if there is no
	  bold font available.
	+ manpage.rc: New file containing vile macros for getting and
	  attributing manual pages.

	+ estruct.h (do_mark_iterate):  Fixed problem which was causing
	  r_orig for the first attribute to not get processed.  I think
	  that this was responsible for some core dumps.

	+ x11.c, proto.h (own_selection): New externally available function.
	  It used to be x_own_selection which was private to x11.c.  All
	  calls to x_own_selection in x11.c eliminated.
	+ estruct.h (OWN_SELECTION): Macro which will either call
	  own_selection() or do nothing depending on whether or not (x)vile
	  is compiled on a system which is prepared to share selections
	  with other clients or not.
	+ select.c (selectregion, sel_extend):  Call OWN_SELECTION().

	+ proto.h (sel_yank):  Name changed from sel_yankmaybe since there
	  is very little "maybe" left about its action.
	+ select.c (sel_yank, push_fake_win, pop_fake_win): sel_yankmaybe
	  rewritten to become sel_yank.  sel_yank now uses push_fake_win()
	  and pop_fake_win() to allocate a fake window so that the selection
	  in the selection buffer may be yanked no matter what (unless
	  there is no selection).
	+ x11.c (x_process_event, x_stash_selection): Call to sel_yankmaybe
	  eliminated from x_process_event.  Call to sel_yank added to
	  x_stash_selection.  This means that the selection will only be
	  yanked when needed thus permitting modification of the selection
	  prior to pasting.

	+ basic.c (setnmmark):  Nuked old keyboard selection code.
	+ select.c (WHICHEND, whichend): New type and variable for keeping
	  track of which end of the selection is fixed while sweeping
	  a selection.
	+ select.c (sel_begin): Set whichend.
	+ select.c (sel_extend):  Selection yanking code removed.  Usage
	  of parameter to sel_extend modified to indicate if wiping (sweeping)
	  with mouse.  Code added to check whichend and act accordingly.
	  Also do the "one-off" fixup here instead of in x11.c.
	+ select.c (output_selection_position_to_message_line): Fixed "one off"
	  error in reporting extent of selection.
	+ x11.c (x_preparse_args): Set foreground and background in 
	  scrollbar graphics context.
	+ x11.c (extend_selection): Changed call to sel_extend to reflect
	  new interpretation of its parameter.
	+ x11.c (multi_click): Put back decrement after end of word is
	  found.  (Paul had previously removed it.)
	+ x11.c (x_process_event):  Changed call to extend_selection
	  when button 3 is pressed to indicate that we are _not_ wiping.
	  (Wiping is permitted however and mouse motion will do the 
	  right thing).

	+ x11.c (pscreen): Added extern declaration.
	+ x11.c (IS_DIRTY_LINE, IS_DIRTY, IS_REVERSED, MARK_LINE_DIRTY,
	  MARK_CELL_DIRTY, CLEAR_LINE_DIRTY, CLEAR_CELL_DIRTY, CELL_TEXT,
	  CELL_ATTR): New macros comprising the interface to pscreen.
	  These could be moved to estruct.h or another header file for
	  use by other screen interfaces.
	+ x11.c (BLINK_TOGGLE): Added comment about this macro.
	+ x11.c (cur_row, cur_col, sc, cur_row, cur_col): Removed these
	  fields from the TextWindow structure.
	+ x11.c (x_putc, x_move, x_eeol, x_eeop, free_win_data,
	  x_resize_screen): Deleted these functions and changed all callers.
	+ x11.c (term): Substituted psc_putchar, psc_flush, psc_move,
	  psc_eeol, and psc_eeop for x_putc, x_flush, x_move, x_eeol,
	  and x_eeop.  Also added x_flush after x_scroll which will
	  initialize the t_pflush field in the TERM structure.
	+ x11.c (x_touch):  Call MARK_CELL_DIRTY and MARK_LINE_DIRTY instead
	  of using old mechanism.
	+ x11.c (wait_for_scroll):  Nuked XXX comment since it doesn't
	  seem to apply any longer.
	+ x11.c (CLEAR_LINE, SWAP_LINE): Nuked these macros which I recently
	  wrote for use in x_scroll.
	+ x11.c (x_scroll):  Nuked code for clearing and moving lines around.
	+ x11.c (flush_line): Minor reformatting.
	+ x11.c (clear_line): Eliminated this dead code.
	+ x11.c (x_flush): Rewritten.  It will now call flush_line for
	  any change in attribute instead of just reversed video.  flush_line
	  still needs to be rewritten to handle the other attributes.
	  Handling of cursor should be better too.
	+ x11.c (x_putline, x_fastpoutline, x_setrowcolors, x_cls): Removed
	  this "notyet" code.  The need for such functions has been replaced
	  by new attribute mechanism and interface to pscreen.
	+ x11.c (multi_click, display_cursor):  Use CELL_TEXT instead of old
	  data structures.
	+ x11.c (x_process_event): Call display_cursor() on ButtonRelease
	  event instead of in x_getc().

	+ display.c (updateline): Wrote new version for OPT_PSCREEN.  I
	  tried modifying the !MEMMAP version, but this version is difficult
	  enough to understand without adding to the rat's nest of #if,
	  #else, and #endif statements.
	+ display.c (updgar, scrolls): Preprocessor statements and a little
	  bit of code for OPT_PSCREEN.
	+ display.c, proto.h (psc_putchar, psc_flush, psc_move, psc_eeol,
	  psc_eeop, psc_rev): New functions and their prototypes.

	+ estruct.h (t_pflush): New field in the TERM structure used
	  by OPT_PSCREEN interface to flush the output.  TTpflush is
	  defined to allow easy access to this field via the variable term.
	+ estruct.h (OPT_PSCREEN): New feature test.  Used for determining
	  if the screen interface wishes to access the pscreen structure
	  directly.  Definitions of VADIRTY and VATTRIB in this file
	  depend on OPT_PSCREEN.

	+ x11.c (x_beep): Use GXxor instead of GXinvert as the logical
	  function in the graphics context for flashing the screen.  GXxor
	  will give better results on color displays.
	+ x11.c (x_getc): Removed if'd out call to display_cursor().
	+ x11.c (x_flush):  Add bounds check to make sure that it is ok to
	  write out the cursor.

	+ estruct.h (VIDEO):  Added new field v_attrs.
	+ estruct.h (VIDEO_ATTR):  Accommodations for color.  Also eliminated
	  VACOL mask.  Added VADIRTY, VAFGCOL, and VABGCOL.
	+ display.c ([pv]scrat):  Eliminated in favor of using the v_attrs
	  field in the VIDEO structure.  Also small modifications to ignore/set
	  dirty bit in updateline().

	+ x11.c (display_cursor):  Called from x_flush instead of x_getc to
	  avoid flicker.  Call of display_cursor from x_getc if'd out.

	+ display.c ([pv]scrat):  Replaced calls to memset with "for" loops
	  using explicit assignment in anticipation of making VIDEO_ATTR
	  a sixteen bit quantity when COLOR is enabled.  This code will
	  still need to be tinkered with somewhat in order to set the
	  foreground and background colors properly for the line whose
	  attributes are being reset.  (I have placed FIXME's in the code
	  to indicate where this needs to be done.)

	+ display.c (scrolls): New local variables longinplace and inplace
	  are used in determining whether or not a potential match of lines
	  to be shifted is really better than a previously computed match. 
	  The undesirable behavior that this corrects can be best observed
	  in vile (I used an xterm with 50+ lines).  Edit a file with
	  enough lines to be able to do a bit of scrolling.  Split the
	  window and make the upper window about half the size of the lower
	  window.  Then start scrolling through lines in the the upper
	  window which are duplicated in the lower one.  (Try it in both
	  directions.) You will notice that portions of the lower window
	  will be updated along with the upper.  The problem was that
	  longer matches were being obtained by scrolling lines from the
	  lower window up to the upper with the cost of having to later
	  update a large segment of the lower window.  This new code will
	  count the number lines which are already properly placed (e.g.,
	  do not need to be moved at all) in a section to be potentially
	  moved.  It will then use this count to help decide if the new
	  potential match is better than the old one.

	+ modetbl (font):  Commented out dependency on X11.
	+ eval.c (SetVarValue, gtenv): Added code to ignore EVFONT when X11
	  is not defined.  The reason for all of this is so that a .vilerc
	  file which has a "set font" line in it may be shared between both
	  vile and xvile.

	+ edef.h, main.c (insert_mode_was): Eliminated.  This variable was
	  _only_ referenced (i.e, not set anywhere) and only referenced
	  in one place.

	+ estruct.h (insertmode, insmode): insmode is a new field in the
	  W_TRAITS structure.  Define macro insertmode in terms of the
	  insmode field in the W_TRAITS structure when OPT_MOUSE is
	  defined. 
	+ edef.h (insertmode): Don't declare insertmode as a variable when
	  it is already defined as a macro
	+ main.c (loop): Check to see if insertmode is set after getting a
	  character.  If it is, re-enter insert mode.  The reason for the
	  above three changes is to prevent insert mode from "moving" to a
	  new window when using the mouse to set focus to another vile
	  window.  These changes allow a window to "remember" which mode it
	  was in when the window was left so that that mode may be
	  reentered when we return to the window.

	+ select.c, proto.h (free_attrib): New function.
	+ line.c (lremove): Traverse attribute list and fix marks
	  indicating the beginning and ending of each attributed region. 
	  The attributed region is freed if both beginning and end both
	  refer to the line about to be removed.

	+ vile.hlp: Documented new resources.

	+ x11.c (blink_id, blink_status, blink_interval):  New fields in
	  TermInfo structure.  Also created new resource XtNblinkInterval
	  and XtCBlinkInterval for setting the blink_interval field.  Setting
	  this field to zero will disable blinking entirely.  Positive
	  values will enable blinking all the time with the blink rate
	  being the value in milliseconds.  Negative values will enable
	  blinking only when the cursor is positioned within a highlighted
	  region.  Again the blink interval is in milliseconds.

	+ x11.c (display_cursor):  New function called from x_getc() for
	  displaying the cursor.  Handles blinking cursors.

	+ x11.c (XtNpersistentSelections, XtCPersistentSelections): New
	  resource instance and class name for resource
	  persistentSelections.  This resource controls whether or not
	  highlighting of selection (and indeed the selection itself), is
	  released when clicking button one.  start_selection() modified to
	  check whether this resource is set or not and to take the
	  appropriate action.

	+ x11.c (invert_display, x_beep): Eliminated invert_display(). 
	  Rewrote OPT_FLASH stuff in x_beep() to reduce dependence on
	  structures in x11.c which know about the attributes.  (These
	  structures will eventually be eliminated.) The flash obtained from
	  the new code also looks better (it was kind of choppy before).

	+ x11.c (x_getc): Make sure that cur_win->show_cursor is TRUE before
	  displaying the cursor.

	+ x11.c (x_setfont): Call update_scroll_bar_sizes when a font change
	  will change the size of the window.

	+ x11.c (turnOnCursor, turnOffCursor, CELL_CURSOR): Nuked all code
	  referencing these.  This is yet another step toward integrating
	  use of [pv]screen and [pv]scrat into x11.c.

	+ x11.c (x_getc): Display the cursor here before calling
	  XtAppNextEvent.

	+ x11.c: Slowed down initial scrolling of selections (you don't want
	  the lines whizzing by if you only want a few more lines).  Sped up
	  scrolling of selections that have been scrolling for a while
	  already.

	+ x11.c: Added resources for scrollRepeatInterval and
	  scrollRepeatTimeout for xvile NO_WIDGETS version.

	+ display.c (vt_leaks): free pscrat and vscrat.
	+ display.c (updateline): consider virtual screen attributes when
	  noting nonblanks in right match.

	+ modetbl, main.c, select.c (WMDTERSELECT): New window mode for
	  controlling whether selections are terse or verbose.

	+ vile.hlp: Documentation for selections and other x11 stuff.

	+ makefile (select.{c,o}): Added to the SRC and OBJ file list.

	+ select.c: New file implementing selection/attribute stuff.

	+ proto.h (free_attribs, sel_begin, sel_extend, sel_release,
	  sel_yankmaybe, sel_attached, sel_buffer, sel_setshape):
	  New prototypes.

	+ estruct.h (OPT_VIDEO_ATTRS, OPT_SELECTIONS): New feature tests.
	+ estruct.h (NKREGS): Set to 37 (rather than 36) when OPT_SELECTIONS
	  enabled.
	+ estruct.h (SEL_KREG): Define the selection kill reg number.
	+ estruct.h (MAXROWS, MAXCOLS): Moved here from x11.c.
	+ estruct.h (REGIONSHAPE): New typedef.
	+ estruct.h (REGION): Position of typedef moved ahead of that of
	  BUFFER (so that AREGION can use REGION and BUFFER use AREGION).
	+ estruct.h (VIDEO_ATTR): New typedef.  New mask values for this
	  typedef also (VACOL, VAREV, VAUL, VAITAL, and VABOLD).
	+ estruct.h (AREGION): New typedef.
	+ estruct.h (b_attrib): New field in struct BUFFER.
	+ estruct.h (do_mark_iterate): New macro for iterating over named
	  marks and region marks for the current buffer.

	+ buffer.c (bfind): Initialize b_attribs field.
	+ buffer.c (bclear): Call free_attribs to free attributes associated
	  with buffer.

	+ line.c (linsert, lnewline, ldelete, ldelnewline): Use macro
	  do_mark_iterate to fix the marks.

	+ tmp.c (dumpBuffer, AdjustPtrs): Call do_mark_iterate for adjusting
	  marks.

	+ undo.c (lineundo, repointstuff): Call do_mark_iterate for mark
	  adjustment.

	+ display.c (vscrat, pscrat): New variables representing virtual
	  and physical screen attributes.
	+ display.c (updattrs): New function called from update().
	+ display.c (vtinit): Initialize vscrat and pscrat.
	+ display.c (update): Nuked assignment of the ruler line in
	  OPT_SCROLLBAR code (x11.c no longer needs this).
	+ display.c (updgar): update pscrat.
	+ display.c (hilite, modeline): use vscrat to do highlighting.
	+ display.c (scrolls): move attributes in pscrat to account for
	  scrolling.
	+ display.c (updateline): Use pscrat and vscrat in updating the line.

	+ edef.h (regionshape): Declare as REGIONSHAPE instead of short.

	+ basic.c (setnmmark): Added code if'd by OPT_SELECTIONS which
	  implements a mechanism for making selections from the keyboard.
	  "m." will mark the start of a selection. "m\" extends the selection
	  rectangularly. "m'" extends a selection by full lines. "m\" extends
	  a selection exactly.
	+ line.c (reg2index): Added code if'd by OPT_SELECTIONS which makes
	  the name "." the kill reg associated with the current selection.

	+ x11.c (PANE_WIDTH_DEFAULT): Changed to 15 for NO_WIDGETS.
	+ x11.c (MAXROWS, MAXCOLS): Moved to estruct.h.
	+ x11.c (scroll_repeat_id, wipe_permitted, sel_scroll_id): New
	  fields in struct _text_win.
	+ x11.c (sel_start_col, sel_start_row, sel_end_col, sel_end_row,
	  wipe_row, wipe_col, show_selection): These fields removed from
	  struct _text_win.
	+ x11.c (row2line, clear_row_selection, save_selection,
	  change_selection): These functions removed along with all references
	  to them.
	+ x11.c (scroll_selection, repeat_scroll): New functions.
	+ x11.c (do_scroll): Added code so that scroll will repeat when
	  button is held down.
	+ x11.c (x_preparse_args): Get button release events too for the
	  screen widget.
	+ x11.c (x_scroll): Rewritten to move attributes (found in
	  cur_win->attr) along with screen data.  Should be more efficient
	  as well.
	+ x11.c (x_flush): Changed way in which cursor is displayed in
	  selections.
	+ x11.c (in_selection): This macro deleted.
	+ x11.c (x_putline): Leave cursor one past last char in line section
	  just put unless at end of line.
	+ x11.c (x_eeol, x_eeop): Erase to end of line/page in reverse video
	  if in reverse video.
	+ x11.c (x_lose_selection, x_stash_selection, x_give_selection,
	  x_own_selection, extend_selection, multi_click, start_selection,
	  x_process_event): Modified/rewritten to use new selection stuff.
	  Other cosmetic improvements/modifications were made to the
	  above functions resulting in the following user visible changes:
	    + clicking button 1 on mode line will set focus on
	      corresponding window without scrolling the window by
	      one line.  Double clicking on mode line will clear the
	      current selection.
	    + selecting text by dragging will now scroll the window
	      up or down when the bottom or top is reached.  It is
	      now also possible to drag with the right mouse button.
	      Speed at which text is scrolled while being selected  will
	      increase with the passage of time.
	    + rectangular regions may be selected by using the control
	      key as a modifier.
	    + highlighting of selection is not lost unless another
	      selection is made either in xvile or somewhere else
	      or unless mode line is double clicked upon.
	    + it is now possible to start a selection in one window
	      and extend it in another window (provided the "other"
	      window is open to the same buffer).

Changes for vile 4.3 (released March 29, 1994)
(pgf)
	+ make all functions called by do_lines_in_region be prepared to
	  take empty lines. (region.c)

	+ added terse addition to the README

(tom)
	+ corrected test in 'eol_command()' to allow command-names with '-'
	  (bind.c)

	+ corrected last 'mlerror()' change (display.c).

	+ added 'tags' rule to override conflict with default rule (makefile).

	+ corrected 'readpattern()' so that '%' can be used as delimiter in
	  ":g" command (search.c)
  
(kev)	
	+ call update_scrollbar_sizes() when changing fonts. (x11.c)

Changes for vile 4.2 (briefly released March 25, 1994)
(pgf)
	+ fixed Register buffer animation, using static flag to limit
	  the work done for each call to relist_registers(). (line.c)

	+ use common update_scratch() routine to trigger animation of
	  modes and maps.  (mode.c, map.c)

	+ add lines to vile.hlp about ".vilerc" vs. "vile.rc"

	+ fixed several bugs in rectangular operations (region.c)

	+ disabled "memory" command under Watcom, since _memavl() doesn't
	  _really_ report how much memory there is left -- just how much
	  is left before it needs to grow the heap. (main.c)

	+ npopen() should be silent on errors. (npopen.c)

	+ gave mlerror() a default message if errno is out of range (display.c)

	+ rationalized use of mlerror() and FIOERR.  now, the function that
	  first generates FIOERR is guaranteed to have put out a message,
	  probably via mlerror. (file.c, fileio.c)

	+ systems without EISDIR now all generate EACCES for directory
	  errors.  (fileio.c)

(tom)
	+ cleanup for OPT_MAP_MEMORY compilation ( display.c fileio.c
	  insert.c line.c random.c region.c tags.c undo.c)

	+ cleanup of OPT_WORKING ifdef (estruct.h)

	+ changed "#elif" to old-style because HP/UX bundled compiler doesn't
	  treat these properly. (fileio.c, should also change x11.c).

	+ corrected logic for arrow-keys in xvile's history by new function
	  'kcod2escape_seq()' (input.c, x11.c, x11simp.c).

	+ corrected 'l_ptr()' function to ensure signed comparison (tmp.c).

Changes for vile 4.1 (not released March 11, 1994)
(pgf)

	+ add include of stddef.h if POSIX, to pick up offsetof, so we don't
	  get a warning when building xvile on linux (estruct.h)

	+ again, fix core from is_falsem/is_truem. (eval.c)

	+ fix compiler warning (bind.c)

	+ removed -rows and -columns from usage message and help. (version.c
	  vile.hlp)

	+ fixed for the Watcom compiler; dense line modes now work. (ibmpc.c)

	+ the 'J' (and :j) command no longer perturbs the yank/kill registers, so
	  the sequence 'dwJp' puts back the word
	  you deleted, not the newline that 'J' deleted.  (region.c, word.c, proto.h)

	+ DOS now uses pressreturn() after a shell escape.

	+ streamlined tb_sappend() (tbuff.c)

	+ changed x11 pasting to not trim leading whitespace, and to use
	  the xxx_no_aindent() functions for performing insertions.  this
	  means you now paste what you cut, with indentation preserved from
	  the original, rather than recreated (or lost) by autoindent or
	  cmode. (x11.c, x11simp.c)

	+ new routine, fnc2str(), to support above change, since the no-aindent
	  commands are multi-char sequences.  (bind.c, proto.h)

	+ implemented rectangular regions, using new "regionshape" global,
	  new commands ("goto-named-mark-rectangular",
	  "put-as-rectangle-after", "put-as-rectangle-before",
	  "open-rectangle", "blank-region"), and new behavior for
	  rectangles of the "shift-right-region" (opens up),
	  "shift-left-region" (deletes), the delete and yank operators. 
	  new rectangular (basic.c, cmdtbl, region.c, random.c, line.c, edef.h,
	  estruct.h, line.c, opers.c, proto.h)

	+ many changes in region.c, to make the region code rectangle-aware.
	  new routines do_lines_in_region()/do_chars_in_line() to support
	  simple cases of walking a region in two dimensions.  reimplemented
	  yankregion using these, so it is now rectangle aware.  new blankline
	  routine.  getregion() knows how to set up rectangular regions.
	  (region.c)

	+ changed getcol/getccol/gocol/gotocol to support rectangle code.
	  (random.c)

	+ changed the 'fulllineregions' boolean to a 'regionshape' descriptor.
	  (exec.c, edef.h ibmpc.c, fences.c, insert.c, basic.c, main.c, word.c,
	  x11.c, x11simp.c)

	+ moved a bunch of region-related code from random.c to region.c

	+ during undo, attempt to retain offset information for marks
	  pointing at a line being replaced.  this makes exact marks
	  last longer, and they're more important now with rectangles.
	  (undo.c)

	+ added extra column arguments to some of the line-processing
	  routines, like entab/detab/trimline.  (insert.c, word.c)

	+ fixed autoindent inconsistency, when breaking a brace-terminated
	  line in half. (insert.c)

	+ turned off the POISON #define.  this should have gone away a while
	  ago (it fills memory with a bad patter when we free it). (line.c)

	+ fixed old bug in the maintenance of MK.o when adjusting due
	  to character edits. (line.c)

	+ maintain record of longest line in a kill-register (line.c)

	+ the histbuffer (_) command now stutters with a call to tgetc
	  instead of kbd_seq, so that the pushback of an unused command
	  works okay. (buffer.c)

	+ anycb() now returns a pointer to the first modified buffer
	  it encounters, so callers can treat the single buffer case
	  specially.  changed callers as well: quit(), zzquit(), and
	  spawn().  (buffer.c, spawn.c, main.c)

	+ DOS video drivers are now selected more cleanly by name.  any
	  driver can be selected from the command line (as long as its
	  name starts with a digit).  drivers can have multiple entries
	  corresponding to multiple names.  the same name can refer to
	  two different entries, in cases where there are two resolutions
	  for the same screen geometry. (main.c, ibmpc.c)

	+ made backspacing be non-destructive in overwrite mode (insert.c)

	+ eliminated the full-buffer-loop in undo.c, by using a cookie to
	  identify the current undo operation, and using it to mark lines
	  that have already been copied.  should be a big performance win
	  for big files on slow machines.  (estruct.h, tmp.c, undo.c)

	+ added support for setting the IBM color palette. (ibmpc.c, vile.hlp)
	  
(kev)
	+ updated help text for X11 (version.c, vile.hlp)

	+ added command line arguments -row, -cols, -leftbar, and -rightbar.
	  (x11.c)

	+ fix for motif resizing (x11.c)

	+ updated help text for X11 (version.c, vile.hlp)

	+ added command line arguments -row, -cols, -leftbar, and -rightbar.
	  (x11.c)
	+ Set XmNresizePolicy to XmRESIZE_NONE in x_configure_window in
	  order to fix resize problems with the Motif widget set in
	  which the scrollbars were getting set very big or very small.

	+ Support for scrollbars on the left in motif added.  openlook
	  still needs to be done.

	+ Added an initialization of XtNgeometry to XtVaAppInitialize
	  setting this resource to NULL.  This overrides any user
	  specified geometry request for the top level shell.  The
	  geometry request is still available through the geometry
	  variable which Tom added to the TextWindow structure.  Tom's
	  code for parsing the geometry has been preserved, but
	  enhanced somewhat to set default values for the number of
	  rows or columns in case if the user specified only the
	  position.  Width and height specifications are considered to
	  be in character widths or heights instead of in pixels.  We
	  let the initialization of the screen and pane widgets
	  determine the size of the outer widgets.  (Much of this is
	  as it was before...the only thing really new here is one
	  line added in the call to XtVaAppInitialize).

	+ Added code to set XtNgeometry on the top level widget if the
	  user's geometry request specified the initial window
	  position.  Only the positional information is set; the width
	  and height are left out in order so that the sizes of the
	  children will correctly influence the initial size of the
	  top level shell widget.

	+ Added scrollbar support for NO_WIDGETS by using core widgets
	  for both the scrollbars and the resize grips.  Geometry
	  management is handled with a simple homebrew widget
	  subclassed from Composite.  I believe that the scrollbar
	  resize mechanism is superior to that found in xvile
	  implemented with the other widget sets (particularly
	  OpenLook).  We might consider either totally getting rid of
	  OpenLook support (how many people are going to use it?) or
	  at the very least reimplement scrollbar resize with the same
	  mechanisms used by the NO_WIDGETS version.  We might also
	  consider dropping the Athena widget set since it seems to be
	  buggy on some platforms.  The code will be easier to
	  maintain though and users will not be so confused by the
	  number of configuration options if we manage to drop a
	  couple of the widget sets.  (A middle ground might be to use
	  only the scrollbar widgets from various widget sets.  Much
	  of the complexity comes from the differences in the Form and
	  Pane widgets.  This way we could still use other widgets
	  from the other widgets sets in the future.  This won't make
	  the configuration any easier, but it might make the code
	  easier to maintain.)
	
	+ Modified manner in which the top of the scrollbar is set for
	  all widget sets.  Rather than forcing dot to be in the
	  middle of the screen, we attempt to leave dot where it is. 
	  The top of the scrollbar is set based upon the top line of
	  the window rather than dot.  This gives consistent scrolling
	  behavior.  Tom's concerns that the "thumb" or slider remain
	  visible even at the end of the buffer are also addressed
	  with this approach.  When at the very end of the buffer (so
	  that the screen has a large number of tildes on it),
	  xt-vile and xaw-vile will still display a sliver indicating
	  the portion of the buffer actually shown.  If this is
	  undesirable, ntildes should be set to something small (like
	  zero).  Once this is done, the thumb will maintain a uniform
	  size from the top of the buffer to the bottom.  I've tested
	  these versions with small buffers (buffers containing zero
	  thru 2*curwp->w_ntrows lines) and the appearance seems to be
	  consistent throughout.  Large buffers (> 4000 lines) seem to
	  still have a slight problem at the end of the buffer in
	  xaw-vile).

	+ Made the insertion bar the mouse cursor (for the xvile
	  screen only) in all versions.

	+ fixed x_working so that xvile may once again be interrupted.

	+ added missing assignment so that insertion bar is now really
	  used when the cursor enters window corresponding to the xvile
	  screen widget.

	+ implemented scrollbarOnLeft resource for NO_WIDGETS version.

	+ nuked ATHENA_WIDGETS code.  This code was eliminated because
	  it was observed that the NO_WIDGETS version functions as
	  well if not better than the ATHENA_WIDGETS version and it
	  runs on machines which have a buggy (Athena) widget library. 
	  On the down side, it will be somewhat harder to add new
	  widgets in the future if this is desired.

(tom)
	+ modified kevin's resources in x11.c to use "geometry" rather than
	  "rows" and "columns".  Adjusted logic so that geometry resource means
	  chars, not pixels.

Changes for vile 4.0 (not released Tue Feb 22, 1994)
(pgf)
	+ fix core from one-too-many chars to strncpy(). (eval.c)

	+ change #elif constructs in version.c to oldstyle #else/#if

	+ applied contributed patch for implementing 0^D in insert mode,
	  and expanded it to implement ^^D. (insert.c)

	+ insert mode now parses function key #c pairs returned from
	  kbd_key(), so arrow keys work.  (input.c insert.c)

	+ no longer turn off dot recording for non-redoable commands if
	  we're in insert mode. (exec.c)

	+ display high-bit keyboard input on message line in either octal
	  or hex, depending on global value of unprintable-as-octal. (bind.c)

	+ implemented "alt-function-prefix" to make function-key parsing
	  in insert mode less ambiguous.  (edef.h, insert.c, input.c, cmdtbl,
	  main.c)

	+ new help for arrow keys, and cd/pwd commands.  also some more
	  pcvile differences.  (vile.hlp)

	+ fixed djgpp implementation of get_vga_bios_info, by packing
	  the structs int 10/1b deals with.  this makes 43 and 50 line modes
	  work.  (still don't work with watcom, though) (ibmpc.c)

	+ made :memory work under DJGPP	(main.c)
	
	+ made catnap() work under DJGPP, so flash mode works now. (random.c)

	+ added more dependencies to makefile.djg

	+ apply patch for honoring the trailing $ in a tag lookup patterns.
	  (tags.c, eric krohn)

	+ make animation of buffer list take into account whether it contains
	  an apropos list or a full "describe bindings" (bind.c)

	+ some makefile cleanup, for mips and NeXT, and compulsion's sake.

	+ modified heuristic for setting dos-mode on an ambiguous (usually
	  empty) buffer -- only set it if the global mode is set, and if
	  we're actually running on DOS. (main.c, random.c, file.c, estruct.h)


(tom)
	+ added new function 'parse_pathlist()' to encapsulate the logic used
	  in lookup of vile.hlp (PATHLOOK) and the CDPATH environment variable
	  (fixes buffer overflow in the latter).

	+ corrected treatment of arrow-keys (in history.c) broken in 3.65
	  using new function 'kbd_escape_seq()' (input.c, history.c).

	+ modified ifdef's in 'interrupted()' to test type-ahead only
	  for DJGPP configuration (main.c).

	+ restored code that translated CDSENSE to driver type, because it did
	  not set screen defaults to maximum size (ibmpc.c)

(kev)
	+ I have added scrollbars to xvile.  I made a copy of x11.c,
	modified it (heavily) and called it xt.c.  [ I've renamed it x11.c,
	and moved the old x11.c to x11simp.c.  We can merge later. ] Minor
	modifications were necessary to several other of the source files. 
	(display.c, estruct.h, main.c, makefile, and window.c.)
	xt.c uses the X toolkit and the Athena widget set to provide the
	following new functionality:

	    A scrollbar for each vile window.  The standard translations
	    provided by Athena scrollbars control movement of text in the
	    vile window.

	    Resize of vile windows by moving the border between
	    corresponding scrollbars (with the mouse).

	    Splitting and deleting of windows may now be done with the
	    mouse.  Ctrl on a scrollbar will cause the scrollbar
	    and the corresponding vile window to be split with the new
	    border at or near the mouse cursor.  Ctrl will delete
	    the window.  Ctrl will make the corresponding window
	    the only window.

	    Problems with getting the input focus set properly have been
	    fixed.

	    Quitting via the window manager works better.  It basically
	    works the same as if you had typed :q.  vile will display a
	    message if there are any unwritten buffers.  We may eventually
	    want to pop up an alert box when attempting to quit with
	    modified buffers from the window manager.

	+ added "ntildes" variable, which controls max number of tildes
	  displayed at the end of a buffer, expressed as a percentage of
	  window size.  [pgf made it a percentage] (edef.h eval.c display.c
	  modetbl vile.hlp)

	+ added support for the Motif and OpenLook widget sets.  

	+ fixed bug where focusFollowsMouse would take us out of the message
	  line when we should remain there.


This change log started on Tue Feb 22, 1994.

vile-9.8v/CHANGES.R5000066400000000000000000002404131415556424100140120ustar00rootroot00000000000000Changes for vile 6.0 (released Tue Jun 18, 1996)

(pgf)	960618
	+ no longer use non-standard RCS extensions to generate revlist.
	  this is slower, but it works always.  (makefile.in)

	+ change makefile targets "tar" and "shar" to "tarball" and
	  "sharball". (makefile.in)

	+ add "const" to tempnam() args to satisfy reported problem with
	  DEC C -- apparently there is already a prototype in scope for
	  tempnam().  (vms2unix.c)

	+ documented (years late :-) the "save-keyboard-macro" command,
	  which will copy the keyboard macro to a named register. (vile.hlp)

	+ allow arg. to "load-register" to force a full-line style load.
	  this allows
	  	1 use-register e load-register "#endif"
	  to be used to duplicate a 'yy' of "#endif".  previously you
	  could not get the full-line effect, i.e. it worked like 'yW'.
	  (line.c)

(tom)	960612 (zg)
	+ modify configure script, putting test for socket, nsl libraries after
	  X-libraries, to avoid duplication (configure.in)

	+ modify cd/pwd logic to recover better when the current and parent
	  directories aren't readable by the current process (path.c, random.c).

(tom)	960527 (zf)
	+ added "--enable-echo" option to configure.in

	+ applied Andy Harper's correction for VMS 'tempnam()'.

	+ added VC_AC_PREREQ macro to allow conditional generation of the
	  configure script, according to whether my patches for autoconf have
	  been applied.  Added local copy of new autoconf macros as well
	  (configure.in, aclocal.m4).

	+ reordered autoconf macros (aclocal.m4)

	+ redefine AC_MSG_CHECKING, AC_CHECKING so that they log the same info
	  to config.log (aclocal.m4).

	+ removed VC_SIZE_T because recent autoconf checks stdlib.h
	  (aclocal.m4, configure.in)

	+ removed VC_TEST_GETPGRP macro (aclocal.m4, estruct.h, configure.in)

	+ removed VC_SETPGRP macro (aclocal.m4, proto.h, configure.in, main.c)

	+ added aliases for Sf, Sb termcap capabilities (AF, AB) for ANSI
	  termcap descriptions.

(tom)	960522 (ze)
	+ corrected a couple of lengths for strncpy0 calls (file.c)

	+ modify handling of toggle-buffer-list so that giving a parameter
	  overrides the default pop/unpop, and toggles the listing of invisible
	  buffers instead (buffer.c)

(pgf)	960516 (zd)
	+ clarifications regarding file/command/shell completion (vile.hlp).

	+ modified quote() routine to allow input of decimal values -- now
	  entering ^VNNN, ^V0NNN, or ^VxNN will insert the character with
	  that decimal, octal, or hex vale.  (255 max).  entering fewer
	  than 3 digits will enter the value, and the terminating character
	  will be "ungotten" and then re-consumed as usual.  feature
	  requested by user, implementation inspired by vim.  (insert.c,
	  vile.hlp)

	+ added digraphs.rc, a set of :map! commands to aid the insertion
	  of ISO 8859/1 8-bit characters.  the ^Kcc form of the maps (and
	  their exact values) is borrowed from vim.  (digraphs.rc,
	  makefile.in, vile.hlp, makefile.djg)

	+ the [Standard Input] buffer is now marked "read-only" rather
	  than "view" to match other piped-to buffers.  (all clients of
	  set_rdonly() affected, since argument was added.)

	+ removed disclaimer from help file regarding x! and w!.

	+ added -R option to set "readonly" mode, put -v back to setting
	  "view" mode as it used to, updated man page to reflect all this.
	  (vile.1, main.c)

	+ the initial response to a ":e" prompt is defaulted to the first
	  command line argument to vile.  (file.c, main.c)

(kev)	960417 (zc)
	+ configure.in, configure:  Changed configure.in so that configure
	  will run cleanly and create something useful in a Sparc / Solaris
	  / X11R6 environment.  Regenerated configure.  Also fixed a few of
	  the autoconf warnings for configure.in.

	+ makefile.in (X_EXTRA_LIBS, X_PRE_LIBS): Removed these makefile
	  variables.
	 
(tom)	960416 (zb)
	+ further corrected 'shell_complete()' to test and adjust for leading
	  "!", and use this to also simplify call from 'cmd_complete()'
	  (bind.c, input.c).

	+ prevent 'do_lines_in_region()' from processing the nominal end of a
	  full-line region, since that is off-by-one to accommodate width
	  requirements; this fixes ":.,.+3>>>" (region.c).

(kev)	960416 (za)
	+ basic.c (setcursor): Permit the mouse to set the cursor when
	  doing an "op" command.  Prevent MK from becoming corrupted if
	  call too set_curwp() caused a window change.

	+ filec.c (mlreply_file): Use Tom's filename completion stuff
	  on shell commands for things like ":e !gunzip -c /usr/doc/".

	+ input.c (shell_complete): Fixed an off-by-one/beginning-of-buffer
	  bug.  [The variable "base" should never be less than zero after
	  the termination of the "for" loop.]

(tom)	960415 (z)
	+ show read-only mode in status line (display.c)

	+ refined/corrected VMS pathname translations, to better handle root
	  directory, and ^X-e command (file.c, filec.c, glob.c, path.c,
	  vms2unix.c).

	+ implemented filename-completion in shell commands (bind.c, filec.c,
	  input.c)

	+ modified filename-completion to recognize environment variables
	  (filec.c).

	+ change token-expansion from ':' to '&' for VMS and MS-DOS (estruct.h,
	  input.c, main.c).

	+ implement error-finder for CSet C/C++ (finderr.c)

(tom)	960410 (y)
	+ modified TERM struct so that no function-pointers should be null.
	  Inactive functions are assigned from the null device's TERM struct.
	  This provides better type-checking, as well as getting rid of
	  no-effect compiler warnings.

	+ restored  include for TurboC (random.c)

	+ adjusted ifdef's to allow changes to 'imdying()' to compile on
	  MS-DOS and OS/2 (file.c).

(pgf)	960329 (x)
	+ new modes:  "readonly", which prevents writing a buffer out, and
	  "readonly-on-readonly", which sets this mode if the buffer is not
	  writable according to the OS.  setting the latter causes vile to
	  mimic vi's default behavior.  it is off by default.  "vile -v",
	  invoking as "view", and reading from a pipe all now set
	  "readonly" mode rather than "view" mode.  (modetbl, main.c,
	  file.c, vile.hlp, vile.1)

	+ better (?) help on using '/' as a path delimter on PC operating
	  systems. (vile.hlp)

	+ new command, "set-unix-mode", as a complement to "set-dos-mode".
	  this capability was there before as "1:set-dos-mode", but it sure
	  was hard to explain to people.  (cmdtbl, vile.hlp, file.c)

(jrs)	960328 (w)
	+ estruct.h: Make TERM "optional" members "mandatory" and protect
	  references to all optionally implemented members with null
	  checks.
	+ ansi.c, at386.c, borland.c, dg10.c, dumbterm.c, hp110.c, hp150.c,
	  ibmpc.c, ntconio.c, st520.c, tcap.c, termio.c, tipc.c, vmsvt.c,
	  vt52.c, x11.c, z309.c, z_ibmpc.c: Remove all TERM-related optional
	  ifdefs and replace all stub functions with null function pointers.
	+ borland.c: Convert function definitions to ANSI C and make most
	  functions static.
	+ estruct.h: Add new optional window title method to TERM and
	  enable it for WIN32.
	+ buffer.c: Optionally set window title based on buffer name.
	+ dirstuff.h: Use  instead of  with Visual C++.
	+ estruct.h: Remove unnecessary ifdefs around undefs.
	+ file.c: Compile a working version of imdying on all platforms.
	+ history.c: We want to use our own isgraph so undef the OS version.
	+ npopen.c: Do all I/O redirections while keyboard is closed.
	+ ntconio.c: Make most functions static, make the insertion
	  cursor code match the expected optional interface, implement
	  the TERM title method, unsuccessfully try to catch abrupt
	  exits and do something about them, die gracefully if console
	  I/O fails.
	+ path.c: Remove unused code to downcase the path in is_msdos_drive.
	+ random.c: Change a bunch of compiler ifdefs to a single include
	  of dirstuff.h which already handles all of the special cases.
	  Add a judicious downcasing on non-caseless MS-DOS-like systems
	  like DJGPP to compensate for the above-mentioned change to
	  is_msdos_drive.
	+ termio.c: Don't put WIN32 typeahead code here since it is
	  already dispatched via TERM methods.
	+ README.PC: Various documentation fixes.

(tom)	960323 (v)
	+ removed tmp.c and OPT_MAP_MEMORY

(tom)	960317 (u)
	+ added "compile-error-expressions" to allow macros to force the [Error
	  Expressions] buffer to be created; otherwise it would only be created
	  on the first use of "find-next-error" (finderr.c).

	+ modified predefined error-expressions to remove unnecessary ':';
	  making them a little more general.  This makes the error finder
	  slower, however (finderr.c).

	+ modified RegStrChr2 to eliminate unnecessary 3rd parameter, making it
	  faster.  Use 'const' where possible in this file (regexp.c).

(tom)	960308 (t)
	+ correction to test for 'PC':  linker on HP/UX allows read from
	  non-existent location during configuration (configure.in).

	+ corrected special cases in word-wrap, by refining 'blanks_on_line()',
	  and use of 'n' in 'wordwrap()' (input.c, word.c).

(pgf)	960307 (s)
	+ added b_lines_on_disk element to BUFFER struct, to get back
	  "count from bottom" functionality in finderr. (file.c, finderr.c,
	  estruct.h)

	+ patch from jim hourihan to support "Cpp" keyword in vile-c-filt,
	  to allow colorizing all cpp lines at once, rather than listing
	  keywords individually. (c-filt.c, vile.hlp)

(tom)	960303 (r)
	+ corrected sign-extension of characters (map.c)

	+ added termcap capability for "@7" (Key_end)

	+ modified treatment of 'PC' in termcap driver; it should be extern
	  since it is "owned" by 'tputs()' (tcap.c).

	+ modified termcap driver to treat \200 specially in the key mapping
	  i.e., add a mapping with the corresponding \0 (tcap.c)

(pgf)	960228 (q)
	+ when notabinsert was active, autoindent accounting was being
	  done incorrectly, causing excess whitespace to be left if
	  you entered a '#' in cmode.  (insert.c)

	+ removed OPT_BSD_FILOCK, since it hasn't ever been used, and
	  the placeholders it was maintaining were incomplete, to say
	  the least.  (main.c, file.c, estruct.h)

	+ eliminate old screen files, that haven't been touched in a
	  while.  (at386.c, dg10.c, hp110.c, hp150.c, st520.c, vt52.c,
	  x11simp.c, z309.c, z_ibmpc.c)

	+ eliminate old SCREEN defines and ifdefs.  (ansi.c, display.c,
	  edef.h, epath.h, estruct.h, file.c, fileio.c, ibmpc.c, makefile.in,
	  spawn.c, termio.c, win31drv.c)


(tom)  96022? (p)
	+ use 'const' where applicable (lots of places :-)

	+ generate externs for CMDFUNC objects in nefunc.h (mktbls.c, all
	  makefiles, and C-files that had declared externs of these).

	+ modified 'pathname[]' to separate out the 'exec_pathname' variable,
	  to make the remaining pathname[] data const.

(tom)  960224 (o)
	+ correct logic of 'is_absolute_pathname()'; for VMS we need to ensure
	  that the pathname contains brackets or colons (path.c).

(tom)  960220 (n)
	+ modify autoconf script to allow "--with-screen=ncurses" to link
	  with terminfo support (configure.in).

	+ modify 'zotwp()' to switch to the most recently-used buffer instead
	  of the first one found, fixing behavior under noautobuffer mode
	  (buffer.c).

(tom)  960212 (m)
	+ modify autoconf script to add $X_PRE_LIBS and $X_EXTRA_LIBS in the
	  X configuration tests (configure.in).

	+ corrected potential null-pointer reference for $abufname (eval.c).

(tom)  960204 (l)
	+ modify 'pathcat()' so that if the 'leaf' given is an absolute
	  pathname, then we'll ignore the 'path' (usually an implied
	  directory), to handle case in finderr when a full pathname is parsed
	  (path.c).

	+ modify logic of find-next-error so that multiple distinct matches
	  on the same line will show up in the message-line (finderr.c).

	+ remove P macro (and ANSI_PROTO) from several modules (c-filt.c,
	  manfilt.c, mktbls.c).

	+ change 'int' to 'long' in places where we cast to/from pointer
	  (region.c, x11.c).

	+ added TTflush to tcapkclose so that xterm-mouse is reset properly
	  when spawning subshell (tcap.c).

	+ moved X_CFLAGS to CPPFLAGS definition so that lint works for xvile
	  (makefile.in).

(tom)  960118 (k)
	+ convert function definitions to ANSI form (55 c&h files affected),
	  so that K&R form is no longer used.  Removed macro ANSI_VARARGS, and
	  reduced ACTUAL_SIG_ARGS definition.  Compiled with VAX-C, TurboC,
	  WatCom 10.0a, gcc 2.5.8, gcc 2.7.2 (Linux, SunOS, Solaris, HP/UX 9),
	  CLIX, IRIX, SCO, UnixWare 1.2.  Also used 'unproto' to compile SunOS
	  and HP/UX.  Used ansi2knr for initial changes (i.e., finding places
	  that used K&R syntax), but this patch does not use ansi2knr.

	  This is not fully ANSI -- vile uses a number of Posix functions that
	  aren't recognized in strict ANSI modes by a number of compilers.
	  It does require that the compiler recognize prototypes and stdarg.h

(jrs)  960108 (j)
	+ path.c (curr_dir_on_drive) [SYS_WINNT]: Translate drive argument
	  from a drive letter (e.g. 'A' or 'a') to a drive number (e.g. 1)
	  since this is what _getdcwd expects.
	  (lengthen_path): Predicate curr_dir_on_drive call on OPT_MSDOS_PATH
	  instead of listing individual systems so that e.g. this code is
	  also compiled in on SYS_WINNT.  Check for curr_dir_on_drive
	  failure and handle that case by assuming the current directory
	  on a non-existent drive is the root directory.

(pgf)  960107 (i)
	+ change order of TTkclose and TTclose in ttclean.  i think this
	  will give us back old behavior wrt terminals that have TI/TE
	  sequences.  we want to finish any screen-oriented i/o before
	  calling ttkclose.  (termio.c)

	+ removed okay_to_ask param from make_bp() and unqname(), since
	  it is now unused.  removed return value from unqname().  (exec.c,
	  file.c, proto.h)

	+ fixed unqname to continue trying wider and wider suffixes until
	  a unique name is found.  it will still loop, but only after a
	  very large number of buffernames has been tried.  uses base-36
	  index on end of filename. (file.c, proto.h)

	+ added %r to dofmt -- takes two args, uses the first as a radix
	  with which to print the second.  (display.c)

	+ bp->b_bname is now null-terminated (again?).  it's really much
	  cleaner this way.  NBUFN has changed
	  from 20 to 21, to make room for the null.  eliminated get_bname()
	  routine.  (buffer.c, display.c, edef.h, estruct.h, eval.c,
	  exec.c, file.c, finderr.c, input.c, main.c, modes.c, proto.h,
	  spawn.c, tags.c, tmp.c)

	+ added a chgd_hilite() side-effect function, which causes
	  a call to attrib_matches() when any of "magic", "ignorecase",
	  or "visual-matches" is changed.

	+ split up the "level" arg, which was overloaded to mean
	  two things, into two separate args, one which says it's a
	  global value we're changing, and the other which says we're
	  just testing whether we can change it.  (estruct.h, modes.c)

	+ guard against null gregexp in attrib_matches() -- possible
	  if pattern failed to compile, making pat[0] non-null, but
	  gregexp null.  (search.c)

	+ fix ifdefs to make it easier to test dos pipes under unix.  get
	  rid of duplicate close in dos readPipe, pointed out by jrs.  (the
	  second close is out in filterregion()).  (npopen.c, spawn.c,
	  proto.h)

(tom)	960105 (h)
	+ corrected inadvertent K&R substitution in APP_S macro, moved
	  bsd-lint expressions to avoid shadowing (finderr.c).

(pgf)	960103 (g)
	+ prevent characters following ^A, ^X and # prefixes from being
	  subject to remapping.  (input.c, vile.hlp)

	+ small change to "find matching indent" macros in vile.hlp, to
	  make them work when they encounter non-empty blank lines. (vile.hlp)

	+ tweak watcom makefile to use "protected mode" compiler.
	  selectable as $(CC), in case this breaks 10.x compiles.
	  (makefile.wat)

	+ fix for identifiers starting with '_', from sean ahern. (c-filt.c)


(tom)	960103 (f)
	+ corrected reference to char beyond regular expression in regexp
	  via 'lregexp()' function (regexp.c).

	+ corrected 'free()' of null pointer in finderr.c, and retested with
	  compile & lint logs, covering most most of the regular expressions in
	  that module (finderr.c)

(jrs)	951231 (e)
	+ configure.in (AC_HAVE_FUNCS): Move it after library checks
	  (so we can test for functions in auxiliary libraries) and
	  add checks for the functions tparm and tparam.

	+ djhandl.c (ctrl_c_count, was_ctrl_c_hit): Declare it as unsigned 
	  long instead of u_long for DJGPP v2.

	+ estruct.h [CC_DJGPP]: Define HAVE_UNISTD_H to eliminate some
	  not declared warnings with DJGPP v2.
	  (OPT_COLOR) [DISP_TERMCAP]: Don't conditionalize it based on
	  Linux.

	+ gppconio.c: Suppress the entire file under DJGPP v2 because the
	  bugs it was supposed to fix are fixed.

	+ makefile.djg (vile rule): Don't let stubedit globbing=no
	  failure prevent a successful build for DJGPP v2 which doesn't
	  seem to support it.

	+ os2vio.c (PRETTIER_SCROLL): Don't define it.
	  (vio_scroll): Base conditional scrolling code on
	  OPT_PRETTIER_SCROLL instead of PRETTIER_SCROLL.

	+ proto.h (was_ctrl_c_hit): Adjust prototype to match new
	  definition.

	+ tcap.c (tparm) [HAVE_TPARM]: Declare it.
	  (tparam) [HAVE_TPARAM]: Declare it.
	  (show_ansi_colors) [HAVE_TPARM]: Use tparm instead of tparam.

	+ version.c (getversion) [CC_DJGPP]: Discriminate DJGPP v2 from
	  the previous version.

(jrs)	951224 (d)
	+ file.c (getfile2bp): Never consult the user about duplicate
	  buffer names if `warn-rename' isn't on. 

	+ filec.c (headers): Don't suppress inclusion of dirstuff.h
	  on OS/2 since it doesn't hurt anything.
	  (fillMyBuff) [SYS_OS2]: Only down-case filenames read from
	  a directory if the drive they are on is not case-preserving.

	+ main.c (global_val_init): Initialize `warn-rename' so that
	  it defaults to the existing behavior.

	+ modetbl (warn-rename): New option.

	+ ntconio.c [SUPPORT_BROKEN_SCROLLING]: Rip out the ifdefs and
	  compile it unconditionally since the case it applies to now
	  no longer affects the efficiency of the most common case.

	+ path.c (headers) [SYS_OS2]: Include os2.h.
	  (is_case_preserving, case_correct_path) [SYS_OS2]: New functions.

	+ version.c (getversion) [CC_CSETPP]: Discriminate VisualAge C++
	  from C Set ++.

	+ vile.hlp (warn-rename, warn-reread): Document them.

(tom)	951223 (c)
	+ rewrote error-finder to support runtime-modifiable error regular
	  expressions (finderr.c, edef.h)

	+ added b_rmbuff member to BUFFER struct to notify error-finder when
	  its buffer is removed; the b_upbuff member handles the modify
	  events (estruct.h, buffer.c).
	  
	+ use macros b_set_obsolete/b_clr_obsolete (buffer.c, display.c)

	+ use RBRACK/LBRACK definitions throughout (filec.c, vms2unix.c)

	+ corrected missing initialization of CHARCELL link in extend_line()
	  that occasionally broke vile-manfilt (manfilt.c).

(tom)	951217 (b)
	+ lint (basic.c bind.c dumbterm.c exec.c insert.c line.c main.c map.c
	  oneliner.c patchlev.h path.c random.c search.c select.c tags.c
	  x11.c), including correcting error return within gotoeol(), and also
	  testing error return from bclear() in pregion(), and
	  attributeregion() in clear_match_attrs().

	+ corrected ifdef'd logic from vile 5.5a with new function 'ins_mode()'
	  replacing logic that's only used in mouse-code (display.c)

(jrs)	951216 (a)
	+ bind.c (fill_partial): Use StrNcmp of length 1 instead of
	  char equality to inherit case-insensitive comparison
	  when extending completions as far as possible.  This is
	  so that if we have `bind.c' and `BIND.OBJ' we will complete
	  up to `bind.' if OPT_CASELESS is enabled.

	+ file.c (fileread): Explicitly check for additional command
	  line input so that `e! RET' doesn't prompt for more input.
	  In that case, default to the filename of the current buffer
	  and optionally prompt for replacement based on the new option
	  `warn-reread'.

	+ filec.c (mlreply_file): Suppress prompting to reread the
	  current buffer based on the new variable `warn-reread'.
	  This is for people who like `e! RET' to assume they know
	  what they're doing.

	+ main.c (global_val_init): Initialize `warn-reread' so that
	  it defaults to the existing behavior.

	+ makefile.wnt (LDFLAGS): New variable to control debugging
	  and the logo.
	  (vile.exe, mktbls.exe): Use it.

	+ modetbl (warn-reread): New option.

	+ ntconio.c (ntscroll): Remove cRest variable and its
	  initialization since the default is what we want anyway.
	  Ensure that rectangles are described by their last row
	  or column, not its successor.  Narrow the amount of
	  backfilled scrolled areas by noting that the bug is the
	  failure to backfill the non-overlapped portion of a scroll.

Changes for vile 5.6 (released Thu Dec 14, 1995)
(pgf)
	+ allow "position-window" to be used from macros, e.g.
	  "position-window bottom".  giving it an arg now reframes to
	  that line from top or bottom, e.g. "11 position-window top".
	  (cmdtbl, eval.c, vile.hlp, window.c)

(pgf)	951212 (f)
	+ writing a region (e.g. ":.,$w foo") when the ends of the
	  region did not fit on the screen would cause "BUG: updpos...".
	  now fixed, by ensuring that moves are always flagged correctly.
	  (btw, this was hidden by anything else that set a w_flag bit,
	  like "ruler" mode.) (exec.c)

	+ fixed propagation of null character when highlighting string
	  literals that span lines.  (c-filt.c)

	+ fixed description of label syntax (vile.hlp)

(tom)	951209 (e)
	+ implemented "next-tag" function, bound to ^A-^], which steps through
	  alternate tags definitions for the last tag value (cmdtbl, tags.c).

	+ ifdef'd out code that causes vile to die when it receives an EOF
	  (linux only, termios.c)

	+ modified to allow trivial (one-match only) glob-expansion of items in
	  'tags' mode so that ~/tags and $HOME/tags work (tags.c).

(pgf)	951209 (d)
	+ take out call to wrapword() in newline(), which caused an
	  extra newline in some wrapping cases.  the condition it was
	  taking care of is now caught earlier on.  (insert.c)

(pgf)	951208 (c)
	+ created separate .zip targets for watcom and djgpp builds, since
	  i seem to have to switch back and forth all the time.  (makefile.in)

	+ do_num_proc and do_rept_arg_proc would accept ^X or ^A prefixes
	  followed by digits as further modifications to the argument
	  count, so 2 ^X-2 wouldn't work as advertised.  now it does. 
	  (main.c)

	+ fixed kbd_reply() so that starting a response with ^V now
	  clears the existing response -- it used to append the
	  quoted character instead.  (input.c)

	+ correction for showmatch mode when the left fence is the first
	  character in the buffer. (fences.c)

	+ better explanation of difference between "wrapword" mode
	  and newer "wrapmargin" mode.  (vile.hlp)

	+ added fallback define of S_ISDIR in path.c.

(tom)	951205 (b)
	+ corrected value of 'fname' in 'readin()' after calling 'ch_fname()';
	  this may have been the original bp->b_fname value, which is
	  reallocated when resolving a pathname (file.c).

	+ modified to check for null pointer return from 'create_msgs()'
	  (msgs.c)

(tom)	951203 (a)
	+ corrected logic of 'line_height()' to get rid of unwanted wraparound
	  on the last column of the screen when linewrap mode is set (display.c)

Changes for vile 5.5 (released Sun Nov 19, 1995)
(pgf)
	+ added tags file format information to vile.hlp.

	+ removed vmalloc.{c,obj} from makefile.{djgpp,wnt,blc}

	+ prevent ^T from inserting spaces if "notabinsert" is set. (insert.c)

	+ force two spaces after a ':' when reformatting paragraphs. (word.c)

	+ mention screen resolution control on PC in man page. (vile.1)

	+ trimmed trailing whitespace from vile.hlp.  where does that stuff
	  come from, anyway?

	+ fix forceblank() to consider lines containing whitespace to be
	  blank.  (random.c)

	+ call upmode() when resetting modeline format.  (eval.c)

	+ vms C compiler complains about folded pre-processor lines.  sigh.
	    (mktbls.c)

	+ added two new macro accessible functions, &local and &global, which
	  return the value of a vile setting.  for instance, "&global cmode"
	  will give the global cmode setting (true or false) and "&local list"
	  will give the local autoindent mode setting.  (modes.c, eval.c,
	  modetbl, macros.doc, vile.hlp)

	+ minor fixes for incremental searching: better tie-in with 'n' and
	  'N' commands, and uses CR as search terminator.  (search.c,
	  isearch.c, edef.h)  (from s.suresh)

	+ eliminate vttidy(), since it had degenerated to a simple
	  wrapper for ttclean().  call ttclean() directly in all cases.
	  (spawn.c, termio.c, version.c, file.c, main.c, proto.h, display.c)

	+ put TTkopen() call into ttunclean, so that keybad and xterm-mouse
	  translation get turned back on after a suspend or shell escape.
	  and then i removed it again.  the TI sequence for the linux
	  console homes the cursor.  not a good thing just before a
	  pressreturn().  but pressreturn() needs the termio stuff that
	  ttunclean does.  so they have to remain separate.
	  (termio.c, main.c)

	+ introduced swbuffer_lfl() which takes lockfl as arg.  swbuffer() is
	  a wrapper which calls swbuffer_lfl() with lockfl == TRUE (the old
	  behavior).  this allows getting rid of the early readin() that was
	  happening in bp2swbuffer() (due to the lack of a lockfl arg), which
	  was in turn causing read hooks to run too early, before the buffer
	  state (modes, name, etc.) was set up correctly.  (buffer.c, file.c,
	  proto.h)

	+ rearranged swbuffer_lfl to make sure it does the right thing
	  with inactive buffers.  (buffer.c)

	+ small addition to vile.hlp regarding where comments can appear
	  in command files (i.e. probably only on lines by themselves)

	+ i couldn't configure xvile on sunos 4.1.3 with X11R6 installed,
	  because the test link against -lXt failed, due to missing -lSM
	  and -lICE.  these have already been tested for and found, so i
	  added $X_PRE_LIBS to the check for -lXt.  this seems to fix it
	  and also seems benign.  is this right?  (configure.in, configure,
	  makefile.in)

(tom)
	+ corrected a bug in wrapmargin that caused it to split and alarm
	  at the wrong point (insert.c, word.c).
  
	+ corrected a bug in linewrap; when the user appended to the end of
	  a line longer than the window, the beginning of the line was
	  overwriting the modeline of the next window (display.c).

	+ modified termcap color support to work with rxvt 2.12 (tcap.c).

	+ rewrote logic for color mode-type to make it an enum-type, more
	  general, and made the visual-matches mode an enum (modetbl, main.c,
	  modes.c, search.c).  This makes name-completion work properly on
	  enumerated types.

	+ added 'default' enum value for termcap colors and added logic to
	  reset colors to default, i.e., orig_colors on exit (modes.c, tcap.c).

	+ modified color modes to be global, since we don't support per-window
	  colors anymore (modetbl, display.c, main.c).

	+ changed 'popup-choices' to a enum-type (modetbl, bind.c, main.c).

	+ make the 'spal()' function a member of the TERM struct to eliminate
	  unused/dummy functions, and to capture internal initialization
	  of 'palstr' (lot of places).

	+ corrected error in vile-manfilt that dumped core due to off-by-one
	  in realloc threshold, and fixed a memory leak (manfilt.c)

	+ added global mode 'resolve-links' to control whether vile resolves
	  and caches directory names (modetbl, main.c, path.c).


Changes for vile 5.4 (released Thu Oct 19, 1995)

(jrs)
	+ This revision provides improved support for Windows NT and
	  Windows 95.  The screen performance is dramatically faster
	  and a new completion mechanism is introduced which is
	  neither purely case-sensitive like Unix nor purely
	  case-insensitive like traditional MS-DOS.  This is used
	  to cleanly support case-insensitive but case-preserving
	  filesystems such as MS-DOS FAT with long filenames or
	  native NTFS.

	+ bind.c, proto.h: Add case insensitive flag to kbd_complete,
	  skip_partial, show_partial, show_completions, scroll_completions,
	  and fill_partial.  Take care to propgate case changes
	  which occur during completion to the keyboard input area.

	+ eval.c, modes.c: Change kbd_complete callers.

	+ dirstuff.h, makefile.wnt: Repair crufty WIN32 port.

	+ edef.h: Rename the operating system `windows/nt' as `win32'.

	+ estruct.h: Rework compiler and system defines so that
	  Visual C++ is detected and so that Borland C++ can be used
	  to compile the WIN32 version.  Also undef some more common
	  names like ABORT which pollute the namespace of many
	  environments.

	+ file.c: Make getfile2bp external so that it can be called from
	  main.  Use the canonical name instead of the supplied name
	  to form the buffer name for case-insensitive, case-preserving
	  filesystems.  This change makes `:e readme RET' for a file
	  whose real name is `README' have a buffer named `README'.

	+ main.c: Use getfile2bp instead of make_bp so file specified
	  on the command line behave more like found files; confer
	  the above example.

	+ filec.c, glob.c: Never lowercase WIN32 filenames and instead
	  compare them case-insensitively.  Pass case-insensitive flag to
	  kbd_complete on WIN32.

	+ path.c: For WIN32 call the new function realpath from
	  canonpath so that the preserved case of a filename is
	  reconstructed even though a different case was used to
	  access the file.

	+ termio.c: For WIN32 add prototype for ntgetch and don't call
	  kbhit.

	+ version.c: Discriminate between Turbo C and Borland C++ to
	  clarify and shorten the version string.  Add support for
	  Visual C++.

	+ makefile.blc: Yet another makefile for WIN32 (like makefile.wnt)
	  which uses Borland C++ instead of Visual C++.

	+ ntconio.c: Massive overhaul for performance, consistency,
	  bug fixes and new features.  The driver is dramatically
	  faster now because of reduced API transactions through
	  batching and because of avoidance of inherently slow functions
	  such as WriteConsole.  Correct a number of inconsistencies with
	  the other MS-DOS-like drivers such as the use of bright
	  white and clearing the screen upon exit.  Fix a number of
	  bugs such a bad interaction between kbhit and getch and
	  work around a bad bug in the Windows 95 implementation of the
	  WIN32 Console API.  Enhance the driver to support all of the
	  function and editing keys and some missing control-key
	  combinations.

	+ bind.c, filec.c: Temporarily disable case insensitive reply
	  correction for now since it doesn't work reliably and it only
	  provides a cosmetic advantage.

	+ estruct.h: Add a new option OPT_UNC_PATH for systems
	  which support Universal Naming Convention (UNC) pathnames.
	  Enable for win32.  Turn on ellipsis and range globbing on
	  win32.  Define new glob range negation characters (^ and !).

	+ filec.c, glob.c, path.c: Change numerous conditionals specific
	  to win32 to use the new OPT_CASELESS option.

	+ glob.c: Extend globbing to handle OPT_CASELESS.  Fix bug which
	  prevented ranges from working on any platform.  Implement
	  range negation.

	+ ntconio.c: Disable mouse support until the bugs are worked out.
	  Don't allow non-keyboard events to cause type ahead check to
	  loop forever.

	+ dirstuff.h: Clean up crufty ifdefs and defines for win32
	  directory operations.

	+ path.c: Correct faulty mapping between _getdrive and curdrive.
	  Rename realpath to case_correct_path and use it for OPT_CASELESS.
	  Handle UNC pathnames correctly during canonicalization and
	  case correction.  Fix bugs in case correction that showed up
	  because of differences between Windows NT and Windows 95.
	  Fix bug in internal name detection that prevented range globbing
	  from working at the beginning of a pattern (e.g. `[a-z]*').
	  Make pure system and share UNC pathnames (e.g. `\\system\share')
	  always appear as directories so completion on them works.
	  This works around a bug in the win32 file attribute semantics.
	  Be sure not to add `\*.*' to a directory that ends with `\'
	  in the the MSVC opendir replacement, add just `*.*' instead.
	  Fix monster memory leaks in MSVC readdir replacement and change
	  mechanism to allow multiple simultaneous open directories.

	+ makefile.wnt: Suppress annoying compiler banner.

	+ fileio.c: Work around another Microsoft bug and make ffsize
	  work reliably on files remotely mounted from Windows 95 systems
	  by using stdio instead of fstat.  Also use the default isready_c
	  because WIN32 stdio is either MS (which is like traditional
	  stdio) or Borland which is already handled.

	+ main.c: Only make '~' a wildcard character on Unix since we only
	  expand ~login on Unix.  This allows short filenames which contain
	  tilde to be expanded properly (e.g. C:\PROGRA~1 => C:\Program Files)
	  on WIN32.

	+ makefile.in: Add the WIN32 Borland C makefile to the official
	  distribution.

	+ npopen.c: Handle WIN32 like MS-DOS, not like Unix so that
	  command filtering works correctly without much effort.

	+ ntconio.c: Re-enable mouse input and completely rewrite the
	  mouse handling to use the generic selection code shared with
	  X11.  This change fixes a number of WIN32 mouse bugs and saves
	  about 100 lines of code.

	+ path.c: Rewrite case_correct_path for WIN32 so that it correctly
	  handles strings which grow on expansion such as those files
	  which include any short-name components.

	+ proto.h, select.c, x11.c: Compile the selection yanking code
	  on WIN32 and add an argument which controls which register to
	  yank into.  Change all callers.

	+ spawn.c: Remove crufty inclusion of sys/stat that seems not
	  to be needed on any platform.  Even if it is, it should be
	  safe to include it unqualified as it is in other files.
	  Change the default COMSPEC from cmd.exe to command.com on
	  WIN32 since there is no cmd.exe on Windows 95 but there is
	  a command.com on Windows NT.  In any case, COMSPEC is usually
	  set.  Enable filterregion code on WIN32 since inout_popen
	  now works.

(kev)
	+ x11.c (x_preparse_args): Make sure that the scroll bar GC has
	  the graphics exposures field set to false.  (The calls to XCopyArea
	  using the scrollbar GC are from a pixmap which will always be
	  copied in its entirety.

	+ x11.c: Changed resources so that default colors will be various
	  shades of gray.  This code is presently disabled.

	+ x11.c (copy_paste): #if'd out the code which caused pasting at
	  the beginning of a line to be put on the line above and pasting
	  at the end of a line to be put on the line below.  Just define
	  OLD_PASTE to be 1 if you want the old behavior back.

	+ x11.c (x_expose_scrollbar): Renamed from x_expose_pane.

	  (update_scrollbar_sizes): Set up an event handler for scrollbar
	  expose events.

	  (x_preparse_args): Removed call to set up expose event handler
	  for panes.

	  The above changes were made because popup menus (from other
	  applications) could cover up the scrollbar and not redraw it
	  properly (I don't really know why).

	+ x11.c (curs_sb_v_double_arrow, curs_sb_up_arrow, curs_xterm
	  curs_sb_down_arrow, curs_sb_left_arrow, curs_sb_right_arrow,
	  curs_double_arrow, curs_watch): Moved these out of struct
	  _text_win so that they are global.  This'll be handy for the day
	  when someone gets up the courage to actually create multiple
	  (top-level) X windows.  There's a lot of other stuff to be moved
	  out, but this is a start.

	  (slider_is_3D, scrollbargc_lt, scrollbargc_dk): New fields in
	  struct _text_win.

	  (alloc_shadows): New function which allocates pixels for light
	  and dark shading for a 3-D look.

	  (draw_thumb, update_thumb, x_expose_pane, x_preparse_args): Added
	  new code for drawing 3-D scrollbars.

	+ input.c (kbd_reply): Set reading_msg_line to FALSE _after_
	  popping down the completions window in order to ensure that the
	  buffer hook does not get run.  (It should not have been run when
	  popping the buffer up either, so when it's popped down, the
	  situation should be the same prior being popped up.)

	+ buffer.c (make_current, run_buffer_hook): Removed the message
	  line check from make_current() and moved it to run_buffer_hook. 
	  We do not want to run the buffer hook if reading from the message
	  line.  See below (I fixed this once before) for more information.

	+ modetbl (SMOOTH_SCROLL): New boolean mode.

	+ main.c (global_val_init): Initialize GMDSMOOTH_SCROLL value. 
	  Default is false so that it'll jump.

	+ display.c (update, updupd): Added additional test to the "return
	  early" code to enforce smooth scrolling if GMDSMOOTH_SCROLL is
	  set.

	+ main.c (main): Prevent curbp from pointing to an already
	  freed memory area.

	+ x11.c (sel_prop, selection_data, selection_len): Removed these
	  fields from struct _text_win.

	  (atom_TARGETS, atom_MULTIPLE, atom_TIMESTAMP, atom_TEXT): Added
	  variable declarations and initialization statements for these
	  atoms.  Initialization is performed in x_preparse_args().

	  (free_selection, x_stash_selection, strndup): Deleted  these
	  functions.

	  (x_get_selection, x_paste_selection, x_get_selected_text,
	  X_convert_selection, x_lose_selection, own_selection): New or
	  rewritten functions to use the Xt Intrinsics instead of Xlib for
	  handling selections.  In particular, xvile now handles the
	  following targets: TARGETS, MULTIPLE, TIMESTAMP, STRING, and
	  TEXT.  xvile should now be ICCCM compliant with respect to
	  selection handling.

	  (x_process_event): Removed all selection handling code.

	  [ Thanks to Brian Schellenberger (bts@unx.sas.com) for
	    contributing code which made xvile more ICCCM compliant.  I
	    used his contribution as a framework for x_convert_selection().

	    Chan Benson's "Implementing Cut and Paste in the X Environment"
	    (The X Resource, Issue 10) was also instrumental in making the
	    above changes. ]

	+ buffer.c (make_current): Prevent the buffer hook from being run
	  if we're presently reading from the message line.  In particular,
	  this will prevent the buffer hook from running when the
	  Completions buffer is popped up.  (:set and :setv were adversely
	  affected since these operations are often performed from one of
	  the buffer hooks and they are not reentrant.)

	+ filec.c (fillMyBuff): Changed the algorithm for non-VMS machines
	  to use qsort() (via sortMyBuff) instead of an insertion sort.  On
	  a 100 MHz pentium, this caused the cpu time needed to build a
	  completion list for a directory of roughly ten thousand files to
	  go from approximately 3 minutes to a mere 2 seconds.  (I know
	  that 10,000 files seems like a lot.  But one of my coworkers
	  discovered this performance deficiency in a directory with over
	  32,000 files.  xvile needed in excess of 14 minutes of cpu time
	  to build the completion list on a SPARC-20.)

	+ filec.c (qs_pathcmp, sortMyBuff): New functions.

	+ vile.hlp: Minor corrections.

	+ select.c (attributeregion): Only allocate memory for new attribute
	  when actually adding new attribute.  attributeregion() is also
	  responsible for deleting attributes.

	+ bind.c (engl2fnc): Make sure the binary search terminates.  Setting
	  shell variable VILEINIT to ./vileinit would cause engl2fnc() to
	  loop endlessly.  I now know that this was not the proper usage
	  of this environment variable.  But engl2fnc() still shouldn't
	  get stuck in an infinite loop.

	+ eval.c (gtenv, SetVarValue): Make sure that curbp is not NULL
	  prior to using it.  This can happen during the execution of
	  .vilerc.  The resultant behavior is not necessarily what the user
	  expects, but at least it doesn't cause a core dump.  For example,
	  put the following into your .vilerc:

		  ~if &seq $progname "xvile"
			set title $cfilname
			set iconname $cbufname
		  ~endif

	  I think the expected behavior would be to have $title and
	  $iconname in xvile take on the values of $cfilname and $cbufname
	  respectively.  But curbp is NULL when these actions are
	  performed.  I don't dare move any of the initialization code in
	  main() around or something else'll break.  [I'm not really all
	  that bothered by this behavior.  The "buffer-hook" variable works
	  well for this type of stuff.]

	+ fences.c (InDirection, simple_fence, fmatchindent): Fixed problem
	  in which closing right curly bracket was not getting indented
	  properly in cmode.

	+ input.c (kbd_reply): Don't erase default message if a completion
	  character is entered.  This takes Tom's fix to this code somewhat
	  further.  Scenerio: I enter ":e ../vile-5.3/fil".  It only
	  completes to ../vile-5.3/file.  At this point I too hastily hit
	  return (having mistakenly expected the completion to be unique). 
	  I realize my error and hit ":e " I see ../vile-5.3/file.  I press
	   and see the other completions (I have popup-choices set to
	  immediate).  I see the other completions and expect to be able to
	  modify the default response since I _have_ pressed a key _and_
	  the default response has not been erased.

	+ main.c (main): Fixed a small bug introduced in 5.3g which caused
	  xvile to core dump when given no arguments.

	+ main.c (cmd_mouse_motion,loop): Permit cursor to rest on the 
	  newline if it was placed there via the mouse.  This permits
	  the pasting of text at the end of the line. 

(pgf)
	+ get rid of #elif in display.c, for K&R compiler on HP/UX.

	+ set "scanbound_is_header" flag in oneliner.c when doing
	  line substitutions.  fixes broken :s/foo/bar/ commands.
	  (search.c, oneliner.c, edef.h)

	+ applied lee johnson's fixups to my changes for OS/2. (estruct.h,
	  os2vio.c)

	+ change name of variable used to cache interruptible pipe-read
	  results.  variables must contain '_cv_' to work correctly.  this
	  speeds up subsequent configure runs quite a lot, since the
	  pipe-read test is a looong one.  (aclocal.m4)

	+ applied fixes from purify'ing on HP from Warren Vik (path.c,
	  map.c)

	+ protect against null filenames (with BUG: report) in readin().
	  (file.c)
	
	+ add another OS/2 specific errno check to ffropen() (fileio.c)

	+ turn on prototypes for OS/2 and IBM compiler in mktbls.c

	+ set [Messages] buffer invisible and active to a) keep it from
	  being found by ":n" and b) keep readin() from being called on it.
	  (msgs.c)

	+ eliminated references to vmalloc code.  i haven't used it in
	  years, and there are better debugging libs available.  
	  (estruct.h, exec.c, file.c, makefile.in, undo.c)

	+ added ".cc" to the default cmode suffixes. (main.c)

	+ changed the deblank() routine to a forceblank() routine -- with
	  no arg still removes blank lines, but with an arg will force
	  that many blank lines at current point.  can be used to quickly
	  double-space some text, for example.  (random.c, cmdtbl, vile.hlp)

	+ minor change to help re-display code to better preserve DOT across
	  help invocations, and to prevent spurious moves if help is reinvoked
	  while still on-screen.  (bind.c, buffer.c, edef.h)

	+ remove usage of gets() from c-filt.c  (on recommendation of
	  runtime warning from gcc on freebsd...  imagine my surprise :-)

	+ fix c-filt.c to correctly recognize keywords which contain
	  spaces after the '#', as in:
	  	#if foo
		#  define bar
		#endif

	+ clean up bufhook so that the hook won't be called too early
	  in the case of being invoked from swbuffer.  that is, we
	  keep make_current from invoking the hook, since swbuffer
	  isn't ready (curwp may not be set up yet).  this let's
	  me run the C-filter macro as a buffer-hook.  (buffer.c)

	+ added the "< register, which contains the last few hundred
	  keystrokes typed.  actually, it will contain somewhere between
	  128 and 256 characters, since its limited to a single dchunk.
	  (estruct.h, map.c, line.c, vile.hlp)

	+ added "dotags" and "devonlylist" targets to makefile.

	+ applied patches to make ^T do a proper shiftwidth in insert
	  mode.  also be sure insertmode doesn't get reset by functions
	  called from insertmode.  (from grant mcdorman)  (insert.c)

	+ modify xterm-mouse code to allow its use with TERMs other
	  than xterm.  currently, if it's not really an xterm, then
	  the mouse reports are assumed to be zero-based rather than
	  one-based.  apparently some Amiga terminal emulator does
	  this.  this can be generalized if needed.  (from grant mcdorman)
	  (tcap.c)

	+ c-filt.c now supports "Literal" attribute, for highlighting
	  strings.  (c-filt.c, vile.hlp) (from ben stoltz)

	+ applied patch to support '?' searches in tags files.  (tags.c, from
	  eric krohn)

	+ implemented nvi-style infinite undo, which overloads '.' command
	  to continue undoing changes, if it immediately follows an undo.
	  added status message to help figure out which way (forward or
	  backward) you're going.  (cmdtbl, undo.c, main.c, vile.hlp)

	+ gave line_report() return value indicating whether it printed
	  message or not.  (random.c, line.c, globals.c, proto.h)

	+ suppress compiler warning in glob.c

	+ changed "Only one occurrence.." message to not beep, and not cause
	  popup messages if you hit it during startup.  this also means "terse"
	  mode will suppress it. (search.c)

	+ removed some dead "ifdef BEFORE" code and commented lines.  (undo.c
	  basic.c bind.c insert.c line.c)

	+ added gppconio.c to the distribution.  one of these days maybe
	  this can go away, when the fixes are incorporated in the djgpp
	  release.

	+ changed the test code in aclocal.m4 to always try and include
	  ioctl.h and sys/ioctl.h.  this makes it match the usage in
	  fileio.c.  the test code didn't have ioctl.h, therefore thought
	  we needed our own extern for ioctl(), and ours doesn't match
	  the freebsd prototype (theirs is variadic).  i seem to only
	  have autoconf 2.2, so if someone wants to rebuild configure
	  with 2.3, that's fine with me.  (aclocal.m4, configure)

(tom)
	+ corrected ifdef in path.c that broke vms compile.

	+ added configuration tests for prototypes, varargs.

	+ corrected missing flag in 'gotoline()' that caused reframing error
	  (basic.c).

	+ corrected off-by-one that made 'N' fail for pattern "." (search.c).

	+ added '\' and ':' to pathname-characters for MSDOS (main.c).

	+ corrected handling of "--with-CFLAGS" (configure.in)

	+ corrected allocation-size in resolve_dir (path.c)

	+ corrected logic of binary-search version of engl2fnc (bind.c)

	+ corrected off-by-one errors in text yanked by goto-matching-fence
	  command (fences.c, select.c).

	+ corrected translation of SEL_KREG in 'index2reg()' from '{' to '.'
	  (line.c).

	+ modified button1-release in xvile to yank the selection (x11.c).

	+ corrected 'updattrs()' to not highlight text that cannot be selected
	  e.g., line numbers (display.c)

	+ compiler warnings for DEC-C and Watcom 10.0a (estruct.h, fences.c,
	  filec.c, mktbls.c, npopen.c, os2pipe.c, os2vio.c, path.c, proto.h,
	  random.c, spawn.c, termio.c, vmspipe.c, vmsvt.c) on OpenVMS and OS/2.

	+ modified quoted-motion to interpret repeat-count as code for type of
	  selection: 1=exact, fullline=2, rectangle=3 (select.c).

	+ modified xvile to _not_ start display if only a "-V" option is given
	  (main.c).

	+ removed 'slash-char' mode, modifying code to use '/' for internal use
	  of MSDOS pathnames (filec.c, glob.c, modetbl, main.c, modes.c,
	  path.c, random.c).

	+ modified name-completion so that if we match _something_, typing a
	  character won't erase the buffer (input.c).

	+ revised manpage filter to allow for escape sequences that set
	  boldface/underlining -- this happens on OSF1 (manfilt.c).

	+ corrected code that supports OPT_XTERM >= 3 -- this is mostly for use
	  in demos since we don't handle text-position reports in :-commands,
	  for example (tcap.c).

	+ modified VALNAMES structure to have a side-effects function pointer,
	  replaced the inline logic in mode-setting with a table (modes.c,
	  modetbl, mktbls.c).

	+ modified logic that set up name-completion table for the combined
	  modes + variables to suppress "no"-prefix, etc.  Made related
	  changes to ensure that vile prompts for boolean modes set via ":setv"
	  (eval.c, input.c, modes.c).

	+ corrected logic that updates command-line display during name
	  completion (bind.c).

	+ modified mode-value completion to include booleans and colors, if the
	  enumerated value code is configured (modes.c).

	+ modified so that vile will prompt for reloading tags buffers when
	  user uses ":e" to view the buffer (file.c).

	+ modified to show the actual filename for the help-file (bind.c).

	+ modified to remember position in help-file when re-reading it (bind.c,
	  buffer.c).

	+ corrected adjust_forw, adjust_back functions to avoid returning
	  non-line location which broke reframing (window.c)

	+ corrected test in 'reframe()' for case where wrapped line was larger
	  than the window (display.c).

	+ modified to use w_line.o to store offset so that current position in
	  wrapped lines that are larger than the window still displays
	  (display.c).

	+ added configure test for ANSI_QSORT (aclocal.m4).

	+ modified test for nsl library to see if it's needed; otherwise this
	  breaks xvile on IRIX 5.3; the standard X library configure test may
	  also add this library (configure.in).

	+ linted on solaris and irix -- conversion and constant-conditional
	  (lots of places).

	+ make the case-insensitive code for WINNT a configuration option

	+ modified logic to make fake window & buffer to satisfy references
	  before vile starts screen mode (main.c, window.c).

	+ added "dumb" terminal driver to allow for prompting before vile
	  starts into screen mode (main.c, termio.c, dumbterm.c).

	+ modified file-completion on VMS to use kev's qsort improvement
	  (filec.c)

	+ corrected version-parsing for VMS filenames (vms2unix.c)

	+ corrected VMS filename-completion when user supplies "/" (filec.c).

	+ modified most exit-calls to do 'vttidy()' first (file.c, ibmpc.c,
	  main.c, vmsvt.c, version.c, termio.c)

	+ modified test-scripts for VMS to work across devices (descrip.mms,
	  vmsbuild.com).

	+ moved terminal/keypad-initialization into TTkopen(), and the matching
	  resets into TTkclose() so that "vile -V" works properly with the
	  dumb-terminal driver (tcap.c, termio.c).

	+ corrected off-by-one error in VMS shorten_path that caused ../SIO to
	  be shown as [-.IO] when cwd was ../SRC (path.c)

	+ enabled directory-completion for VMS (estruct.h).

	+ removed some ifdefs for apollo and CenterLine C that should be
	  obsoleted by the 'configure' script (estruct.h).

	+ moved TTkclose/TTkopen calls in fileio.c down to where they're
	  actually used -- spawning subprocesses -- to avoid spurious
	  reinitialization of the terminal in termcap mode (fileio.c,
	  npopen.c).

	+ corrected motions '(' and ')', which did not handle empty lines
	  like vi (basic.c).

	+ corrected handling of command-line '+' when argument is greater
	  than buffer length, and also ensured that initial-search string
	  doesn't conflict with contents of .vilerc (main.c).

	+ corrected logic of regstrchr, which did not skip '\' characters for
	  range-expressions.  This caused pattern "[<>]" to match '\' also
	  (regexp.c).

	+ modified ibmpc drivers to update current_res_name, so that vile will
	  restore the screen resolution after spawning a command (borland.c,
	  ibmpc.c).

	+ corrected logic for $buffer-hook so that it's not invoked unless the
	  buffer is the current window, so that editing commands work
	  (buffer.c).

	+ modified logic to enable 'readin()' to run $read-hook when reading
	  from a pipe -- which concludes with an FIOEOF code (estruct.h, file.c)

	+ corrected logic that sets the first buffer-pointer so that startup
	  scripts can manipulate it.  This implies that we'll always create the
	  unnamed buffer, just in case it's needed, and remove it after reading
	  .vilerc if it's unmodified.  Also remove, if possible, any stray
	  windows belonging to the unnamed buffer if a named buffer is
	  available, just in case .vilerc created windows (main.c).

	+ modified ffexists/ffaccess to check that their argument is really
	  a valid pathname (fileio.c).

	+ corrected logic that closed [History] buffer, which was resetting
	  'autobuff' mode, and warning message if :show-history was given when
	  history mode was off (history.c).

	+ corrected the check I'd added to ffexists/ffaccess (I'd used
	  maybe_pathname, which was requiring pathname-delimiters) to use
	  isInternalName instead (fileio.c).

	+ modified logic in execute-named-command to prevent accidental
	  invocation of commands (such as ":q!") when the command is terminated
	  by unexpected character (such as ) (exec.c).

	+ corrected logic that sets last_eolchar when interpreting macros,
	  so that commands such as "set nu lw" will work (input.c).

	+ modified logic so that saving the unnamed buffer to a file renames
	  the buffer (file.c).

	+ made mouse work for msdos+watcom configuration using polling (estruct.h,
	  ibmpc.c)

	+ updated makefile for watcom 10.0a (makefile.wat)

	+ corrected logic in wrap_at_col(), which sets the column at which the
	  wrapmargin mode activates; I'd used 'col_limit()' in an expression,
	  which broke when linewrap was set.  Also checked for end-of-line
	  before wrapping; this was an error in 'o' (insert.c).

	+ modified interface of 'getccol()' and 'getcol()' to pass 'list' mode
	  for the special case of testing wrapmargin (insert.c, random.c, etc).

	+ rewrote manfilt.c to handle more general escape and underline sequences
	  (manfilt.c).

	+ refined treatment of wrapmargin to trim trailing whitespace when a
	  tab/space is inserted past the wrap-margin.  This still isn't
	  _exactly_ what vi does (insert.c, word.c).

	+ corrected handling of ^D/^U/^F/^B scrolling commands for long wrapped
	  lines which weren't doing anything if the screen didn't display at
	  least two lines, and final position of ^B, which wasn't going to the
	  top of screen (basic.c)

Changes for vile 5.3 (released Tue May 09, 1995)
(pgf)
	+ implemented "watchinput" arg for the poll code in catnap().
	  (random.c)

	+ fixed the definition of VDISABLE to attempt to use _POSIX_VDISABLE
	  before using our own value. (termio.c)

	+ cleaned up path lookup (flook()) code, and the code that tries
	  to find our executable.  previously, we didn't know where the
	  executable was until someone used the ":version" command.  and,
	  we assumed that argv[0] could always be used to find us.  but
	  if argv[0] contains no slash chars, we can make no assumption
	  about where we came from.  there are still some problems in here,
	  because i think we sometimes try to run access() on things that
	  aren't quite pathnames yet.  (bind.c epath.h estruct.h main.c
	  path.c proto.h version.c)

	+ correct behavior of forwline()/gotoline() so that we get an error
	  if we try to go to a line beyond the end of the buffer.  (basic.c)

	+ don't check for '\r' on empty lines when counting doslines. (file.c)

	+ fix ".bak" style backups when the filename is of form ".foo".  now
	  change this to ".foo.bak" rather than just ".bak".  (UNIX only)
	  (fileio.c)

	+ added TI/TE and KS/KE processing to tcapk{open,close}.  i don't
	  know that this is always right, but it fixes an xterm arrow key
	  bug in some cases.

	+ removed TI/TE part of above change.  it's not always right.  the
	  terminal open/close code needs serious examination.  sigh.

	+ removed broken ULTRIX ifdef in x11.c, which tried to support
	  KEY_Remove.  it was broken.  i _could_ make it work, but i
	  don't know what i'd bind it to.  (x11.c)

	+ fixed "arrow key during insert" bug introduced in 5.2, which
	  prevented arrow from moving beyond EOL when inserting.  (basic.c)

	+ vile will now warn and insist on ":q!" if not all edited buffers
	  are visited during the edit session (i.e. some are still
	  "unread").  this is for vi compatibility, since some people use
	  "ZZ:n" when moving through their files, and vile was quitting
	  after the ZZ.  (the routine anycb() has been renamed
	  any_changed_buf() as well.)  (main.c, buffer.c)

	+ a new mode, "warn-unread", which will suppress the above behavior
	  if it is turned off.  (modetbl, main.c)

	+ implemented "visual-matches" mode, which allows one to highlight
	  all matching occurrences of a search string when doing a search. 
	  that is, if i search for "foo", then all occurrences of "foo" in
	  the buffer will be highlighted (as specified by the value of
	  "visual-matches").  i did not allow for color -- only bold,
	  italics, underline, and reverse are supported.  this can be
	  added in the future, i suppose.  (modetbl, modes.c, main.c,
	  search.c, undo.c, estruct.h, vile.hlp)

	+ added command to clear visual-matches:  "clear-visual-matches",
	  bound to '=' by default. (cmdtbl, search.c)

	+ added concept of "ownership" to attributes, so that, for example,
	  search-string attributes can be cleared independently of selection
	  attributes or ctl-A sequence attributes.  (select.c, search.c,
	  estruct.h, display.c)

	+ added/changed text in README.CFG which describes what to do
	  when configure or the make doesn't work.  (README.CFG)

	+ reset the action of VDSUSP char under POSIX.  (termio.c)

	+ applied patch from rick sladkey, for borland.c fixups and djgpp
	  compilation:

	    Part 1: borand.c enhancement and bug fixes
	    + enhance borland.c so that scrolling regions are used
	      efficiently

	    + enhance borland.c so that individual characters are buffered
	      which makes certain conio packages much faster (e.g the DJGPP
	      one)

	    + enhance borland.c to handle PC-style function keys (e.g.  F1,
	      F2, PageUp)

	    + make the cursor-toggling code in borland.c, generic, optional
	      and turned off by default since a big blinking block is
	      horribly ugly

	    + fix the color handling in display.c so that the broken and
	      unusable garbf kludge in bor?color in borland.c is no longer
	      needed

	    + fix erase to end of page in borland.c so it actually works

	    + enhance the mode detection in borland.c so that the screen
	      mode does not need to be changed in the default case (i.e. 
	      when using the current mode)

	    + prevent borland.c from clearing the screen on exit so it is
	      like vile on every other display device (i.e it goes to the
	      lower left instead)

	    Part 2: misc bug fixes affecting the MS-DOS versions

	    + change the default msdos slash character to '/' instead of
	      '\\' because typing tab (for completion) after backslash
	      inserts a ^I instead which makes completion under MS-DOS much
	      less useful and fairly annoying

	    + fixed a null pointer dererencing bug in main.c which occurs
	      when the vile.rc file is being edited but it does not exist
	      yet

	    + enhanced makefile.djg so that either ibmpc.c or borland.c can
	      be used and so that borland.c is used by default

	    + fixed a bug in path.c that caused the first slash after a
	      drive letter not to be canonicalized properly (e.g. 
	      C:\FOO\BAR => c:\foo/bar)

	    + fixed a bug in path.c affecting DJGPP that caused relative
	      pathnames containing an explicit pathname to be corrupted
	      (e.g.  C:FOO => ../:/foo) by deleting incorrect code whose
	      intention is solved by the previous fix

	    + omit a conflicting prototype for delay which I don't know who
	      needs but it can't be used as is on all platforms

	    + fixed a fairly serious bug in file.c that causes the file
	      size to be computed incorrectly at startup on dos-mode files
	      which caused an explicit write of an unmodified buffer to
	      append garbage to the file because the size was overstated by
	      the number of returns in the file which have already been
	      deleted but not yet subtracted from the count

	+ further changes to make rick's changes work okay under watcom.
	  the DOS path-deliter is now selectable, with "set slash-char". 
	  (edef.h, estruct.h, file.c, filec.c, fileio.c, glob.c, input.c,
	  modes.c, modetbl, path.c, proto.h, random.c, vile.hlp)

	+ added in patch from Russ Herman which fixes kbhit() problem with
	  function keys in OS/2.  (borland.c)

	+ eliminate FAIL macro in regexp.c, since it saves very little,
	  and is hard to write correctly without _someone's_ compiler or
	  lint complaining about it.  (regexp.c)

	+ fix infinite loop caused by null search patterns (e.g. ".*" or
	  "^".  (estruct.h, search.c)

	+ got rid of vestigial "tungetc()" code.  (input.c, proto.h, edef.h)

	+ fix (quickly) the broken @a-in-a-macro problem. (map.c)

	+ added ifdef'ed code which allows logging all keystrokes to
	  a tempfile, which can help when trying to recreate rare bugs.
	  (map.c)

	+ modify regstrncmp to take use system strncmp when possible.
	  (regexp.c)

	+ made "fence" characters (i.e {,}.(,),[,]) configurable by
	  user (new mode, "fence-pairs"), so that < and > can be added
	  easily (i hear this is useful for html editing).  (fences.c,
	  insert.c, main.c, modes.c, modetbl, proto.h, vile.hlp)

	+ added patch from anthony shipman, to keep X11 selections from
	  starting unless at more than one char is swept.  (x11.c)

	+ added a binary search to engl2fnc, but it's not quite right.  i
	  was in a hurry.  it's ifdefed.  (bind.c, externs.c)

	+ minor efficiencies in regstrncmp and regstrchr.  (regexp.c)

	+ interrupted() is now a macro again, when appropriate.  this
	  speeds up simple searches to run something like 10% faster.
	  (main.c, edef.h, estruct.h, proto.h)

	+ fix cosmetic message bug when 'q' command is ended immediately
	  with another 'q'.  (select.c)

	+ fix forwchar() to work as advertised.  from a user's point
	  of view, it now skips the newline if no arg is given, so it
	  can move across lines.  this meant some places where it was
	  called with default args internally had to be changed. 
	  (basic.c, word.c)

	+ force an update() in reposition(), so that "redraw-display"
	  can be used in a macro to force an incremental screen update.

	+ fix typo in cmdtbl.

	+ created pictmode.rc, a primitive "mode" which assists in
	  drawing ascii "art".  not that i've used it much yet...

	+ changed cbuf[2] in replacechar() to cbuf[NLINE].  apparently
	  the length arg that is supposed to prevent overruns doesn't
	  work, if you do a command like "replace-char %keywas", i.e.
	  use a variable to provide the response. (insert.c)

	+ added ISO-8859 characters and punctuation to ispunct() etc.
	  classes in charinit().  i assume this is "right".  (main.c)

	+ applied patches from Lee Johnson (71310.405@compuserve.com) for
	  support of OS/2 from the IBM C Set ++ Compiler (2.x).  changes
	  mostly to pipe support, directory access, and file completion.
	  new makefile (makefile.icc), new screen (os2vio.c), and new pipe
	  routines (os2pipe.c).  (borland.c, buffer.c, dirstuff.h,
	  display.c, edef.h, estruct.h, file.c, filec.c, fileio.c, glob.c,
	  makefile.in, mktbls.c, modes.c, npopen.c, path.c, proto.h,
	  random.c, spawn.c, termio.c, version.c)

	+ fixed --with-cflags option to configure script (configure.in,
	  configure)

	+ add another mention of ctrl-button functions, in the button
	  section of help file.

(tom)
	+ modified configuration scripts to conform to autoconf 2.2
	  (aclocal.m4, configure, configure.in, dirstuff.h).

	+ modified select.c to recover from manfile error that produces
	  empty attribute-region (select.c).

	+ removed "#error" for SunOS's K+R compiler (line.c).

	+ modified to make OPT_MAP_MEMORY and SMALLER configurations compile
	  (cmdtbl, display.c, search.c

	+ modified tmp.c to use calloc on page/chunks to appease Purify.

	+ added auxiliary programs to lint-rules (makefile.in).

	+ use void-casts for strcmp, lsprintf, etc., (lots of places), and
	  FALLTHROUGH comments for SunOS and IRIX lint (display.c, main.c,
	  oneliner.c, wordmov.c)

	+ removed redundant ';' after FAIL() macros that causes IRIX lint
	  warnings in (regexp.c).

	+ mods for miscellaneous lint (csrch.c, exec.c, filec.c, insert.c,
	  main.c, modes.c, proto.h, region.c, tcap.c).

	+ added stdarg.h to configure.in test so ANSI_VARARGS will work.

	+ modified lint ifdef's for ANSI_VARARGS  case, tested
	  with IRIX lint (estruct.h).

	+ added configuration tests for 'errno', 'time_t', 'off_t'
	  (configure.in, aclocal.m4).

	+ split-out neproto.h (from nefunc.h); cleanup gcc's -Wnested-externs
	  and -Wredundant-decls warnings (mktbls.c, estruct.h, proto.h, etc.)

	+ use IRIX lint to find/modify functions that can be made static
	  (proto.h and several modules...)

	+ corrected logic in makefuncdesc() and fnc2kcod() that caused vile to
	  ignore the user-defined key bindings (bind.c).

	+ modified mlreply_file() to handle the ^R!shell-command case (filec.c)

	+ corrected ifdef that broke 'slash-char' mode when compiling
	  SMALLER (main.c, modes.c).

	+ modified wildcard-expansion for VMS to handle comma-separated lists,
	  and /readonly option.

	+ corrected tab offset in 'vtputc()' so that linewrap displays properly
	  with various tab sizes (display.c).

	+ added ifdef to use MAXPATHLEN if it is defined in 
	  (estruct.h).

	+ adapted code by kev to resolve directory names which may contain
	  embedded symbolic links (path.c, configure.in).

(kev)	
	+ display.c (l_to_vcol): Make sure that we don't try to examine
	  characters which are past the end of the line.  Also compute
	  non-varying parts of the loop condition in advance for efficiency.

	+ configure.in: Don't use grep to pick out -D lines since some
	  versions of grep limit the number of characters which are output.

	+ search.c (attrib_matches): Start DOT out at the head of the buffer
	  to attribute matches for instead of at the first line.  This will
	  cause the first character in the buffer to be highlighted if
	  deserving.

	+ search.c (attrib_matches): Added new code for attributing with
	  color.

	+ modes.c (fsm_mono_attributes): Added color to this list.  Hmm...
	  "color" doesn't seem to be a "mono" attribute, does it?


Changes for vile 5.2 (released Thu Feb 23, 1995)
(pgf)
	+ added vile-c-filt to the man page.  (vile.1)

	+ remove root cause of"Cc" core dump -- no longer
	  allow an extra amount of right-motion just 'cuz we're in insert
	  mode.  whatever the reason for this extra was, it doesn't seem
	  to be necessary anymore.  recoded remaining conditions for
	  clarity.  (basic.c)

(kev)
	+ estruct.h (OPT_COLOR): Don't define in terms of DISP_X11.  This
	  fixes the ":set all" core dump.  OPT_COLOR indicates that the
	  older (line-by-line) color mechanisms should be used.  These
	  mechanisms are stubbed in x11.c, but are not implemented (and
	  probably won't be).  My recent change to NCOLORS (for DISP_X11)
	  made some OPT_COLOR ifdef'd code in modes.c break (there are only
	  eight entries in the cname array but there are now sixteen
	  colors.) So rather than put NCOLORS back to 8, it seemed more
	  expedient to simply disable all of the OPT_COLOR code which xvile
	  was never able to make use of anyway.  We should also probably
	  take the OPT_COLOR related ifdefs and stubs out of x11.c.

	  (VIDEO_ATTR): Make sure that this is typedef'd to be a short
	  when DISP_X11 is defined.

(tom)
	+ corrected core dump when user types "Cc" (line.c).

	+ change "defined(sun)" to "SYS_SUNOS".  (finderr.c)
	  
Changes for vile 5.1 (released Tue Feb 21, 1995)
(pgf)
	+ fix longstanding bug when keyboard macro is executed while
	  it is being recorded.  (input.c)

	+ fixed broken beginDisplay/endofDisplay nesting in xterm-mouse
	  code, which caused lockups after a resize operation. (tcap.c)

	+ fixed misspelled ifdef which caused filename truncation when using
	  "tilde style" backups.  (fileio.c)

	+ changed "X11" to "DISP_X11" in vmsbuild.com and descrip.mms.

	+ fixed OPT_REVSTA ifdefs so modeline reverse-video can be turned
	  off.  (display.c)
	  
	+ trimline() can be called with DOT.o == llength(lp), for instance
	  if a macro calls "end-of-line" followed by "append-string" where
	  the string starts with a CR.  trimline() was trimming (or not,
	  didn't matter), and then backing DOT.o up to the last char on the
	  line.  the CR would then break the line, instead of appending to
	  it.  this is probably a problem in other functions as well, if
	  called from a macro, since we don't do the "DOT.o can't sit on
	  the newline" hack while executing macros.  (region.c)

	+ replaced contents of c-filt.c with x-filt.c.  it seems to be a
	  full superset of its functionality.  it is now installed along
	  with manfilt, as vile-c-filt.  the help file now talks more about
	  it.  (c-filt.c, makefile.in)

	+ documented the color.[fb]color[1-16] subresources. (vile.hlp)

	+ included the c-filt.flx code contributed by alistair crooks in
	  the distribution.  (c-filt.flx, makefile.in)

	+ changed the "built" names of manfilt and c-filt to vile-manfilt
	  and vile-c-filt, to match their installed names, and to match
	  the documentation. (makefile.in)

	+ changed the new color resources to be {f,b}color[1-9,10-15],
	  rather than A-F as before. (x11.c)

	+ turned off IBM_VIDEO for linux.  it's not necessarily true.  
	  turned on OPT_COLOR for linux and DISP_TERMCAP, which is what we
	  were trying to imply with the above anyway.  (estruct.h)
(kev)
	+ patchlev.h (PATCHLEVEL): Updated to "c".

	+ x11.c (update_scrollbar_sizes -- NO_WIDGETS version):
	  Restructured loop which allocates new scrollbars and grips
	  somewhat.  In addition to no longer creating one more grip than
	  necessary, we also explicitly check to see which grips need to be
	  created.

	+ x11.c (check_scrollbar_allocs): Allocate the same number of grips as
	  scrollbars.  We don't actually need this many, but allocation in this
	  manner caused some subtle allocation problems with GROW().  GROW() was
	  being called as follows:
	  	GROW(cur_win->grips, Widget, oldmax-1, newmax-1);
	  When cur_win->grips is initially allocated, cur_win->grips is
	  NULL, oldmax is 0, and newmax is cur_win->rows/2.  Note then that
	  -1 is being passed as the third parameter to GROW().  This causes
	  newmax elements (rather than newmax-1 elements -- the number of
	  elements allocated) to be zero'd near the end of the grow macro.

	  The other piece of code affected (adversely) by this allocation is
	  in update_scrollbar_sizes() where new scrollbars and grips are
	  created.  It turns out that one more grip than necessary is created.
	  Under certain conditions, the GROW macro would zero out this extra
	  grip.  When reinvoked, update_scrollbar_sizes() would assume that
	  this extra grip had been created and not bother to recreate it.

  	+ patchlev.h (PATCHLEVEL): Updated to "a".

	[ Note: The following changes constitute the merge of Jukka Keto's
	  changes for color support to xvile.  Thanks Jukka! ]

	+ estruct.h (OPT_COLOR): Define in terms of DISP_X11, not X11.

	  (NCOLORS): Conditionally define this to be 16 instead of 8.

	  (VAFGCOL, VABGCOL): Removed.
	  
	  (VACOLOR, VCOLORNUM, VCOLORATTR): New defines.

	+ select.c (attribute_cntl_a_sequences): Color support.

	+ x-filt.c: New file.  This is Jukka's syntax coloring filter for C
	  programs.  I modified it slightly to compile clean under gcc with
	  Tom's favorite warning flags: -Wall -Wshadow -Wconversion
	  -Wstrict-prototypes -Wmissing-prototypes.  Also fixed a problem
	  with "'".  It also no longer requires an ansi compiler.  Note: It
	  should probably be merged with c-filt.  A command line switch to
	  [xc]-filt could be used to indicate whether monochrome or color
	  should be used.

	+ x11.c (struct _text_win): New fields colors_fgc, colors_bgc,
	  colors_fg, and colors_bg.

	+ (Xt{N,C}{f,F,b,B}color{0-9,A-F} i.e, XtNfcolor0,...): New
	  resource defines.  Kind of ugly to have to declare all of
	  these like this, but that seems to be the way its done.

	  (color_resources): Structure which defines the color subresources.

	  (x_preparse_args): Get the color subresources and initialize
	  the color GCs.

	  (x_setfont): Set new font for all of the color GCs.

	  (flush_line): Handle color attributes.  Also check for the
	  most common (default) attribute first for efficiency.
	  
(tom)
	+ corrected end-of-line problem with autoindent that broke 'append-string'
	  (insert.c).

	+ turn off 'access()' function for DEC C on a VAX as per bug report
	  by amish@data.uchicago.edu (estruct.h).

	+ added arrow-key definitions for VAX (vmsvt.c).

	+ corrected treatment of underlining in termcap driver (tcap.c).

	+ implemented termcap-based colors (tcap.c).

Changes for vile 5.0 (released Fri Feb 10, 1995)
(pgf)
	+ rearranged ifdefs leading to OPT_WORKING def'n for clarity.
	  (estruct.h)

	+ a couple of the new scratch buffer names were too long.  (edef.h)

	+ added commands for undoing system maps ("unmap-system-chars")
	  and abbreviations ("unabbreviate").  (map.c, cmdtbl,
	  vile.hlp, proto.h)

	+ NetBSD, FreeBSD, etc. all seem to define the termcap "kD" attribute
	  as DEL.  i consider this questionable, since they also produce
	  DEL from the Backspace key, but in any case, it means we shouldn't
	  define a system map for the DEL key.  we should really have separate
	  system maps for insert and command modes, but i think that might be
	  overly complicated.  so instead, i suppress the mapping of an ASCII
	  DEL to anything else (at the system level -- the user can still do
	  whatever they want.)  (tcap.c)

	+ renamed our signal() wrapper to setup_handler(), and always use it.
	  on systems with sigaction(), use it in place of calling signal() to
	  ensure system calls are restartable.  setup_handler() is now in
	  main.c, moved from termio.c (buglist, display.c, file.c, main.c,
	  proto.h, spawn.c, termio.c, x11.c, x11simp.c)

	+ use test for restartable reads on pipes rather than stock
	  restartable system call test, when trying to configure OPT_WORKING.
	  OSF/1 3.0 has restartable system calls, but reads (and writes) on
	  pipes will return EINTR regardless of SA_RESTART state.  they
	  call this a feature, based on the POSIX spec.  i haven't been
	  able to check.  (if you link against -lsys5 on OSF/1, you _can_
	  turn on OPT_WORKING.  but they claim that may be a bug, and
	  a "libsys5.a" may exist on other system, so i'm not going to
	  trust or use it.) (aclocal.m4, configure, configure.in, estruct.h)

	+ pasted characters now have the NOREMAP bit set, to prevent map
	  expansion of pasted text. (x11.c, estruct.h)

	+ changed token parsing to no longer treat ^L and ^M (i.e. formfeed
	  and carriage return) as whitespace.  this fix is mostly for :map,
	  so that carriage returns can appear in the lhs and at the start
	  of the rhs, but it should also allow those characters in other
	  response contexts as well.  (exec.c)

	+ implemented "flow-control-enable" command, which re-enables
	  software flow control for those users who still need it.  not all
	  implementations (posix/sgtty/termio) were disabling it in the
	  first place -- i'm surprised selections worked there (they may
	  not have.) (termio.c, cmdtbl, proto.h, vile.hlp)

	+ protect against infinite recursion when attempting to print
	  0x80000000 as a signed integer.  (display.c)

	+ changed file completion buffer to show the full prefix of the
	  thing that's being completed (patch from jukka keto). (bind.c)

	+ added jukka keto's c-filt.c program to the distribution. (c-filt.c,
	  makefile.in)

	+ changed HAS_ALARM define to HAVE_ALARM, and let it be autoconf'ed.
	  (estruct.h, configure.in, configure)

	+ added code in ffgetline(), which is where pipes are read, to
	  check for EINTR from a SIGALRM and redo the read() if we're
	  on a system where the read() isn't restartable. this lets
	  us turn on working on all system that have alarm(). THEN, i
	  backed this change out with ifdefs, since i think some old
	  kernels can lose data if they get a signal during a
	  read().  (fileio.c, display,c, estruct.h, edef.h)

	+ put start of child process status reporting in system_SHELL().
	  ifdef'ed it out, since the WIFSIGNALED etc. macros probably
	  aren't on all systems, and i don't want to break this release.
	  (npopen.c)

	+ introduce checks for SCO systems, which are probably not so odd
	  when compared with their peers, it's just that their peers have
	  all gone away.  (configure.in, configure, termio.c, estruct.h)

	+ fix globbing in root directory (i.e. ":e /j*k" now gets "/junk"),
	  and move DOS check for this same thing ("c:auto*.bat") slightly.
	  ensure what we don't end up with doubled or trailing slashes
	  ("//foo", "/foo/") anywhere, since DOS won't open those or stat
	  them properly.  (glob.c)

	+ fixed benign wp/curwp mixup in l_to_vcol().  (display.c)

	+ change expression for lint. (map.c)

	+ move ifdef for ANSI_QSORT into estruct.h, so it can be used in
	  proto.h as well as glob.c (proto.h, glob.c, estruct.h)

	+ added a couple of SIZE_T casts to keep "new ansi semantics" warnings
	  at bay.  (file.c, history.c)

	+ fixed some typos in the vile.hlp, added a version number, to
	  correspond to the version it's distributed with.

	+ change name of __MAXINT to not have __ on front, add cast to (int).
	  (display.c)

	+ changed the FL_PATH search order to look in the table first.  this
	  a) seems more correct, and b) will help ensure that the new helpfile
	  location (/usr/local/lib) will be checked before the old (which was
	  /usr/local/bin).  took /usr/local/bin out of the internal table.
	  i have more changes pending for this area, having to do with bugs
	  in how we determine where the executable came from.  but i'll hold
	  them until next release.  (bind.c, epath.h)

	+ added note about old helpfiles to README and README.CFG.

	+ added some more reminders for myself to the release_warnings
	  target. (makefile.in)

	+ created patchlev.h file.  include and use it it in version.c.

	+ added missing range checks to EXACTLY case of regrepeat() to
	  prevent going off end of line when matching 'cc*' on a line
	  that ends in 'c'. (regexp.c)

	+ fixed ifdefs for signal_pg(), to negate pid when killing a pgrp
	  with kill().  (estruct.h)

	+ moved setting of new process group out of x_open(), and into a
	  command, which can be used in a .vilerc if someone needs it.  it
	  seemed like the cases we were trying to catch were bugs in other
	  programs (shells and window managers).  this seems like the most
	  flexible approach, at least until i understand the problems a little
	  better.  (x11.c, main.c, cmdtbl, vile.hlp, proto.h)

	+ simplified, and moved non_filename() to version.c, so it can more
	  easily use the PATCHLEVEL string.  (proto.h, version.c, path.c)
	 
	+ changed PATCHLEVEL from a char constant to a string, for more
	  flexibility in naming patches.  duh.  (version.c, patchlev.h)

	+ added GNU General Public License to distribution, as required by
	  configure/configure.in.  (makefile.in, COPYING)

	+ tweaked/updated copyrights, added some vile specific caveats and
	  info to the COPYING file.

	+ reenabled '!' expansion in shell commands.  more vi's than not
	  seem to do it.  (input.c)

	+ arrange to check the X event queue when doing updates() during
	  a pipe read.  we were only checking in x_working() before, which
	  isn't called if "set noworking" or OPT_WORKING == FALSE. (proto.h,
	  x11.c, file.c)

(tom)
	+ modified column shown by ruler to be the actual cursor column, rather
	  than the effective column (display.c).

	+ made vms sys$/lib$ calls consistent (uppercase) to simplify greps
	  (path.c, random.c, termio.c, vms2unix.c, vmspipe.c, vmsvt.c).

	+ changed input-buffer size and error checks for vms to avoid
	  data overrun problems (termio.c).

	+ corrected glob-expansion for environment-variables, e.g., $FOO
	  (glob.c).

	+ updated tests for memory leaks (bind.c, map.c).

	+ corrected glob-expansion of msdos pathnames that use '/' (glob.c).

	+ corrected bug that prevented '!' from being inserted into shell
	  commands without being escaped (input.c).

	+ added command 'append-string' for symmetry with 'insert-string'
	  (insert.c, cmdtbl).

	+ modified vax scripts to compile on AXP hardware under OpenVMS
	  (descrip.mms, display.c, vms_link.opt, vmsbuild.com, vmsshare.opt)

	+ corrected shadowing of 'stat' in npopen.c

	+ added version.o: patchlev.h dependency to all makefiles.
	  (descrip.mms makefile.djg makefile.tbc makefile.wat makefile.wnt)

(kev)
	+ main.c (newprocessgroup): Changed XHAVE_SETSID to HAVE_SETSID.
	  Added HAVE_BSD_SETPGRP ifdef which is necessary due to the fact
	  that setpgrp on BSD systems requires two arguments.

	+ x11.c (scroll_selection): Sign extend row and col.  It's possible
	  to sign extend in fewer lines of code if we make certain
	  assumptions about the widths of ints, shorts, and longs.  Not as
	  portable though.

	  (extend_selection): Add scrolling timeout _after_ updating the
	  display.

	+ vile.hlp: did a lot of tweaking/rewording/correcting.

	+ display.c (l_to_vcol): Use wp->w_dot instead of DOT.  DOT uses
	  curwp which is not what we want here.  This problem was causing
	  core dumps when I got into xvile and did the following:

	  	:help
		/fmt

	+ x11.c (x_change_focus): Do not attempt to give ourselves focus
	  when focusFollowsMouse is true and we enter the window.  Also,
	  don't rely on the receipt of FocusIn/FocusOut events for deciding
	  whether or not to show the cursor.

	  (x_preparse_args): Set the XtNinput resource to TRUE in the
	  call to XtVaAppInitialize() instead of in a separate call to
	  XtVaSetValues(). [This is how Volume 4 in the O'Reilly series
	  recommends doing it].

	  (x_wm_delwin): Removed the unused WM_TAKE_FOCUS stuff from this
	  function.

	  (grip_moved): Removed superfluous "#if MOTIF_WIDGETS" / "#endif"
	  pair.

	  (scroll_selection): Cleaned up decoding of row and col.

	  (x_preparse_args): Took out WM_TAKE_FOCUS stuff.

This change log started on Wed Jan 11, 1995.
vile-9.8v/CHANGES.R6000066400000000000000000000371341415556424100140170ustar00rootroot00000000000000Changes for vile 7.0 (released Fri Feb 28, 1997)

(tom)	970228
	+ corrected OS/2 pipe problem, by closing dup'd file descriptors
	  (os2pipe.c).
	+ correct special IRIX 5.x -lsocket test, from 6.5c
	+ correct logic for VILE_STARTUP_FILE (main.c).
	+ correct a couple of uses of const (main.c, file.c).

(pgf)	970227 (e)
	+ fixed the mail sending in imdying.  i think it's been trying
	  to run the command "on host" for a long time now.  in addition
	  to simply fixing the command, and the printf arguments (which were
	  also broken), it now runs sendmail if it can find it, since
	  /bin/mail is not a reliable delivery agent anymore.  (file.c)

(tom)	970227 (d)
	+ ifdef'd function-key change to x11.c from 6.4d (reported by Graeme
	  Miller).
	+ add environment-variables VILE_HELP_FILE, VILE_STARTUP_FILE and
	  VILE_STARTUP_PATH to allow user to override default configuration.
	  (suggested by Andy Harper ).
	+ correct unused build-definition HELP_LOC from changes in 6.4c by
	  prepending it to $startup-path on initialization.

(tom)	970226 (c)
	+ fix additional nits for ffwopen() (reported by Graeme Miller and
	  Andy Harper).
	+ add workaround in configure script for users with Solaris 2.5.1 and
	  gcc configured for 2.4 or 2.5, due to gcc not shadowing term.h
	  (reported by Andy Harper , but my ISP has the
	  same problem)

(tom)	970221 (b)
	+ modify ffwopen() fix from 6.4a to work with DEC C (reported by Graeme
	  Miller ).

(kev)	970220 (a)
	+ x11.c (x_getc): Don't advance DOT after paste when in insert mode.
	  If we do, it goes too far.  Thanks to Philippe Chassany for finding
	  this one.

Changes for vile 6.5 (released Mon Feb 17, 1997)

(tom)	970210 (j)
	+ correct bracketing of shell-command buffer names from 6.4g (reported
	  by Paul Fox).
	+ modify filename completion to allow completion of "." and ".." as
	  non-directory leaves.
	+ fix some places (not all!) for gcc -Wcast-qual -Wwrite-strings
	+ some compiler nits for Visual C/C++ 4.0 on WinNT.

(kev)	970129 (i)
	+ x11.c (start_selection): Make sure that prevDOT is set to the DOT
	  in the window where the click occurs.
	  (x_process_event): In the Button3 "ButtonPress" code, set prevDOT
	  to DOT in order to sensibly handle the situation where the user
	  first marks the beginning of a selection by pressing Button1 and
	  then releasing it (without wiping) and then uses Button3 to mark
	  the end of the selection.  In this case, DOT will be left at the
	  location of the initial Button1 press.

(tom)	970125 (h)
	+ add limit-check to getcol(), in case mark.o is out-of-bounds.
	+ correct an indexing out-of-bounds in 'attribute_cntl_a_sequences()'
	  that Purify reported.
	+ add configure options for development (trace, dbmalloc, no-leaks).

(tom)	970119 (g)
	+ modify logic that forms buffer names so that shell commands will
	  be bracketed, thus avoiding an ambiguity.  This was reported by
	  pgf; he used ^X-e to open a file in the buffer list that was
	  a shell command.  Putting the cursor on the first '!' picks up
	  the remainder of the line as the shell command, which is wrong.
	+ apply fix from pgf for better description of ^A-d in vile.hlp. 

(kev)	970120 (f)
	+ x11.c (x_getc): Advance DOT by one after a paste so that default
	  position for newly pasted text is *after* the text just pasted.

(kev)	970120 (e)
	+ x11.c: Added resource controlling whether DOT is reset after making
	  a selection.  Also added/extended code for implementing this.
	+ vile.hlp (selectionSetsDOT): Documented this X resource.

(tom)	970119 (d)
	+ Restrict xvile's modifier + mouse-2 behavior to check only the shift
	  modifier (my system sets one of the modmap flags on all mouse
	  clicks).
	+ modify select/paste behavior in xvile so that the default pastes text
	  at the last cursor (or mouse-click) position before selecting
	  (requested by Jukka Keto )
	+ reset MK in set_curwp(), to avoid letting xvile cause DOT and MK
	  point to different buffers, which breaks getregion().  This happened
	  when the focusFollowsMouse resource was set (reported by Ralphe Neill
	  )
	+ add check for infinite loop in multimotion() (i.e., the 'q' command)
	  that might arise from xvile's switching the value of DOT in response
	  to mouse motion.  The loop happened because MK is a global rather
	  than per-window.
	+ check return values from getregion() in sel_extend().
	+ change default binding of KEY_F11 to execute-macro-11, for
	  consistency (does anyone have a keyboard w/o ?).
	+ add bindings for KEY_F21 through KEY_F35 and corresponding logic to
	  x11.c and tcap.c (from a request by Abraham V.  George
	  ), so that xvile & vile can recognize these
	  codes.  If they're not in a default binding, the KEY_Fxx aren't
	  defined.  Note that vile's are bound to 8-bit codes, so they're of
	  limited usefulness.
	+ modify mktbls to allow 8-bit codes in nefkeys.h
	+ corrected some places where WINMARK wasn't ifdef'd consistently,
	  as part of testing that configuration.

(tom)	970109 (c)
	+ eliminate epath.h by variables $startup-file and $startup-path.
	+ disable SIGHUP during normal quit/exit to workaround spurious "vile
	  died" message when I've spawned vile in an xterm from another process
	  (e.g., ded) on SunOS 4.x (this happens when doing :q! from vile with
	  a modified buffer).
	+ modify "print-prefixed-lines-til" command to print the buffer name
	  rather than filename, thus allowing any buffer except [p-lines] to be
	  indexed.
	+ modify configure.in so that nsl and socket libraries aren't tested
	  on IRIX 5.x, since those don't work with X11R5.

(kev)	970108 (b)
	+ configure.in: Added back in the tests for the nsl and socket
	  libraries which seem to be necessary in order for configure
	  to work cleanly on Solaris 2.5 with X11R6.

(tom)	970103 (a)
	+ correct an off-by-one in kbd_erase() that resulted in display
	  glitch in filename completion when the prompt-text was a very long
	  filename (bind.c).
	+ modify ffwopen() on VMS to propagate existing file permissions when
	  creating a new version of an existing file (requested by Robert J
	  Wright R.Wright@curtin.edu.au)

Changes for vile 6.4 (released Sun Dec 22, 1996)

(tom)	961216 (c)
	+ correction to infinite-loop fix in 6.3b
	+ add $helpfile symbol, initialized to "vile.hlp".

(tom)	961208 (b)
	+ added "print-prefixed-lines-til" command to print into [p-lines]
	  while prefixing the lines with filename and line-number.
	+ work-around Linux bug that causes 'getchar()' to return incorrect
	  value after an interrupt, so inserts of ^C would be garbled (input.c).
	+ guard against infinite loop which resulted from reverse search on
	  "$", resulting from 6.2a fixes (search.c).
	+ implement colored attributes in termcap driver (tcap.c)
	+ correct typo in cache-variable for VC_TYPE_OUTCHAR macro
	+ test with autoconf 2.12 (no change needed).

(tom)	961122 (a)
	+ modify handling of xterm mouse-click in insert mode to allow it
	  unless the click would move the cursor out of the current window
	  (requested by David McCoy).

Changes for vile 6.3 (released Mon Nov 18, 1996)

(tom)	961117 (g)
	+ moved xvile's translation strings out of fallback resources, since
	  these are ignored when a resource file is installed (e.g., in
	  $HOME/XVile or /usr/lib/X11/app-defaults/XVile), causing the
	  scrollbars to become unworkable.
	+ use 'newprocessgroup()' rather than 'fork()' for xvile -fork.
	+ correct threshold in updpos() so that when list mode is set, a ^J
	  in the last screen column (e.g., 80) will be visible.
	+ correct limits for whitespace-removal in 'inspound()' that caused
	  lines to join when inserting a '#' after typing ^D in an open-line
	  command (reported by Emil Rojas).
	+ modify so that '~' is not escaped when echoing previous value for a
	  string unless it was used in the special case of string replacement. 

(tom)	961113 (f)
	+ clarified special-character expansion in vile.hlp (Paul Fox).
	+ add alias to xvile for "-t" option to prevent it from superseding the
	  normal vile "-t" option (x11.c).
	+ added resources for xvile pointer shapes (x11.c) requested by Tim Su
	  .
	+ added -fork command-line option to xvile, to fork process after
	  initialization (main.c, version.c, x11.c) requested by Richard
	  Mitchell .
	+ added error handler so that xvile prints usage message if command
	  line parsing or Xt initialization fails (x11.c).
	+ add ifdef to file.c to accommodate missing extern for 'environ' in
	  djgpp 2.x (patch by Jerry Alexandratos).

(tom)	961107 (e)
	+ correct symbol conflict with shared library on OpenVMS 7.0 by
	  renaming opendir, etc., and tempnam.  Also, remove redundant rule for
	  vms_link.opt from descrip.mms (from logs by Sheldon E. Smith
	  ).
	+ correct sign-extension in ntconio.c that prevented display of 8-bit
	  characters (fix by Even Holen ).
	+ fix compiler warnings in borland.c (from logs by Jerry Alexandratos
	  ).
	+ correction to logic for "~endif", macros weren't re-enabled after
	  exiting an ~if/~endif (fix by Ian Jamison ).

(tom)	961105 (d)
	+ apply Brendan O'Dea's  followup patch to ensure
	  that "#", "%" and ":" substitutions aren't made in search/replacement
	  inputs.

(pgf)	961030 (c)
	+ apply brendan o'dea's patch to implement use of ~ in a replacement
	  pattern, to expand to the previous replacement.  this patch also
	  turns off the longstanding behavior of supplying the previous
	  replacement pattern as the default response to the "replacement
	  string: "  prompt.  i added a paragraph in the help file.  (estruct.h
	  input.c main.c oneliner.c search.c)

(tom)	961022 (b)
	+ modify 'showpat()' to show at least one highlighted space even if the
	  pattern is null, e.g., a '$' matching the end of line (oneliner.c).
	+ implement $forward-search variable (modetbl, eval.c).
	+ corrected "^$" pattern-matching broken in 6.2a (search.c).

(tom)	961019 (a)
	+ corrected logic of ~else/~elseif broken in 6.1a (exec.c), reported by
	  Timothy Phan .
	+ use new type IFSTK to combine if-stacking variables to clarify their
	  relationship (exec.c).
	+ modified macro trace to make if simpler to understand (exec.c).
	+ corrected boundary condition that prevented match of "\>" on the end
	  of line in search commands (search.c).
	+ corrected handling of command line arguments with similar buffer
	  names by prohibiting match against buffer names (main.c, file.c).
	+ corrected translation of '\\' in special case where it preceded a
	  potential metachar, causing search for "\\>" to fail (regexp.c),
	  reported by Emil Rojas.
	+ corrected wrap-around case in tags lookup where there was only one
	  match; using next-tag would report that there was no such tag
	  (tags.c).
	+ implement regular-expressions in cheap_buffer_scan(), making it work
	  with trailing "\>" emitted by ctags -N option (tags.c) reported by
	  Emil Rojas .
	+ add double-checks in swbuffer() and related logic to recover in case
	  $buffer-hook frees the current buffer (buffer.c), reported by
	  Sean Ahern .

Changes for vile 6.2 (released Tue Oct 15, 1996)

(tom)	961006 (d)
	+ correct filling of blanks for non-bce terminals, so the filling is
	  used only for color terminals (tcap.c).

(kev)	961004 (c)
	+ x11.c (update_scrollbar_sizes):  Make sure that grips are
	  managed properly when multiple windows are created at
	  startup.  Fixes David Snyder's "xvile -h" bug where it was
	  not possible to resize the two windows by grabbing the
	  resize grips.

(tom)	961004 (b)
	+ rename 'refresh()' to 'vile_refresh()', 'filter()' to 'vile_filter()',
	  to avoid naming-conflict when including  to support terminfo
	  driver.
	+ correct missing assignment for scanpt from 6.1a (exec.c).
	+ correct sign-extension problem in setup_dobuf() from 6.1a (exec.c)
	+ added (write-only!) $cryptkey variable (eval.c).
	+ don't attempt to set encryption on temporary buffers unless global
	  'crypt' mode is set (buffer.c).
	+ correct logic that reset local 'crypt' mode w/o restoring it, preventing
	  user from reading encrypted files (file.c)
	+ modify so that OPT_CRYPT and OPT_WORDCOUNT are normally configured.
	+ modify termcap driver to conditionally compile for terminfo libraries
	  so that if vile is built on a system such as Solaris that provides
	  termcap compatibility via terminfo, the color support will work.
	+ modify configure script to check for terminfo libraries.
	+ modify termcap driver so that if "op" (original pair) is defined,
	  fcolor and bcolor default to "default", for better compatibility
	  with color_xterm and dtterm (tcap.c).
	+ modify termcap driver to use "ut" capability to denote whether
	  background-color-erase (bce) is supported (tcap.c).

(tom)	960920 (a)
	+ allow continuation-lines in macros, denoted by a backslash at the
	  end of the line.
	+ add new directive "~elseif" (exec.c)
	+ restructured dobuf() using new function 'begin_directive()', fixing a
	  place where 'execstr' was modified w/o saving old value (exec.c)
	+ add new function 'no_such_function()' (bind.c, etc.)
	+ modified debug-trace in msg_putc() to work around Linux's printf
	  which calls strlen on all string arguments (msgs.c).
	+ modified to not use "#elif", since HP/UX K&R compiler doesn't handle
	  this (termio.c).

Changes for vile 6.1 (released Tue Sep 10, 1996)

(pgf)	960910
	+ added text to README and vile.hlp regarding possibility of
	  tom's taking over the source tree.  not completely firmed
	  up yet, but likely.  thanks tom!!!!

(tom)	960903 (d)
	+ adapted patch by Larry Schwimmer's (schwim@cyclone.stanford.edu)
	  for configure.in

	+ modify configure script to ensure that cached information is used
	  only on the system/version that was used to extract the data.

	+ remove (and correct rules for generating) vms_link.opt, vmsshare.opt

(pgf)	960812 (c)
	+ removed const from dirnam[] buffer in imdying.  removed cast
	  to (char *) which prevented any compiler in the world from
	  showing us this error.  grrr.  i hope no one else loses
	  work because of this one.  (file.c)

	+ fix minor warning from extern'd prototype in buffer.c.

	+ removed vile.man production rule from makefile.in.

	+ applied changes from martin zinser (m.zinser@gsi.de) for VMS
	  builds -- mostly casts, and some changes to the vms build scripts.

(jrs)	960809 (b)
	+ on NT reset the console input mode after a shell escape to fix
	  the problem reported by paul with ^C.  (ntconio.c)

	+ fixed a file corrupting bug caused by reading in a  file
	  which contained lines longer than 255 characters by accounting
	  for the possible fall-through of fastreadf into slowreadf in that
	  case.  (file.c)

	+ don't reset the keyboard when simply writing a file since it
	  causes an annoying screen flash with the new NT screen buffer
	  handling.  (file.c)

	+ some minor changes to prevent us accessing (not even dereferencing)
	  dangling pointers.  (buffer.c, file.c, itbuff.c, tbuff.c, path.c,
	  search.c)

	+ fix leak of the minibuffer window structure.  (window.c) 

	+ make sure ttgetc returns something on all platforms, even if
	  it isn't used.  (termio.c)

	+ make nthandler return a value (in case it ever gets called :-).
	  (ntconio.c)

(pgf)	960717 (a)
	+ applied rick's changes for proper operation in an NT command
	  window with scrollbars.  (ntconio.c)

	+ add target for formatting the man page, so a readable version
	  can go in the pc zip distributions.  (makefile.in)

	+ don't run the readhook for is_temporary() buffers.  (file.c)

	+ fix usage message. (version.c)

This change log started on Friday Jun 28, 1996.
vile-9.8v/CHANGES.R7000066400000000000000000002234541415556424100140220ustar00rootroot00000000000000Changes for vile 8.0 (released Sat May 30, 1998)

Changes for vile 7.5 (released Sat May 30, 1998)

	+ document problem with static initialization of union in CMDFUNC.
	+ review g++ warnings, use TYPECAST macro in the newer "harmless" const
	  warnings.

 (tom) 980529 (p)
	+ move mlsave[] into edef.h, updating logic so that the last error
	  message during initialization will be displayed properly.
	+ add logic to main.c to popup messages generated during initialization
	  as per popup-msgs mode (reported by Brendan O'Dea).
	+ modify logic for do_source() so that no error is reported if the
	  default .vilerc is not found (reported by Brendan O'Dea).

 (tom) 980528 (o)
 	+ fix minor memory leak in free_majormode()
	+ add a "+fork" option to xvile to override forkOnStartup resource.
	+ add search.pl to the list of supported Win32 perl scripts and add a
	  usage comment to same (patch by Clark Morgan).
	+ plug hole in x_open by setting maxscrollbars to zero, fixing a
	  scenario where the Motif version would crash (patch by Larry Gensch).

 (tom) 980527 (n)
	+ make search rule for startup file and :so consistent - and always
	  using $VILE_STARTUP_PATH if the file is not found in the current or
	  $HOME directory - using new function 'do_source()' (reported by
	  Arnold Robbins).
	+ add Clark Morgan's name to the modules he wrote (w32cbrd.c, w32misc.c,
	  w32pipe.c).
	+ rename perl-api.doc to perl.doc, updated (patch by Brendan O'Dea).
	+ modify too-restrictive test for infinite loop in scanner() to work
	  with 'n' command after "?.*" expression (reported by Kevin Buettner). 

 (kev) 980525 (m)
 	+ estruct.h (do_mark_iterate): Restore location of
	  api_do_mark_iterate_helper to its pre-"l" position.  Moved
	  declaration of mp so that it's available for expansion of
	  api_do_mark_iterate_helper.
	+ perl.xs: Added Brendan O'Dea as an author.
	  (Vile::command, Vile::Buffer::command): Set discmd so that
	  prompts are not displayed.
	+ perl/search.pl: New file.
	+ makefile.in (search.pl): Added to PERL_SRC and INSTALL_PERL
	  variables.  Added install target.

 (tom) 980523 (l)
 	+ remove _WIN32 ifdef's from perl.xs, so that $VILE_LIBRARY_PATH
	  is supported on Unix as well.
 	+ add vile-pager script to macros directory.
	+ modify makefile.in to install Perl scripts in $(datadir)/perl
	  (reported by Kevin Buettner).
	+ correct typo in perl.xs: CODE where PPCODE should have been used
	  (patch by Kevin Buettner).
	> patch by Brendan O'Dea:
	+ some ifdef fixes for OPT_EVAL, OPT_NAMEBST and OPT_SELECTIONS when
	  extensions are disabled.
	+ correct placement of api_do_mark_iterate_helper() in do_mark_iterate
	  macro.
	+ quiet a warning in the Perl interface when an optional script is
	  not found for inclusion.
	> patch by Clark Morgan:
	+ modify the win32 build environment so that perl scripts are copied
	  from .\perl to %VILE_LIBRARY_PATH\perl
	+ modify perl.xs to patch the new library location into @INC

 (kev) 980522 (k)
 	+ perl.xs (mlreply, mlreply_dir, mlreply_file, mlreply_no_opts):
	  Use the PPCODE: directive instead of the CODE: directive.  Get
	  rid of assigning RETVAL and the OUTPUT: directive.  Use XPUSHs
	  to return the values.  Also changed the type to void instead of
	  SV *.

 (tom) 980521 (j)
 	+ modify first item in VILE_STARTUP_PATH to be $(datadir).
 	+ add *.pl to makefile.in's install rules if configured --with-perl
 	+ move *.pl to perl subdirectory
	+ move *.rc to macros subdirectory
	+ move *.doc to doc subdirectory, as well as README.MENU, renamed to
	  menus.doc, and README.CFG, renamed to config.doc
	+ minor fix for HPUX compiler options in CF_ANSI_CC_CHECK configure
	  macro.
	+ newer CF_IMAKE_CFLAGS macro adds IMAKE_LOADFLAGS to makefile.in
	+ add configure-test for strerror, use it if available (reported by
	  Ian A Watson).
	+ change 'strdup' call in select.c to 'strmalloc', to build on VMS 6.2,
	  with DEC C 4.1-001 (reported by Sackett Andrew
	  ).
	+ change c_action in Brendan's patch to a union, eliminating casts.
	> patch by Brendan O'Dea:
	+ Procedures now behave more like builtin functions--they may be bound
	  to keystrokes and listed in the [Binding List] pop-up (for which an
	  optional help string may be supplied):
		store-procedure foo "some descriptive text"
		...
		~endm
		bind-key foo ^A-f
	  this appears under `:describe-function foo' as:
		"foo"                           M-f
		  ( some descriptive text )
	  Notes/Bugs:
	    * describe-key doesn't work yet.
	    * setting the MOTION/OPER flag is not implemented for procedures
	      --not sure whether it ever could/should be.
	    * the method used to update the [Binding List] requires *lots* of
	      passes through the tree.
	  Perl stuff (strings to eval or coderefs) can also be put into the
	  command table under a name--described in the perl.xs comments.
		Vile::register grep => 'hgrep', 'recursive grep', 'hgrep.pl';
	  the Vile::register_motion and register_oper variants additionally set
	  the MOTION or OPER flag:
		*cb = \$Vile::current_buffer;
		Vile::register_motion 'my-forward-line-at-bol' => sub {
			$cb->dot((scalar $cb->dot) + 1, 0);
		};
		Vile::register_oper 'my-delete-til' => sub { $cb->delete };

 (tom) 980520 (i)
	+ correct force-console entry in modetbl (patch by Clark Morgan)

 (tom) 980519 (h)
 	+ correct const-cast warnings for x_set_icon_name() and
	  x_set_window_name().
 	+ correct fallback prototype for mktemp, which should not have a 'const'
	  parameter.
	+ vile-pas-filt should treat '_' as an identifier character
	  (reported by Radek Liboska).
	> patches by Clark Morgan for Win32 and Perl configurations (tested on
	  WinNT 4.0 and Win95):
	+ Winvile's read pipe and region filter operations now create implicit,
	  hidden console windows (i.e., black console windows don't pop up and
	  disappear anymore).  Exception:  Win95's command.com hangs if it
	  attempts to communicate with implicitly created consoles.
	  Consequently, a new boolean mode (called "force-console") has been
	  created which specifies whether or not consoles are created
	  explicitly prior to creating a child process or implicitly when the
	  child process is exec'd.  By default force-console is only set when
	  the host is win95 and the current shell is command.com
	+ Prevent ^C/^Break in a console subshell from kernel faulting win95.
	+ If the user's shell is a unix clone derived from the Bourne shell,
	  add an extra layer of quoting that preserves Unix argument semantics.
	  For more details, refer to the function mk_shell_cmd_str() in the
	  file w32misc.c
	+ new file w32misc.c + some common win32 code in w32pipe.c moved to
	  w32misc.c
	+ modify makefile.wnt to add two new build configurations to the Win32
	  env:  vile-with-perl and winvile-with-perl.
	+ add VILE_LIBRARY_PATH environment variable to perl.xs to locate
	  the help file.
	+ add new file mkprlenv.wnt, which is included by makefile.wnt

 (tom) 980515 (g)
 	+ modify quote() function to show the accumulated number for ^Vnnn.
 	+ change 'value' parameter of SetVarValue() to eliminate a const-cast
	  warning, which in turn led to applying const to TTrez interface.
 	+ change category of 'sideways' mode to allow setting it for internal
	  buffers, such as [Help].
	+ add a range-test for rows and columns in movecursor() to avoid
	  passing negative coordinates to tcapmove when setting the 'sideways'
	  mode.
	+ distinguish MS-DOS drives from UNC pathnames (patch by Ed Henderson)

 (tom) 980513 (f)
 	+ replace global variable curswval with the corresponding function
	  calls, make nextsw a function next_sw(), so that shift-width is
	  computed correctly as needed (reported by abigail@fnx.com and Ian A
	  Watson )
	+ correct handling of command-line options in crypt.c (patch by
	  Paul Fox).
	+ correct missing check for empty line in screen_string, which would
	  cause a core dump if :show-variables were run on an empty buffer
	  (reported by Ed Henderson , patch by Kevin
	  Buettner).
 	+ updated modes.doc to match implementation of fences.

 (kev) 980511 (e)
	+ api.c (api_motion): Revised the settings for the following
	  global flags: clexec, discmd, disinp, isnamedcmd.  Some of
	  these were not getting set or were getting set in such a
	  way so as to either cause core dumps or incorrect behavior.
	+ bind.c (kbd_erase, kbd_erase_to_end): Don't erase anything if
	  disinp is FALSE.  Reason: If we didn't display anything to
	  begin with, there should be nothing to erase.
	+ history.c (hst_append): Don't append to the history buffer if
	  disinp is FALSE.
	+ input.c (editMinibuffer): Make sure the input character is
	  added to the buffer when disinp is FALSE.
	+ perl.xs (svrs): New variable which represents the input
	  record separator.  This is necessary because the symbol
	  corresponding to rs is not exported from the Win32 DLL for
	  perl5.00402.
	  (perl_init): Initialize svrs.
	  (READLINE): Use svrs instead of rs.
	  (set): Call api_setup_fake_win() to make sure that local
	  sets are done to the correct buffer.
	  (set_region): Renamed from setregion.  setregion is still
	  maintained as an alias.  I'm not entirely sure I like the new
	  name better, but it is at least consistent with set_selection.
	  (selection_buffer, set_selection): New methods for getting/setting
	  the selection.
	+ proto.h, select.c (get_selection_buffer_and_region): New function.

 (kev) 980506 (d)
	+ fences.c (comment_fence): Call scanboundry() before calling
	  scanner() to set the scanner's boundary.  This fixes a bug
	  in which the corresponding fence would sometimes not be matched
	  due to an old scan boundary sitting in the middle of the region
	  delimited by the two fences.  A quick way to reproduce the bug:
	  Search for something in the middle of a multi-line comment.
	  Move your cursor to the beginning or end of the comment.  Press
	  the '%' to try to move to the other end of the comment.  Notice
	  that it doesn't.  (Or it does, if the bug has been fixed!)
	+ input.c (editMinibuffer): Some hacks for 'i', 'a', 'I', and 'A'.

 (tom) 980506 (c)
	+ modify getregion() to handle the special case where a region is given
	  extending to the end of file, e.g., "^A~]", when DOT is on the last
	  section, will set DOT to the first line past the file, e.g., the
	  buf_head line (reported by Adam Denton).
	+ modify return from kbd_reply() so that macros behave more
	  consistently with interactive use, by returning an ABORT when
	  name-completion fails.
	+ modify handling of mini-edit character to allow it to be bound to the
	  same code as abortc (e.g., escape).
	+ correct a case where entering mini-edit character would allow name
	  completion to exit from kbd_reply().
	+ modify handling of minibuffer editing commands so that non-motion
	  commands (such as 'i' and 'a') are treated as errors rather than
	  implicitly inserting them into the buffer.

 (tom) 980503 (b)
 	> patch by Clark Morgan
	+ correct bug that made winvile font-dialog die on Win95, using example
	  from Petzold for processing messages associated with the system menu.
	+ added a menu separator to the system menu
	+ gave "Font" a  keyboard accelerator
	+ added a cast to keep the compiler from barking about a call to
	  EnumFontFamilies().

 (kev) 980503 (a)
 	+ api.c (api_setup_fake_win, api_dotinsert): Set MDNEWLINE to
	  false when deleting a newline before the end of a file.
	  (api_dotgline): Unused, #if 0'd out.
	+ makefile.in (vile-perl-api.pod, vile-perl-api.doc,
	  vile-perl-api.html, vile-perl-api.man): New targets.  I'm going
	  to let Tom decide which of these should be installed and where.
	+ perl.xs: Converted the inline documentation to be almost pod
	  format.  There is still a preprocessing step needed to convert
	  to a pod file.  I also rearranged the order of the methods
	  so that they'd be roughly alphabetical.
	  (svgetline, svgetregion, svgettors): Don't look at end
	  marker any more to determine end of region.  Instead,
	  use the region length to keep track of how many characters
	  are left in the region.  (I added a comment on the problems
	  associated with the end-of-region mark to the code just
	  before svgetline()).
	  (setregion): Rewritten to call getregion() for setting up
	  the region.  This way the length gets set right.
	  (perl_default_region): Make sure the region is really being
	  computed by getregion().
	  (do_perl_cmd): Fixed the code so that range specs work
	  again.

Changes for vile 7.4 (released Fri May 1, 1998)

 (tom) 980501
	+ change table lookups in match_complex() and global_val_init() to
	  work with CSet.
 	+ change WATCHTYPE from an enum to an unsigned int, since TurboC did
	  not accept that in prototypes.
	+ increase LEN_BUFFER in mktbls.c to accommodate renaming of VI_NL
	  (caused compile problem with Solaris 2.5.1 cc, but is still limited
	  to allow test-compiles with TurboC).
	+ make declarations of x_watchfd() x_unwatchfd() consistent, to compile
	  with unproto on SunOS 4.x

 (kev) 980429 (za)
	+ finderr.c (predefined): Add hgrep pattern to the predefined
	  regular expressions for the error finder.  (Patch from Clark
	  Morgan.)
	+ hgrep.pl: Added Clark's error finder comment.
	  Removed comment about me about to make massive changes which'll
	  change the interface drastically.
	  (hgrep): Don't search in files named 'tags'.  (Suggested by
	  Clark Morgan.)
	+ eval.c, proto.h (stenv): New function for setting vile's
	  variables (from perl or wherever).
	+ perl.xs (working): Added OPT_WORKING ifdefs.  (Description
	  of problem from Clark Morgan.)
	  (set): Handle perl variables as well as modes.
	  (buffers): New method which retrieves a list of all buffers.

 (tom) 980429 (z)
 	+ trim trailing whitespace from .c and .h files
	+ implement font-selection in winvile, added to control menu.  This
	  works passably, though you must press ^L to repaint if the character
	  size does not change. (Italic fonts are clipped a little also, but usable).
	+ add logic to ntwinio.c so that winvile user can use control modifier
	  to mouse button to perform rectangular selection, as in xvile
	  (requested by Richard A Ward ).
	+ correct ":e!" command so that if user asks to reread the unnamed
	  buffer, that vile simply clears it, rather than passing a null
	  filename to readin() (reported by Keith Williams
	  ).
	+ rename symbol NL to VI_NL, and the termcap symbols in tcap.c
	  to use "tc_" prefix to avoid conflicts with curses.h on OSF/1 3.2
	+ add pas-filt.c and corresponding vile-pas-filt program (request by
	  Radek Liboska )
	+ modify c-filt.c so that it reads all command-parameters as keyword
	  files.
	+ correct two errors in c-filt.c (did not handle continued string
	  literals - reported by Clark Morgan - and did not handle preprocessor
	  lines with leading whitespace.
	+ correct minor formatting nit in [Settings] buffer, adding a blank
	  line between the multi-column and single column buffer settings.
	+ make a more-useful message when describe-function is applied to
	  a user-defined procedure.
 	> patch by Clark Morgan:
	+ Winvile gets its own unique $progname value.
	+ The ';' register is made accessible to all versions of vile.  The
	  availability of the ';' and '.' registers to all versions of vile is
	  documented in vile.hlp .
	+ New win32 mode called "scroll-pause" added, which inserts a small
	  delay in the console editor's scrolling code if required by user's
	  video HW.  Documented in vile.hlp .

 (kev) 980427 (y)
	+ history.c (WillGlue): Allow '\r' to be glued.
	  (edithistory): Transform '\n' into '\r' for insertion into the
	  history buffer.
	+ input.c (eol_history): Allow '\r' to match '\n'.
	+ modes.c (choice_to_code): Do case insensitive comparisons.  This
	  permits TRUE and FALSE to be used as boolean values as well as
	  'true' and 'false'.  (The perl interface was being given the
	  uppercase values to return.  Though it could be argued that I
	  should maybe convert these to 0 and 1...)
	  (adjvalueset, set_mode_value): Split functionality of adjvalueset
	  into adjvalueset which (still) does the prompting and the
	  new function set_mode_value which does the setting.  Having
	  a setter which does no prompting makes it easier to call from
	  other places (like the perl interface.)
	+ proto.h (set_mode_value): New declaration.
	+ perl.xs (perl_prompt, perldo_prompt): More or less renamed
	  from the old perl and perldo.  perl and perldo still exist,
	  but they are small wrappers which make managing the history
	  easier.
	  (current_position): Alias for dot.
	  (READLINE, mlreply, mlreply_no_opts, mlreply_file, mlreply_dir):
	  Put calls to hst_glue() in so that the history mechansism will
	  work right.
	  (Vile::set, Vile::get, Vile::Buffer::set, Vile::Buffer::get):
	  New methods.

	  Brendan O'Dea contributed the following changes to perl.xs:

	    I have nuked the original perldo/replace_line mechanism
	    and arranged such that both perl and perldo feed a string
	    to eval to the same [static] function after getting the
	    user's input.

	    The perldo wrapper massages the string into an implicit
	    loop if required in pretty much the same way as Perl does
	    for the -n/-p options.

	    Additionally I've modified the way PRINT works to the
	    minibuffer so that it handles embedded newlines and joins
	    on $,

	    The options format is almost the same as used by perl, and
	    defaults to `-lpi' which was how it originally worked.
	    Example:

		:r $MAIL :%perldo print if /^From /^M-00ni

	    Two minor problems are that the history pastes the options
	    onto the command, and there is a minor glitch with `-lpi'
	    which causes a trailing newline to be appended to the
	    buffer.

 (tom) 980426 (x)
	+ modify :-line line specification parsing so that statements such
	  as
		:.,.+2,+3,-4;99p
	  work as in vi.  Both the repetition for commas and the character
	  class for semicolon were missing.
	+ modify :-line line specification parsing so that statements such
	  as
		:1,w filename
		:.w filename
	  work as in vi.  Vi accepts an empty string (e.g., between the "," and
	  "w") as ".", and does not require that both limits in a range be
	  given.  Previous behavior of vile would prompt, in the latter
	  example, when the space after "w" is typed, for the number of lines.
 	+ corrected :-line parser bug which caused state hang, e.g, when
	  typing
		:a1
	  vile would be expecting a command verb when the '1' is read, so
	  it would only allow the user to abort the command.
	+ modify end-character parameter of readpattern so that it is not
	  necessary to escape a '?' when doing a reverse search.
	+ correct logic of set_rect_columns() so that reversed rectangular
	  selection (where DOT > MK) gives the right number of columns
	  (reported by Kuntal M. Daftary).
	+ remove spurious comma in enum WATCHTYPE (reported by Larry Gensch)
 	+ update README.MENU with "cmd" keywords for the examples of search
	  menu entries.  Other minor documentation updates.
	+ tested xvile with ElectricFence, doalloc and Purify.  (The problems
	  with 'working' mode did not appear on SunOS or Solaris, but did on
	  Linux).  Minor fixes to ifdef's to build the test configuration.
	+ remove chgd_fences callback from the newer regular-expression
	  fences modes, since that function applies only to fence-pairs.
	+ modify 'working' mode so that xvile simply sets the watch cursor.
	  Though the "working..." message would be nice to have, it introduces
	  problems with X Windows to cause events which may interrupt the
	  normal event processing.  The new scheme sets a flag which is tested
	  in the event loop; the watch cursor will therefore not appear
	  immediately, but it is still automatic.  (prompted in part by a
	  bug report by Mike Peercy ).

 (tom) 980424 (w)
	+ make xvile menu entries "work" which rely on executing from the
	  :-line, by using "cmd" prefix for "apropos", and new function
	  >s for describe-key.  (The "cmd" is a kludge - we should revisit
	  this later, since it does not help if we want to process parameters
	  from the macro before running out & reverting to the :-line).
	+ modify describe-key so that it prompts for a keycode which is not
	  mapped.
	+ add new function >s, which prompts for a keycode which is not
	  mapped, e.g., "#1" for function-key-1.
	+ add note to vile.hlp about the use of backtic in shell expressions
	  (patch by Clark Morgan).
	+ revised fences so that the C-preprocessor and C-comment functions
	  are parameterized in terms of regular expressions, making one mode
	  per expression.  As such, they are reusable for majormodes.
	+ remove logic from x11.c for is_color_cursor, to make cursor visible
	  on reverse-video areas.
	+ add new mode mini-hilite, which controls the appearance of the :-line
	  when user toggles into mini-edit mode.
	+ make ^G toggle in the :-line editing rebindable, as the character
	  'mini-edit'.
	+ correct logic for ^G toggle so that user can insert that character
	  into a reply by quoting it.
	+ correct core-dump due to vtinit() calling 'imworking()', which was
	  happening when executing a command such as ":!resize -s 24 80".
	+ correct core-dump when user types ^G^V in a :-line prompt (reported
	  by Shawn Halpenny ).

 (kev) 980422 (v)
	+ api.c (curwp_visible): Renamed from curwp_after.  No longer static.
	  (linsert_chars): Don't suppress the newline when that's the
	  only character being inserted.  Thanks to Brendan O'Dea for
	  providing me with a test case which demonstrated this bug.
	  (api_motion): Set clexec and discmd to avoid printing on the
	  message line.
	  (api_swscreen, api_update): Don't detach the fake windows anymore.
	+ api.h (curwp_visible): Declared.
	+ estruct.h (is_fake_window): New macro.  Changed all callers
	  of is_fake_win() (which was a function) to call is_fake_window
	  instead.
	  (is_visible_window, for_each_visible_window): New macros.
	+ buffer.c, display.c, exec.c, file.c, finderr.c, history.c,
	  ibmpc.c, modes.c, oneliner.c, select.c, window.c, x11.c
	  (for_each_visible_window): Changed some occurrences of
	  for_each_window to for_each_visible_window.  Any code which
	  really needs to look at all the windows, whether fake or
	  visible still uses for_each_window.
	+ perl.xs (keystroke): Make sure that curwp doesn't point
	  at a fake window before attempting to get a keystroke.
	  Also fixed the nonwaiting version so that it works.
	  (beep): New method.
	+ proto.h, window.c (is_fake_win, detach_fake_windows,
	  reattach_fake_windows): Removed these functions.
	+ shell.pl: Extended it's functionality.  It now includes enough
	  terminal emulation to do some simple line editing.  (Enough for
	  bash to work in vi mode.)
	+ window.c (push_fake_win, pop_fake_win): Don't increment/decrement
	  the b_nwnd field of a buffer when pushing/popping.  This field
	  indicates the number of visible WINDOW structures that a buffer
	  has.  (#if 0'd out for now.  Need to remove altogether at some
	  future date.)
	+ x11.c (grip_moved): Fixed both OpenLook and Motif versions so
	  that they don't delete the window when it is shrunk to a size
	  less than 1 line.  Although this make a certain amount of sense,
	  it can be quite annoying to a user to lose a window from a slip
	  of the hand.  Note that there are still some problems with this
	  code.  Windows that are made really small don't always end up
	  really small (reported by Paul Askounis).
	  (x_watchfd): Cast third argument of XtAppAddInput to an XtPointer.

 (kev) 980419 (u)
 	+ ansi.c, borland.c, dumbterm.c, ibmpc.c, ntconio.c, ntwinio.c,
	  os2vio.c, tcap.c, termio.c, vmsvt.c (null_t_watchfd,
	  null_t_unwatchfd): Added to term structure initializations.
	+ estruct.h (WATCHTYPE): New enumerated type.
	  (t_watchfd, t_unwatchfd): New fields in the TERM structure.
	  (TTwatchfd, TTunwatchfd): New macros for calling the watch/unwatch
	  functions.
	+ makefile.in (watch.c, watch.o): Added to the appropriate targets.
	+ api.c (linsert_chars): Made more efficient.  Handle newlines
	  at end of buffer properly.
	  (api_gotoline): Allow DOT to be position at end of buffer.
	  (api_motion): Fixed bug which was calling early return.  (Thanks
	  to Sean Ahern for finding this one.)
	  (api_swscreen): Detach/reattach fake windows.
	  (api_update): New function.
	  (propagate_dot): New function.
	  (api_command_cleanup): Call propagate_dot; don't do this work
	  directly anymore.
	+ api.h (api_update): Declared.
	+ buffer.c (renamebuffer): New function.
	  (namebuffer): Moved some of the functionality to renamebuffer.
	  Call renamebuffer to do the work.
	+ perl.xs (GIMME_V, G_VOID): Define in terms of GIMME and G_SCALAR
	  if not already defined.  (Thanks to Brendan O'Dea for pointing
	  this out.)
	  (perl): Don't do initializations/cleanups of Vile::current_buffer
	  if called recursively.
	  (perl_init): Cause Vile::Buffer::PRINTF to be defined.
	  (svcurbuf_set): Put return statement in.
	  (stringify_coderef, perl_free_callback, svgetline, svgetregion,
	  svgettors): New functions.
	  (INITMESSAGE, ENDMESSAGE): Removed these nvi remnants.
	  (PRINT): Handle input record separator and input field separator.
	  (READLINE): Rewritten to handle the record separator correctly;
	  call svgetline, svgetregion, or svgettors as appropriate.
	  (attribute_cntl_a_sequences): Pass the region shape when calling
	  attribute_cntl_a_seqs_in_region().
	  (fetch, attribute, buffername, filename): New methods.
	  (Warn): Minor cleanup.
	  (mlreply, mlreply_no_opts, mlreply_file, mlreply_dir):  Allow
	  either a TRUE or FALSE status to set the return value to a
	  string.  The other status codes cause undef to be returned.
	  Thanks to Brendan O'Dea for diagnosis and patch.
	  (command): Adjust the way docmd is called to match new extra
	  parameter introduced in patch t (or thereabouts).
	  (keystroke, working, update, watchfd, unwatchfd) New methods.
	  Also throughout this file (perl.xs), there was a lot of minor
	  reformatting.  A few new comments were even added.
	+ proto.h (renamebuffer, attributeregion_in_region, null_t_watchfd,
	  null_t_unwatchfd, watchfd, unwatchfd, dowatchcallback,
	  detach_fake_windows, reattach_fake_windows): Declared.
	  (attribute_cntl_a_seqs_in_region): New parameter.
	+ select.c (attributeregion_in_region): New function.
	  (attribute_cntl_a_seqs_in_region): New parameter for passing
	  the shape of the region.  Use shape parameter for setting region
	  up properly.
	+ shell.pl, tailf.pl: New example perl scripts.  Not really complete
	  yet, but they demo some of the new facilities.  (Maybe we should
	  create a demo directory?)
	+ watch.c: New file containing fd watching framework.  Will probably
	  add timer management here as well.
	+ window.c (detach_fake_windows, reattach_fake_windows): New functions.
	  Actually, I'm not convinced anymore that this is the right way to
	  do it and these will probably go away.
	+ x11.c (x_watchfd, x_unwatchfd, watched_input_callback): New
	  functions.

 (tom) 980417 (t)
	+ modify interface of 'docmd()' to allow caller to set clexec, allowing
	  menu.c to invoke this and cause commands to prompt interactively.
	+ modify 'get_executable_dir()' to use 'flook()' to deduce xvile's
	  location, so that new_vile menu-entry works when the full path is not
	  given (reported by Lance Heller ).
	+ restore search-behavior on DOS, NT and OS/2 for startup file.  These
	  systems have no $HOME, so we look along the $PATH.
	+ correct/extend configure test for isready_c macro:  add a case for
	  UWIN, check for end of list, add a definition for SYS_WINNT.

 (tom) 980414 (s)
 	+ correct change to dofile in 7.3o, which caused vile to discard
	  the startup file after processing it if it were specified on the
	  command-line (reported by Sean Ahern, some input by Brendan O'Dea).
	+ modify configure script, adding test for stdio structs that control
	  the isready_c macro, making this handle the case for SCO UW ver 7
	  (requested by Clark Morgan).
	+ modify configure script to add Perl's link-prefix (patch by Brendan
	  O'Dea).
	> patch by Clark Morgan:
	+ turn OPT_W32PIPES on (I modified to condition it on SYS_WINNT).
	+ add entry to error finder to support perl 5 diagnostics
	+ create temporary filenames in w32pipe.c with an API that
	  preferentially honors the current settings of TMP and TEMP.
	+ add back Win32-specific comments to c-filt.c
	+ fix a bug in c-filt.c that caused coloring to go south if a string
	  literal ended with \\.  E.g., the statement:
		char *x = "\\";
	  would cause almost all syntax coloring following this var declaration
	  to fail.

 (tom) 980412 (r)
 	+ modify configure script and makefile.in to allow for DOS-style
	  suffixes (e.g., ".exe"), needed for OS/2 EMX.
 	+ fix pathname support for OS/2 EMX by allowing MS-DOS-style drive
	  letters (estruct.h, path.c).
 	+ suppress 'working...' message while writing to a pipe (reported by
	  Clark Morgan).
 	+ add rule to make c-filt to makefile.djg
 	+ add writePipe() function to make MS-DOS version able to write to a
	  pipe.
	+ use backslash-form for path in c-filt.c on Win32 (Clark Morgan).
	> clipboard support for vile/winvile under Win32 (Clark Morgan):
	+ Permits Win32 users to copy the unnamed register contents to the
	  Windows clipboard.  Functionality is bound to Alt+Insert.
	+ Adds stubs for two additional clipboard-related features.  Stubs are
	  bound to Ctl+Insert and Shift+Insert.
	+ Adds a new Win32 source file (w32cbrd.c).
	+ Revises the "Win32 specifics" section of the help file to talk about
	  Win32 features.
	> new implementation of w32pipe.c (Clark Morgan):
	+ reset ukb to zero in filterregion() to avoid having insfile() insert
	  file/pipe input into a kill register, rather than the current buffer
	  on platforms where softfork() is faked.
	+ w32pipe.c module documentation lists limitation of native win32
	  pipes.
	+ winvile.exe and vile.exe are now built with thread-safe libraries,
	  because
	+ spawn.c's filterregion() routine has been modified to create separate
	  writer and reader threads in a Win32 env.

 (kev) 980409 (q)
	+ api.c (api_setup_fake_win): Added another parameter to this
	  function which controls whether the deferred deletes get
	  done or not.  Fixed all callers.
	  (api_dotinsert, api_dotgline, api_setup_fake_win, api_bp2vbp,
	  api_command_cleanup): Added code for doing deferred deletes.
	  (api_delregion, api_motion): New functions.
	  (api_edit): Rewritten to better deal with anonymous buffers.
	  (api_swscreen): Permit oldsp to be NULL.
	+ api.c, api.h, perl.xs (SCR, VileBuf): Renamed SCR to VileBuf.
	  Other renamings done as well so that names of local variables
	  make more sense.
	  (api_dotgline, READ): Added new (output) parameter to
	  api_dotgline which indicates if a newline is needed or not.
	+ map.c, proto.h (mapped_ungotc_avail): New function.
	+ perl.xs (svStartLine, svStopLine, svScreenId, svcurscr):
	  Eliminated these static globals.  More importantly, this
	  means that $VI::StartLine, $VI::StopLine, $VI::ScreenId,
	  and $curscr are no longer available from perl.
	  (svcurbuf): New static global which plays a similar role to
	  the now defunct svcurscr.
	  (svcurbuf_accessors): new static global variable.
	  (newVBrv): Renamed from newVIrv.  Also, no blesses the object
	  it creates into Vile::Buffer instead of VI.
	  (perl): Don't call getregion unless haveregion is non-NULL.
	  Fixes a nasty infinite loop bug in getregion().  Also
	  removed initialization of svStartLine, svStopLine, etc.
	  (VI, Vile, Vile::Buffer): The VI package is no more.  Everything
	  has been renamed to go into either the Vile package or the
	  Vile::Buffer package.
	  (svcurbuf_set): Magically called when $Vile::current_buffer gets
	  set.
	  (perl_init): Nuked references to svStartLine, svStopLine, etc.
	  Also added magic to svcurbuf so that svcurbuf_set is called
	  whenever $vile::current_buffer is assigned to from Perl.
	  (perl_eval): Or'd in the G_KEEPERR flag in the call to
	  perl_eval_sv.  The lack of this flag was preventing error messages
	  from getting printed.
	  (current_buffer): New method in both Vile and Vile::Buffer.
	  (Msg, AppendLine, DelLine, GetLine, GetLines, SetLine, InsertLine,
	  LastLine, SwitchScreen): Nuked.
	  (PRINT, READLINE): Documented.
	  (insert): Alias for PRINT.
	  (new, edit): edit is an alias for new and new was renamed from Edit.
	  (setregion): Documentation updates; motions as regions.
	  (delete, motion): New methods.
	  (command): Now a method in both Vile and Vile::Buffer.
	+ ptypemap (T_VileBuf): Renamed from T_VI.  Slight change in message
	  when buffer no longer exists.
	+ region.c (getregion): Prevent infinite loop when MK and DOT are in
	  different buffers.  Print a BUG: message when this happens.
	+ select.c (sel_extend): Added FIXME comment at approximate place in
	  the code where we should check to make sure DOT and MK are in the
	  same buffer.  (BTW, to reproduce this bug (where they aren't the
	  same), get into xvile, split the screen and put a different buffer
	  in each. Now click with the mouse twice, very rapidly, each click
	  falling on alternate sides of the middle mode line.  After doing
	  this, DOT will be in one buffer and MK in the other.  There's
	  probably other places that need to fixed too.
	+ x11.c (x_preparse_args): When adding the event handler, for
	  x_process_event, or in (Button1MotionMask | Button3MotionMask)
	  instead of ButtonMotionMask.  It seems that my X server on linux
	  generates motion events regardless of whether any mouse buttons
	  are pressed when ButtonMotionMask is used.  I think this is
	  actually a bug in the X server, but the above is a more precise
	  way of saying what we really want to do anyway.

 (kev) 980403 (p)
	+ hgrep.pl, glob2re.pl, visit.pl: New files which implement
	  a recursive grep with hypertext links in perl.
 	+ api.c (api_command_cleanup): Fixed bug in which DOT
	  was being propagated to the fake windows instead of
	  the real ones.  (Which is a pretty useless thing to do.)
	  (api_swscreen): Added big comment noting problems with
	  calling api_command_cleanup.
	+ cmdtbl (exechypercmd, showhypercmd, operattrhc): New
	  commands related to hypertext commands.
	+ estruct.h (AREGION): Added new field ar_hypercmd which
	  points at a hypertext command.
	+ select.c (hypercmd): New static variable used to communicate
	  the hypertext command string to attributeregion().
	  (free_attribs, free_attrib, sel_begin, selectregion,
	  attribute_region): All modified slightly to deal with the
	  new ar_hypercmd field in the AREGION structure.
	  (attribute_cntl_a_sequences): Look for an H followed by
	  the hypertext command, followed by a null character in
	  the ^A sequences.
	  (attributehyperregion, operattrhc, hyperspray, doexechypercmd,
	  exechypercmd, doshowhypercmd, showhypercmd): New functions.
	+ vile.hlp: Added new sections "Writing your own filters" and
	  "Hypertext".
	+ x11.c (multi_click): Added code to execute hypertext command,
	  when present, on a double click.

 (tom) 980331 (o)
 	+ change logic that determines whether to set dos mode for a file so
	  that .vilerc (or vile.rc) and source'd files are treated specially.
	  For those files, all lines must end with ^M's to set dos mode
	  automatically when they are read.  This will reduce the chances of
	  trimming ^M's from map commands.
	+ modify dofile() function, used to load/execute .vilerc and source'd
	  files, to check first for buffer with the same filename.  This fixes
	  a problem which would cause vile to allocate more than one buffer for
	  .vilerc when an error is encountered.
	+ use new function tb_insert() rather than tb_put() to insert strings
	  for expand-chars.  The tb_put() function truncates the buffer at the
	  location of the new character, and does not work well for inline
	  editing.

 (kev) 980330 (n)
 	+ api.c (api_gotoline): Make sure that we can move off of
	  buf_head if presently on it.  (This fixes a bug in which
	  it was sometimes impossible to move dot.  setrange also
	  exhibited a similar bug.)
	+ cmdtbl (perl): Allow perl to be run in view mode.
	+ perl.xs (perl): Set/restore clexec, discmd, and isnamedcmd
	  so that calls to the various mlreply functions will work
	  from within perl.  (Thanks to Sean Ahern for bug reports
	  and patches.)
	  (perl_init): Call lengthen_path to expand ~ to the user's
	  home directory.  (Thanks again to Sean Ahern for bug
	  reports and patches.)
	  (sv2linenum, sv2offset): New functions for converting
	  '$' and '$$' to either line number or offsets within
	  lines.
	  (VileCommand): Renamed to command.
	  (inplace_edit, setregion, dot, mlreply, mlreply_no_opts,
	  mlreply_file, mlreply_dir): Added documentation.
	  (setregion, dot): Handle '$' and '$$'.
	  (setregion): Return the buffer object in a scalar context.
	  (attribute_cntl_a_sequences, unmark): New functions.
	+ proto.h (attribute_cntl_a_seqs_in_region): Declared.
	+ select.c (attribute_cntl_a_seqs_in_region): New
	  function.

 (kev) 980324 (m)
	+ api.h (dot_changed): New field in SCR structure.
 	+ api.c (api_gotoline): Prevent enormous amounts of looping
	  for outrageous count values.
	  (api_dotgline): Fixed bug which caused <$curscr> operator
	  to go into infinite loop.
	  (api_command_cleanup): Added code for propagating DOT.
	  (api_bp2sp): Initialize dot_changed field.
	+ perl.xs (perl_init): Add our own search paths to @INC.
	  (dot): New method for getting/setting DOT.
	  (GetUserInput): Removed.
	+ proto.h (is_fake_win): Declared.
	+ window.c (is_fake_win): New function.

 (kev) 980321 (l)
 	+ api.c (api_setup_fake_win, api_dotgline, api_command_cleanup,
	  api_bp2sp):  Rearranged initialization of DOT so that it will
	  be done conditionally in api_dotgline.  This fixes a nasty
	  bug in which lines could get added to the wrong buffer.  It
	  also allows perl functions to be written which look at the
	  current location of DOT and possibly do something with it.
	  Before, we were always setting it to the start of the region
	  (which may not have a lot of relevance).
	+ api.h (SCR): New field dot_inited.
	+ perl.xs (setregion): Set dot_inited field.
	+ x11.c (atom_CLIPBOARD, x_preparse_args): New atom; initialize.
	  (x_get_selection, x_paste_selection, x_get_clipboard_text,
	  x_convert_selection, x_lose_selection, own_selection,
	  x_own_selection, copy_to_clipboard, paste_from_clipboard,
	  x_process_event): Handle CLIPBOARD selections as well as
	  primary selections.
	+ cmdtbl (copy_to_clipboard, paste_from_clipboard): New
	  commands.
	+ estruct.h (CLIP_KREG): New kill register.
	  (NKREGS, SEL_KREG, KEYST_KREG): Renumbered to account for
	  new kill register, CLIP_KREG.
	+ line.c (index2reg): Represent the clipboard kill register
	  with a ';'.
	+ vile.hlp: New documentation about X11 CLIPBOARD selections.

 (tom) 980321 (k)
	+ correct logic in tcap.c so that visual-matches works for a specific
	  color (reported by Kuntal M. Daftary).
 	+ add test for Xp library, needed to link with RedHat Motif 2.1
	  (reported by Richard ).
	+ add configure option --with-startup-path to allow installer to
	  customize the $startup-path used by vile.
	+ change Unix lib directory (i.e., location of vile.hlp) to
	  $(prefix)/shared/vile.  The older location, $(exec_prefix)/lib, is
	  still in the $startup-path, but vile.hlp will not be installed
	  there.
	+ remove config.cache at the start of configure script, since we use it
	  only for problem reporting.
	+ ifdef'd out w32pipe code, but make it available for further
	  development as OPT_W32PIPES (recommended by Clark Morgan).
	+ minor fixes/resync for configure macros CF_CHECK_ERRNO,
	  CF_DISABLE_ECHO, CF_FIND_LIBRARY, CF_NCURSES_LIBS and
	  CF_NCURSES_VERSION.

 (kev) 980320 (j)
 	+ api.c (linsert_chars): Rewritten both for efficiency and
	  so that the MARK at the end of the region stays put when
	  doing something like:

		$curscr->inplace_edit(1);
		while (<$curscr>) { s/foo/bar/g; print; }

	  (setup_fake_win): No longer static.  Renamed to
	  api_setup_fake_win.  Also set DOT here to the beginning of
	  the region.
	  (api_mark_iterator): New function.
	  (api_gotoline): No longer static.  Also renamed from
	  _api_gotoline.  Fixed all callers.
	  (api_dotinsert, api_dotgline): New functions.
	  (api_bp2sp): Initialize the region beginning and end
	  to point to something valid.
	+ api.h (SCR): Added new fields region, regionshape, and
	  inplace_edit.
	  (api_dotinsert, api_dotgline, api_gotoline, api_setup_fake_win):
	  Added declarations.
	+ cmdtbl (perldo): New command.
	+ estruct.h (api_do_mark_iterate_helper): New macro.
	  (do_mark_iterate): Invoke api_do_mark_iterate_helper in order
	  fix the the marks in the SCR structure region.
	+ perl.xs (newVIrv): Make the references to SCR objects that
	  we give perl refer to globs instead of a scalar.  Bury
	  the scalar in the scalar portion of the glob.  The reason
	  we do this is so that these references may be used as
	  filehandles as well as objects.
	  (perl_free_handle): Slight change to account for extra
	  levels of indirection to get to the thing we really have
	  to zero out.
	  (perl): Added calls to hst_flush() and hst_init() in order
	  to prevent user input from a perl command from being added
	  to the history line for the perl command.  (It was simply
	  getting appended on the end.)  Unfortunately, this input
	  doesn't seem to be recorded in the history any longer, but
	  at least it doesn't mess up the perl command.
	    Also rewrote the code for setting up a region, making sure
	  that the new fields in the SCR structure are initialized
	  appropriately.
	  (replace_line, perldo): New functions.
	  (perl_init): Tie STDIN to read from the minibuffer.  Modified
	  other tie statements (calls to sv_magic()) slightly to do
	  the same thing.
	  (Msg): No longer an alias for PRINT.
	  (PRINT): New method which handles both buffers and STDOUT
	  and STDERR.
	  (READLINE): New method which will either read a line from
	  a buffer or fetch input from the user via mlreply_no_opts().
	  When it reads from a buffer, it has the potential to read
	  multiple lines if used in an array context.
	  (VileCommand): New method which runs an arbitrary vile
	  command.  I'll probably rename this one -- don't like
	  the caps.
	  (inplace_edit, setregion): New methods which set/get fields
	  from the SCR structure.
	  (GetUserInput): Will probably go away.  This was my first
	  attempt at a mechanism for fetching user input.
	  (mlreply, mlreply_no_opts, mlreply_file, mlreply_dir): Various
	  methods for fetching user input from the message line.
	+ ptypemap (T_VI): Account for the fact that our objects may
	  also now be considered as filehandles.  (The references now
	  refer to globs instead of scalars.  The scalar is still there,
	  but it's just stuck inside the glob.)

 (tom) 980317 (i)
	+ remove binding of quote-next-character to ^V (reported by Keith
	  Williams , recommended by Paul Fox).
 	+ add an AIX-specific pattern to finderr.c (patch by Michael Finken
	  ).
	+ correct w32pipe.c to re-open stdin on the first available descriptor
	  (i.e., 0) when cleaning up after a filter operation (patch by Clark
	  Morgan).

 (tom) 980316 (h)
 	+ correct logic that shifts minibuffer back on return from kbd_reply,
	  had not set curwp.

 (pgf) 980315 (g)
	+ documentation and usage improvements for vile-crypt, in crypt.c,
	  vile.hlp, and vile.1.

 (tom)	980314 (f)
 	+ add "attribute-reverse-til" (suggested by Kuntal M. Daftary
	  daftary@cisco.com).
 	+ correct logic of find_mode() so that :setl cts=4 works as before.
	+ modify kbd_reply() to support inline-editing of the user's text, both
	  by arrow keys, as well as vi-style motion commands.  Use ^G to toggle
	  between the two modes.
	+ change interfaces/logic of hst_append(), kbd_show_response(),
	  kbd_reply() to make them accept nulls.  This is for later extensions,
	  since regexp.c does not handle nulls.  Use the mask KBD_0CHAR for
	  this purpose.
	+ modify check for type-ahead to make 'showmatch' skip the 1/4 sleep,
	  ignoring the current value of 'smoothscroll' (reported by Matthias K.
	  Buelow )
 	+ adjust redefinition of WINDOW in tcap.h to work around OSF1 3.2,
	  which includes curses.h from term.h
 	+ split-out function ntcons_reopen() from ntkopen(), to move it past
	  the pressreturn() call; otherwise the user sees no prompt when
	  running a shell command (reported by Manoj Bhargaw ).
	+ minor adjustments to 'w32pipe' by moving some code into w32pipe.c to
	  allow reuse in the GUI winvile, and using $shell rather than inline
	  expressions for shell spawned in pipes.  Testing with bash did not
	  seem to allow /bin/sh as a possible shell, so I dropped that from
	  Clark's patch.
 	+ improve pipes for W95/WinNT using native support, new mode 'w32pipe'
	  (patch by Clark Morgan).

 (pgf)	980218 (e)
	+ added "crypt-til" operator (bound to ^X-C) which will
	  encrypt/decrypt an arbitrary region.  the main goal was to make
	  it easy to read a previously encrypted file and decrypt it for
	  reading, or to read a clear file, and quickly encrypt it before
	  writing it.  i find crypt mode to be cumbersome at best -- i find
	  the explicit command to be more useful.
	+ modified crypt.c to allow building it as standalone utility.
	  this gets built as vile-crypt, and it's compatible with the crypt
	  command inside of vile (if used over an entire buffer).  usage
	  is:
	    vile-crypt [-m] [-k crypt-key ] [file ...]
	  if '-k crypt-key' is omitted you will be prompted instead, and
	  '-m' leaves text to the first blank-line intact, which i find
	  useful for encrypting individually stored mail messages.  the
	  en/decrypted text appears on stdout.
	+ attempted to document vile's encryption features in vile.hlp.

 (tom)	980208 (d)
 	+ reformatted proto.h, ordering prototypes alphabetically.
 	+ make column shown by ^G the same as for the ruler (reported by David
	  Letcher ).
 	+ add command show-printable to show exactly what vile does with the
	  character classes.
 	+ newer autoconf configure macro circumvents problems generating
	  config.h due to limited sed buffer size on antiquated systems (e.g.,
	  HP-UX 9.x, SCO 3.x).
 	+ updated configure test, to avoid use of broken IRIX 6.2 nsl library.
	+ add configure option --with-locale to allow use of i18n support via
	  setlocale function.
	+ use new symbol SYS_OS2_EMX to avoid nonstandard use of 'defined'
	  keyword in OPT_CASELESS preprocessor expression (reported by Adam
	  Denton).
	+ move the call that forks xvile up to the first place where it could
	  be used, to minimize data space.

 (tom)	971219 (c)
	+ correction to CF_CURSES_TERMCAP configure test so that SVr4 systems
	  that do not have a prototype for tgoto, but still require curses.h
	  will build properly (patch by Brendan O'Dea).

 (tom)	971218 (b)
 	+ add configure-test to see if $LIBS already contains termcap functions
	  before looking for additional libraries.
 	+ amended CF_CURSES_TERMCAP and CF_TYPE_OUTCHAR tests to use vile's
	  headers (correcting symbol conflict with NL in estruct.h vs curses.h),
	  and to double-check that failure to link test with tgoto was
	  due to conflict with prototype (latter reported by Brendan O'Dea).

 (tom)	971217 (a)
 	+ add CF_CURSES_TERMCAP macro to test for prototypes in curses.h vs
	  termcap.h
 	+ add variable $patchlevel.
 	+ updated README.CFG to list the newer options (reported by Ralphe
	  Neill ).
 	+ use CF_SIZECHANGE macro to eliminate a SCO-related hack in configure.
 	+ interpret --with-x option in configure-script (reported by Paul Fox).
 	+ add/use TYPECAST macro to quiet the "harmless" const warnings.
 	+ modify CF_IMAKE_CFLAGS macro to work with SGI's imake macros which
	  combine the -I/usr/include and -nostdinc options, confusing gcc
	  (reported by Billy Little ).
	+ fixes for Perl-related rules in makefile.in (patch by Brendan O'Dea).

Changes for vile 7.3 (released Mon Dec 8, 1997)

 (tom)	971207 (t)
 	+ correct include-path for configure script's check for missing
	  externs, to work with --srcdir option (analysis by Kevin Buettner).

 (tom)	971205 (s)
 	+ add logic to configure.in to use a filter (installed by td_lib)
	  named 'td_config' which works around limited 'sed' when constructing
	  config.h on SCO 3.x, HP-UX 9.x and other antiquated platforms.
 	+ add configure options --disable-extensions (SMALLER, FEWNAMES) and
	  --disable-shell (OPT_SHELL), and --with-dmalloc.  The shell option is
	  experimental; note that a genuinely secure editor should not allow
	  directory names to be specified (but I think that's the only omission).
	+ add fallback for tparam/tparm in tcap.c (for EMX, but usable for
	  genuine termcap systems such as SunOS 4.x), to support color.
	+ add files for building termcap version on OS/2 with EMX
	  (makefile.emx, config.emx and os2keys.h).
 	+ change $shell to use $COMSPEC on OS/2, MS-DOS, etc.  This is needed
	  for the OS/2 EMX configuration, but useful in the others.
 	+ modify configure script to use ifdef's in estruct.h when testing
	  for missing extern/prototype declarations rather than a separate
	  list in aclocal.m4 (this requires rebuild/test on most platforms).
	+ combine configure-tests for errno, sys_nerr and sys_errlist.
	+ minor fixes:  new versions of CF_NCURSES_LIBS, CF_ADD_INCDIR,
	  CF_CHECK_CACHE, CF_NCURSES_CPPFLAGS.
	+ correct handling of :map containing ".", which was being handled
	  as if the "." always appeared at the end (patch by Duncan Sargeant;
	  input.c, map.c).

 (kev)  971203 (r)
	+ api.c (lreplace): Fix marks up.  This won't always be right,
	  but at least it'll be closer.  We need a way to modify marks
	  and attributes from perl.
	  (setup_fake_win): changed return type to int.
	  (api_fscreen, api_edit, api_swscreen, api_bp2sp): new functions.
	  (sp2bp, bp2sp): Removed these macros.
	+ api.h (api_swscreen, api_fscreen, api_bp2sp): declared these
	  functions.
	  (sp2bp, bp2sp): macros moved from api.c.
	+ configure.in (LINK_PREFIX): set this variable.  (From Brendan
	  O'Dea.)
	  (CFLAGS, LIBS): Use $perl_bin_path instead of perl in the
	  --with-perl section.
	+ makefile.in (LINK): Prepend LINK_PREFIX as determined by
	  configure to the link command.  (From Brendan O'Dea.)
	+ perl.xs (newVIrv): Don't allocate api private part here. (It's
	  allocated in api_bp2sp now.)  The second parameter has also
	  changed; changed all callers.
	  (perl): Print error messages and warnings to message line.
	  (perl_init): Setup warning handler.  Also tie STDOUT and STDERR
	  so that output to these filehandles will be printed on the
	  message line.  (Thanks to Brendan O'Dea.)
	  (perl_eval): New function.
	  (Msg): Rewritten to handle multiple arguments. (From Brendan O'Dea.)
	  (GetLines): new function which fetches all lines in the range.
	  (Edit, FindScreen, SwitchScreen, Warn): New functions.
	+ proto.h (perl_free_private): removed.
	  (perl_free_handle): added.
	+ ptypemap (T_VI): Translate C null pointers to perl undefs.

 (tom)	971128 (q)
	+ modify tagignorecase mode to use lowercased keys in the binary-tree,
	  and applying tagignorecase mode to the search within the tagged file,
	  making this behave as Joseph F. Garvey requested.
 	+ implement tags-completion.
	+ replace Alex Wetmore's binary tree code with a balanced binary tree
	  module that's a little more general, and does deletion more rapidly
	  than my first try.
 	+ minor fixes for foreground/background colors when resizing terminal
	  window so minibuffer is painted correctly (display.c, ntconio.c).
 	+ rename ntvile to winvile.

 (tom)	971112 (p)
 	+ correct logic for minibuffer by ensuring that it is not marked for
	  undo, and that the value of MK is save/restored when modifying
	  the minibuffer.

 (tom)	971109 (o)
 	+ correct range of scrolling region in ansi.c
 	+ correct treatment in xshell.sh for no-arguments.
 	+ change TTrev() / TTattr() parameter to unsigned.
 	+ implement mouse and flash in OS/2 VIO driver (os2vio.c).
 	+ correct logic in vtputc() to prevent minibuffer from writing into the
	  lower-right corner of the screen.

 (tom)	971108 (n)
 	+ more CSet unsigned/signed compiler warning fixes (estruct.h)
 	+ don't reopen terminal in ansi.c if it is already open.
 	+ correct handling of rename-buffer when it is a scratch buffer that
	  does not happen to be a stored procedure.
	+ recorrect lookup_namebst() call in engl2fnc(); it should always allow
	  partial match.  Fixed by adding a third mode where the lexical first
	  match will be returned rather than the middle one in a range.
 	+ correct tab-position in ntconio.c
 	+ modify borland.c to reset colors when exiting or running a shell.
	+ change tcapkopen() to reflect possibility that terminal
	  initialization string moves the cursor.
 	+ add simple gui terminal driver for WinNT (ntwinio.c, makefile.wnt).
	  Built with Microsoft Visual C++ 4.1, both with IDE and makefile.wnt.
	  Use "nmake -f makefile.wnt cfg=ntvile".
	+ integrated related patch by Clark Morgan for repainting the screen
	  correctly after a :stop command.
 	+ rewrote internals of command/message line to make it a one-line
	  minibuffer, including mods for OPT_RAMSIZE and OPT_WORKING.  Tested
	  Linux (for tcap.c, x11.c, ansi.c), OS/2 (os2vio.c), WinNT (ntconio.c,
	  ntwinio.c), VMS (vmsvt.c), djgpp (borland.c).

 (tom)	971028 (m)
	+ correct inverted parameter in call on lookup_namebst().
	+ compiler warnings from Solaris (unsigned vs signed in bind.c, ifdef
	  in trace.c).
	+ minor changes to compile on OS/2 with EMX.
	+ modify borland.c to reset colors to white/black on exit.

 (tom)	971027 (l)
	+ backout change to own_selection, since it doesn't follow ICCCM,
	  in the sense that it increases X traffic needlessly (pointed out by
	  Kevin Buettner).  Kept check on return value from XtOwnSelection.
 	+ correct out-of-bounds indexing in dname_to_dirnum() by adding a
	  length parameter, use memcmp.
 	+ modify Alex's change so that buffers that are renamed or deleted
	  update the corresponding entries in the binary-tree.  Also, don't
	  allow built-in commands to be removed or replaced.  Finally, make the
	  name-completion work with an empty command.
	+ add $end-of-cmd variable (patch by Alex Wetmore).
	+ integrate patch by Alex Wetmore 
	  that makes stored procedures act just like built-in commands, i.e.,
	  able to run them from the :  prompt.  This works by building a binary
	  tree of all of the command and procedure names.

 (tom)	971015 (k)
	+ add configure options --with-Xaw-scrollbars and
	  --with-drag-extension.  These make it easy to build xvile with
	  Kevin's scrollbars by specifying --without-Xaw-scrollbars, or to use
	  the Xaw's default translations for scrollbars by specifying
	  --without-drag-extension.
	+ ifdef'd out the code that invokes $xshell in ":!command".
	+ correct logic in xvile that spawns a new instance from menu entry,
	  was leaving a zombie when the new instance closed (reported by Brian
	  Moore ).
	+ modify own_selection to always try to own the select, as well as to
	  check the return value from XtOwnSelection (reported by Ian Jamison
	  )
	+ add Lesstif-specific ifdef for workaround (requested by Larry Gensch).
	+ correct ifdef'ing of Motif version of xvile (reported by Larry
	  Gensch).
	+ add screen types Xol and Xm as aliases for OpenLook and Motif.
	+ correct quoting in configure script for OpenLook case.
	+ fix some compiler warnings and add 'make check' target (reported by
	  Nelson H. F. Beebe )

 (kev)	971013 (j)
 	+ perl.xs, ptypemap: Lots of new code which extends the perl
 	  interface a bit more.
 	+ api.c, api.h: New files which sort of implement nvi's API for
 	  extension languages.
 	+ makefile.in (OBJ, VILESRC): Added api.o and api.c to these
 	  lists.
 	+ estruct.h (BUFFER): Added new field, b_api_private, used by
 	  the extension language API.
 	+ buffer.c (FreeBuffer): Free up the extension language API
 	  related data structure referenced by b_api_private.
 	  (bfind): Initialize the b_api_private field.
 	+ cmdtbl (perl): Put in a reasonable set of flags for this
 	  command.  (It used to be NONE.)
 	+ exec.c (execute_named_command): Added region support for the
 	  perl command.
 	+ proto.h (push_fake_win, pop_fake_win, perl_default_region,
 	  perl_free_private, api_free_private): New prototypes.
 	+ select.c, window.c (push_fake_win, pop_fake_win): These
 	  functions removed from select.c and put into window.c.  Also
 	  they are no longer static.

(kev)	971009 (i)
	+ perl.xs, ptypemap:  New files.  Beginnings of perl interface
	  for vile.
	+ cmdtbl (perl): New command enabled only when --with-perl
	  supplied as an option to the configure script.
	+ configure.in, makefile.in: perl related changes.
	+ (fix typo in xshell.sh - tom)

(tom)	971008 (h)
	+ correct typo in stubbed-out code for $xshell, add $xdisplay and
	  example script 'xshell.sh' which can be used to run a shell command
	  from xvile, prompting at the end so that the output doesn't go away
	  when the xterm completes.
	+ rename vile's ctype macros to mixed-case to avoid conflict.  This
	  is needed for Solaris 2.6, which does not implement ctype as macros.
	+ modify casts and some names (e.g., new, operator, class) to allow
	  compiling with C++ (tested with g++ 2.7.2 on Linux).

(kev)	971007 (g)
	+ x11.c (multi_click): Reimplemented multiclick selections for
	  lines.  Previously, it was not possible to select the entirety
	  of a wrapped line by clicking on a row other than the first
	  row.
	+ window.c (mvupwind, onlywind, delwp, splitw, enlargewind,
	  shrinkwind):  Make sure that w_line.o is zero just after
	  setting w_line.l to a new value.  The lack of this
	  assignment in mvupwind() was causing a SEGFAULT on my linux
	  box.  [To test it, create a very long wrapped line with a
	  bunch of lines (say 100) before it; my test has in excess of
	  10,000 characters on the long line.  Make sure linewrap mode
	  is set.  Then say 100^Y.  The SEGFAULT was immediate.  You
	  can also reproduce it by dragging the scrollbar for awhile.]

(tom)	971006 (f)
	+ document --with-screen values better in configure --help.
	+ implement Athena widget scrollbar support in x11.c, using Kevin's
	  dragging support from the no-widget case.
	+ add $xshell environment variable, use this to control :sh command
	  from xvile.
	+ new CF_X_ATHENA configure macro adds configure options --with-Xaw3d
	  and --with-neXtaw.
	+ corrected CF_IMAKE_CFLAGS, which was not using the imake symbol that
	  specified X function prototypes.  (This was old behavior, which did
	  not seem to matter until adding Xaw scrollbars on Linux).

(kev)	971005 (e)
	+ basic.c (setwmark): In linewrap mode, account for undisplayed
	  rows before the first row shown of a very long wrapped line.
	+ display.c (vtset): Don't allow wrapped lines to overflow onto
	  the mode line.  I don't think characters from the buffer were
	  ever getting written to the modeline, but vteeol() would sometimes
	  erase the modeline when displaying very long wrapped lines.
	  (reframe): Handle reframes of long wrapped lines more gracefully.
	  In particular, once the top row of a very long wrapped line
	  goes off the top, it is now possible to have the cursor positioned
	  on somewhere other than the bottom row.  Scrolling up or down
	  via right or left right movement within a long wrapped line also
	  looks a lot better now.
	  (updattrs): Don't attempt to access rows before the top row
	  of a window when updating attributes.  Also, don't access
	  rows of or below the the mode line.  This fixes a SEGFAULT.

(tom)	970918 (d)
	+ amend logic for find_mode() so that "&glo cmode" and "&loc cmode"
	  work as before majormode changes (reported by Sean Ahern).
	+ merge autoconf macros from tin/xterm, which mainly affect the
	  configuration tests for ncurses and imake $CFLAGS, used to augment
	  autoconf's tests for X Windows.
	+ also (since some systems have deficient 'sed' programs) provide
	  alternate hook for using a program 'td_config', which is currently
	  bundled in td_lib.tgz, that does the sorting operation of config.h in
	  a reasonably portable manner.
	+ add mode 'maplength' to control the maximum length of a map
	  string.
	+ correct definition of OUTC_ARGS for the case where it should be a
	  'char' value (patch by Jason Molenda ).

(tom)	970907 (c)
	+ modify CF_CACHE_CHECK macro to use AC_CANONICAL_HOST to obtain a
	  "better" value for SYSTEM_NAME.  This is displayed as part of the
	  :version command.  Add config.guess and config.sub to support this.
	+ changes for 7.2b omitted some macros dealing with echoing during the
	  make process (reported by Jens Schleusener )

(tom)	970905 (b)
	+ merge configure macros from tin-unoff and lynx (configure.in,
	  aclocal.m4).
	+ rename configure macros to CF_ prefix, for consistency/merge with
	  other programs (configure.in, aclocal.m4).
	+ correct handling of tparm return-value; it must not be freed, at
	  least for SVr4 and ncurses (tcap.c)
	+ ensure that majormode names are a legal identifier.
	+ modify so that majormode names can be mixed case (requested by
	  Sean Ahern).

(tom)	970904 (a)
	+ add variable $majormode so that it can be tested in a script
	  (requested by Philippe Chassany).
	+ fix potential ifdef problem for cbuf1 (reported by Brendan O'Dea).
	+ simplified VMS permissions code, using the protection parameter in
	  'open()' to achieve the objective of propagating a file's current
	  protection, as well as making it compile with DEC C (reported by
	  Simon Hefti ).

Changes for vile 7.2 (released Thu Sep 4, 1997)

(tom)	970903 (k)
	+ modify rename-buffer so that if we rename a buffer, we'll clear the
	  flag that marks it for removal when popped-down.
	+ modify show-modes command so that it will format more than 3 columns
	  if the screen is wide enough.
	+ correct logic of delfrommap(), which dumped core when unmapping
	  a single-character map (reported by Paul Fox).
	+ modify show-majormodes so that giving a count will make it show all
	  of the submodes prefixed by the majormode name, e.g., c-suffixes
	  (suggested by Paul Fox).
	+ modify documentation to use "define-majormode" and "remove-majormode"
	  for clarity, other related fixes to documentation (suggested by Paul
	  Fox).

(tom)	970902 (j)
	+ correct logic in find_mode() that did not find majormode qualifiers
	  for majormodes that began similarly (e.g., "com" masked by "c").
	+ correct an uninitialized variable in per_submode(), found by Purify.
	+ correct ifdef'ing in tcap.c, from 7.1i, when neither tparm nor
	  tparam is found.

(tom)	970901 (i)
	+ if the command-line '@' option is used, set the $startup-file
	  variable to correspond to the startup file which is used.
	+ add tagignorecase mode, which causes tag searches to be done ignoring
	  case (requested by Joseph F. Garvey ).
	+ initialize last_eolchar in docmd() so that 'set' command works
	  properly in a macro.
	+ add %B substitution for error-buffer regular expressions to allow
	  using [Standard Input] and other scratch buffers as error buffers.
	+ modify format-til command to treat '#' specially when in cmode, so
	  no whitespace is inserted after it.
	+ modify format-til command to support comment-prefix mode and handle
	  repeated prefix, so that, for example, vile can now format multiple
	  levels of email replies.
	+ add comment-prefix mode, which specifies a regular expression that
	  controls the portion of a line which is prefixed when formatting.
	+ modify default setting of comments mode to make repeated prefix
	  match (e.g., "> > >", is different from "> >").
	+ ensure that imdying() always exits (reported by Clark Morgan).
	+ workaround for incompatible interpretation of termcap Sf/Sb
	  capability with BSD vs SYSV platforms (tcap.c).

(tom)	970829 (h)
	+ correct initialization of $palstr on OS/2.
	+ correct some of the signed/unsigned warnings from IBM CSet compiler.
	+ remove obsolete autoconf fallback macros.
	+ correct handling of ":abbr res RES", ":abbr wres WRES" combination by
	  forcing matches on these to check that the beginning of the match is
	  an identifier boundary (reported by Paul Laub ).
	+ correct assignment in maplookup() which caused a -1 returned when no
	  more characters were available for matching to be converted to the
	  0xFF character.
	+ modify fopen-for-write calls on VMS to add "0" argument, which makes
	  the new file get the user's default protection (requested by Brian
	  Reed ).
	+ correct logic that allowed repeated definition of submodes (reported
	  by Duncan Sargeant).
	+ allow submode names to begin with "no", assuming they are booleans
	  (reported by Duncan Sargeant).
	+ corrected lookup of hyphenated submodes, e.g., c-tabstop (reported
	  by Duncan Sargeant ).
	+ allow define-submode to accept an '=' between the submode and its
	  value.
	+ modify define-mode and remove-mode to suppress warning message if
	  the mode does not exist, since this produces unnecessary warnings
	  when re-sourcing .vilerc
	+ include  only where it is needed, halving the build time
	  (patch by Clark Morgan).
	+ modify configure script to work with CLIX old-style shared libraries
	  (e.g., -lc_s) needed for xvile.

(tom)	970816 (g)
	+ correct type mismatch in filec.c when sizeof(size_t) !=
	  sizeof(unsigned) (reported by Larry Gensch ).
	+ modify vmsbuild.com to tell MMS (or MMK) to ignore warnings,
	  workaround for an inconsistency between versions of DEC C
	  (suggested by Andy Harper and Adam Denton).
	+ initial implementation of majormodes, which supports grouping of
	  buffer modes, together with qualifiers (e.g., cmode and c-suffixes).
	  New commands include define-mode, define-submode, remove-mode,
	  remove-submode, list-majormodes.  (Most changes are in mktbls.c and
	  modes.c).

(tom)	970619 (f)
	+ modify ":set" command so that it does not force a mode to be set,
	  but instead shows the local buffer and window settings.
	+ correct missing error-test in logic that sets regular-expression
	  modes (reported by Philippe Chassany).
	+ add configure option to specify the total numbered macros available,
	  e.g., execute-macro-1, ifdef'd with OPT_EXEC_MACROS (requested by
	  Philippe Chassany).
	+ modify xvile menus to allow arbitrary command line rather than
	  bound functions (exec.c, menu.c).
	+ correct spurious parameter in vms2unix.c, from 7.1d changes.

(tom)	970607 (e)
	+ modify VMS terminal driver, vmsvt.c, to work when invoked from a
	  command-file, i.e., get terminal characteristics from SYS$COMMAND
	  rather than SYS$INPUT (reported by Adam Denton).
	+ treat '$' as an identifier character on VMS (requested by
	  Adam Denton).
	+ clarify discussion of color in help-file (patch by Clark Morgan).
	+ modify map.c to use TBUFF's, as well as new kbd_reply interface,
	  to remove limit on mapped strings.
	+ change interface/internals of kbd_reply() to use a TBUFF, so we don't
	  need fixed-size buffers any more (bind.c, exec.c, eval.c, history.c,
	  input.c, line.c, modes.c).
	+ correct uninitialized buffer in loadkreg().
	+ correct indexing in display_cursor() function in xvile; exposed when
	  displaying a long list for the historical buffer command.

(tom)	970526 (d)
	+ add $ncolors variable to allow run-time modification of the meaning
	  of colors (e.g., white).
	+ change $palette to a dynamically allocated string.
	+ modify termcap and IBM terminal drivers to support 16 colors.  Note
	  that the termcap driver can do this only when configured against a
	  terminfo library (inspired by a patch from Clark Morgan).
	+ modify mktbls to generate the enumerated choices tables (i.e., for
	  color, visual-matches) to simplify ifdef'ing these between the
	  8-color and 16-color configurations.
	+ undo some of the const parameters of functions, thereby eliminating
	  most of the places where casts were used to remove const.
	+ modify VMS processing of tags to strip file's version number
	  (adapted from fix by Adam Denton ).
	+ modify bclear() to free attributes before removing the buffer's
	  lines, thereby making it faster (patch by Ian Jamison).

(tom)	970513 (c)
	+ set local buffer mode for 'dos' in slowreadf(), which fixes the
	  problem of that function modifying the global mode when piping a file
	  to vile, hence causing syntax errors in vile.rc when it contains
	  trailing carriage-returns (file.c) (analysis by Clark Morgan).
	+ correct missing VASEL flag that caused 'q' command on OS/2 to not
	  display highlighting, missed in 7.0b (os2vio.c) (reported by George
	  Eccles )
	+ implement 'flash' for WinNT (ntconio.c)

(tom)	970513 (b)
	+ ifdef'd menu.c to work with 7.1a

(tom)	970512 (a)
	+ modify has_C_suffix() to ignore case on platforms where filename
	  case should be ignored (reported by Emil Rojas ).
	+ add version in vmsbuild.com to release_warnings
	+ remove unnecessary test for Xaw/SimpleMenu.h (configure.in).
	+ improve geometry of Xaw menus using Box (patch by Brendan O'Dea
	  )
	+ add menu.c to the modules for xvile on VMS (reported by Graeme
	  Miller).

Changes for vile 7.1 (released Wed May 8, 1997)

(tom)	970508 (none)
	+ undo a place where I'd dropped an XtVaGetValues() call, since it
	  appeared redundant, but was not - affects only Xaw build (x11.c).
	+ ifdef'd a test in newscreensize() that is applicable only when
	  OPT_WORKING is set; this had broken screen initialization on MS-DOS
	  (display.c).

(tom)	970507 (l)
	+ add resource to control menu-height (x11.c, menu.c).
	+ correct definition in vms2unix.c to allow compile with VAX C, which
	  doesn't like "#define foo xxx.foo".

(tom)	970430 (k)
	+ modify lookup of .vilerc to use startup-file search rules (menu.c)
	+ correct missing XmString conversion (menu.c)
	+ add configure check for -lXext to support Athena build on X11R4.

(tom)	970429 (j)
	+ use im_waiting() function to reset "working..." state after executing
	  a menu-command (menu.c).
	+ modify lookup of .vilemenu to use startup-file search rules.
	+ corrections for porting Xaw version to SunOS, etc., with X11R4 and
	  X11R5 (x11.c, configure.in)

(tom)	970428 (i)
	+ implement Xaw (Athena widget) version of menus.  Simplified buffer
	  lookup function for menus, align/document resource names (menu.c,
	  x11.c, configure script).
	+ correct minor memory leaks during initialization (main.c)
	+ correct array-indexing error that caused core dump when selecting
	  line-wrapped text, moving cursor up (display.c).

(tom)	970422 (h)
	+ improved example of menus for xvile (Philippe Chassany).
	+ correct mistyped index in c-filt.c, which was a char (patch by Ian
	  Jamison).
	+ correct c-filt.c handling of nested comment delimiters (patch by Ian
	  Jamison )
	+ correct sign-extension in tcap.c for xterm mouse-coordinates.

(tom)	970407 (g)
	+ add mode 'tagword', which allows user to lookup the whole word rather
	  than a substring.  (from Adam Denton ).
	+ reintroduce flag 'i_displayed' into 'working' mode (I'd forgotten
	  that it suppressed the message until screen-mode).
	+ improve buffer-switching in menu-support (patch by Philippe Chassany)
	+ correction to MS-DOS, etc., where attempt was made to fclose a file
	  pointer that was out of scope (patch by Clark Morgan).
	+ modify definition of eql_bname() macro so that buffer names are
	  treated as case-insensitive where filenames are, e.g., WinNT and
	  OS/2 (patch by Rick Sladkey from report by Clark Morgan).
	+ add predefined regular expression to finderr.c to improve support
	  for MS-DOS pathnames (patch by Clark Morgan).

(tom)	970407 (f)
	+ integrated menu-support for Motif xvile (patch by Philippe Chassany
	  ).
	+ refined changes to 'working' mode to ensure that the "working..."
	  message is cleared when the timer elapses.

(kev)	970407 (e)
	+ fileio.c (isready_c): Small tweak to the ifdefs for mklinux w/
	  shared libraries.  This'll probably be needed for other systems
	  with the up and coming GNU libc as well.

(tom)	970330 (d)
	+ correct missing ']' on generated buffer name for shell output, e.g.,
	  "[!ls]" rather than "[!ls" (reported by Paul Fox): (file.c).
	+ correct unnecessary escaping of '!' in prompts that are not expanding
	  the shell contents (reported by Paul Fox): (input.c).
	+ modify semaphore used by 'working' mode to make the SIGALRM timer
	  elapse when it is not in use, allowing idle process to swap out
	  properly (reported by Bill Kipp): (display.c, etc).
	+ correct filename parsing for MS-DOS/etc configuration by checking
	  for device name (patch by Clark Morgan).

(tom)	970322 (c)
	+ fixes for piping to vile in WinNT (patch by Clark Morgan).
	+ add logic for visual-matches in color, WinNT (patch by Clark Morgan).
	+ add vile-c-filt.exe to makefile.wnt, modify default keyword file
	  on that system to vile.keywords (patch by Clark Morgan).
	+ correct problem with MS-DOS/Win95/NT version of npopen.c that left
	  temp-files after reading from pipe, because file-remove was done
	  before closing (patch by Clark Morgan).

(tom)	970315 (b)
	+ use macro GCC_UNUSED throughout to quiet gcc warnings about unused
	  (dummy) parameters.
	+ modify configure script to use VC_GCC_WARNINGS
	+ add mode to control whether formatting adds one or two spaces
	  after sentences (patch by Otto Lind).
	+ handle C++ comments (patch by Otto Lind ).
	+ implement colored attributes in OS/2 video driver (os2vio.c)
	+ modify writereg() so that it recomputes the region size after
	  invoking the $write-hook; this is necessary since it may change the
	  file's size (reported by Bob Wall ).

(tom)	970314 (a)
	+ modify c-filt.c, manfilt.c to simplify compiling w/o auto-configure
	  "config.h".
	+ modify MS-DOS/Win31/WinNT portion of npopen.c to leave input file
	  descriptor alone when reading from pipe, solving a problem with
	  applications hanging under Thompson Toolkit (patch by Clark O.
	  Morgan )
	+ correct inequality changed in 6.2g which is part of right-margin
	  threshold computation (report and fix by William Yuan
	  )
	+ corrected definition of $(exec_prefix) in makefile.in (reported by
	  Joachim Schimpf ).
	+ apply suggested casts in vms2unix.c to appease DEC C 5.3 (reported
	  by Andy Harper and Graeme Miller).

This change log started on Wednesday Mar 12, 1997.
vile-9.8v/CHANGES.R8000066400000000000000000003061521415556424100140200ustar00rootroot00000000000000Changes for vile 9.0 (released Thu Nov 15, 1999)

 (tom) 991115 (c)
	+ various changes to comments (patch by Ryan Murray).

 (tom) 991111 (b)
	+ revert 8.3s change that modified inout_popen() to convert pathname
	  to backslashes on DOS, etc., since it too easily confuses commands
	  that have genuine slashes (reported by Ed Henderson).
	+ modify check for curses/termcap library to try linking tgetstr(),
	  to work around broken linker on FreeBSD, but still detect properly
	  HPUX curses library that has termcap functions.
	+ remove pointers to defunct mirrors (reported by Clark Morgan).
	+ remove duplicate description in vile.hlp of vile-crypt; the manpage
	  covers this topic.
	+ use new configure macro CF_ADD_CFLAGS to make configure check for
	  headers (which uses only $CPPFLAGS) work with X_CFLAGS computed by
	  autoconf's AC_PATH_XTRA.
	+ correct ifdef's for sys/select.h to use USE_SYS_SELECT_H, which takes
	  into account the configure check for fd_set from 8.3n (reported by
	  Jens Schleusener).
	+ use newer CF_TYPE_FD_SET configure test, from xterm which checks for
	  Xpoll.h which may conflict with sys/select.h
	+ use newer CF_X_ATHENA configure test, from xterm which checks for
	  nonstandard locations of that library on HPUX.
	+ add configure test to see if -lcrypt is needed in $LIBS to link
	  crypt() function (reported by Paul Fox).

 (tom) 991109 (a)
	+ correct special case of 'n' command on an empty line at the end of
	  a buffer for a pattern that matches zero characters, e.g., ".*",
	  "^" or "$" (reported by Kevin Buettner).
	+ modify internal regular expression data for ranges that include the
	  backslash character so the backslash is escaped, compensating for
	  a change in 6.2a to handle "\\>" pattern.
	+ use function XDisplayString() to obtain the actual display name,
	  needed to make xvile's "New" menu entry direct new sessions to the
	  proper display.
	+ correct a divide-by-zero when computing percentage for ^G command,
	  from 8.3l changes for $position-format (reported by Clark Morgan).
	+ ensure that symbols for EXIT_SUCCESS and EXIT_FAILURE are used where
	  they apply in the filter programs.
	+ add fflush and fclose at the end of filter programs to ensure that
	  the filtered file is written, even on systems whose exit() function
	  does not do this properly (for Dr Luis Mandel ).
	+ correct documentation of $line variable (reported by George Eccles).
	+ add grep commands for dos and win32 to vileinit.rc
	+ add RPM spec to release_warnings in makefile.in
	+ combine calls for getenv("HOME") into new function home_dir(), to use
	  in logic for -I option, making that work properly for Cygwin
	  environment, where $HOME normally is not the same as the "~"
	  expansion.

Changes for vile 8.4 (released Sun Nov 7, 1999)

 (tom) 991107 (z)
	+ change copyright notice to distribute vile using GPL.
	+ update RPM spec based on package by Tim Powers ,
	  add xvile.wmconfig, vile.wmconfig and use xpm icons.
	+ workaround for problem introduced in 8.3r, resetting 'vile_is_busy'
	  flag after each command in main loop().  Otherwise, perl scripts
	  that set this flag via working(0) without restoring it would disable
	  menus.
	+ add -I option, which directs vile to source vileinit.rc, and if the
	  user has no startup file, to make a simple startup file which sources
	  vileinit.rc (request by Peter Williams).
	+ install a default menu file for xvile (.vilemenu) in the data
	  directory.
	+ add vileinit.rc, which adds various useful macros and key bindings
	  to the other initialization files, as an example.
	+ minor fixes for vilefilt.l and makefile.l
	+ correct value computed for $pathlist-separator, supply trailing null.
	+ add $bflags variable, to simplify checks for scratch buffers.
	+ add xshell.sh to install rules for xvile.
	+ reinstate/complete $xshell logic, making it detach the subprocess if
	  waitpid() is available (reported by J.  Chris Coppick - see 971015).
	+ implement showmatch for winvile (patch by Clark Morgan).
	+ more fixes for OPT_CACHE_VCOL, to handle two special cases: showmatch,
	  which temporarily moves the cursor without necessarily updating
	  the sideways value, and a control character split across the right
	  margin.
	+ minor fixes to make vile build/work with --disable-extensions
	+ correct redundant unget when parsing ":%&g" command that would leave
	  'g' repeated in prompt (reported by Mark Crosland
	  )

 (tom) 991030 (y)
	+ correct logic for OPT_CACHE_VCOL which accounts for the starting
	  point when it may be a nonprinting character, i.e., rendered as
	  multiple columns.
	+ fix an error in BeOS version of catnap, exposed by change for SCO;
	  the code did not handle a zero delay time while watching for input.
	> patches by Clark Morgan:
	+ modify ntwinio.c so popup menu's check-marks match those in the
	  system menu.
	+ modify the label of the popup menu "Menu" selection, remove trailing
	  "..." because this cmd does not invoke a dialog box.
	+ update doc/w32modes.doc to cover Windows 98

 (tom) 991019 (x)
	+ minor fixes for OPT_CACHE_VCOL, to take into account list and number
	  modes.
	+ fix a typo in manpage.rc that let empty responses pass by.
	+ save/restore token's column when processing tags (patch by Ed
	  Henderson).
	+ change tttypahead() to use catnap() in preference to ioctl(FIONREAD),
	  since SCO OpenServer's FIONREAD can be used only for sockets (says
	  Bela Lubkin), while select and poll are a little more flexible.  This
	  makes cursor keys work with the terminfo version.
	+ make entering/leaving check in finderr.c faster by checking only the
	  regular expressions that contain the %V (verb) token.
	+ minor fixes to no-leak code in modes.c
	+ fix memory leak from not freeing macro parameters (bind.c)
	> patch by Clark Morgan, for winvile cursor/selection code:
	+ a left mouse button click in the editor's text window clears the
	  current selection (a la notepad and word).
	+ don't start a selection until the cursor actually moves at least 1
	  char.  This change helps prevent a window selection with left mouse
	  button from also being interpreted as "start new selection", thus
	  wiping out the current contents of the unnamed register.
	+ turn off cursor prior to copying to clipboard via right mouse button.
	+ turn off cursor prior to pasting with middle mouse button.
	+ these changes appear to now prevent the editor from dropping stray
	  cursor glyphs in the text windows (although the editor will still
	  occasionally leave cursor glyphs in the message window due, perhaps,
	  to race conditions between the GDI and the editor's event loop).
	+ a couple of minor fixes for shrinking/enlarging a window via a left
	  mouse button drag of the mode line.

 (tom) 991010 (w)
	+ add syntax filter for Python scripts, and associated pymode.
	+ correct bug in ^X-^, which did not copy special characters such as
	  arrow keys.
	+ correct bug introduced in rewrite of ^X-( and ^X-) command for 8.3,
	  which left ^X-) on the end of the recorded text (reported by George
	  Eccles, analysis by Paul Fox).
	+ add $kbd-macro variable to show the contents of the keyboard macro.
	+ install perl modules as data, not scripts (patch by Ryan Murray).
	+ minor fixes with EXTERN_CONST definition to allow building xvile and
	  vile with g++ on Linux.
	+ remove unused/obsolete code for dot-replays-macro in input.c
	+ modify write_message() in perl.xs to erase the message line if the
	  message is empty, e.g., in the end of lock.pl
	+ correct handling of leading blanks for '#' comments in xs-filt.c
	+ add VAREV to special case handling of terminfo/termcap no_color_video.
	+ disallow execution of '<' register, i.e., by "@<".
	> patches by Clark Morgan:
	+ $cfgopts now shows whether a Unix-hosted editor uses TERMCAP or
	  TERMINFO screen DB.
	+ directory lookup via CDPATH enabled on all hosts (previously only
	  supported on UNIX), but only tested on VMS, Unix, and Win32 (don't
	  have access to DOS, OS/2, BEOS).
	+ documented win32 double/triple click feature.
	+ added $cdpath, which is the editor's copy of the external CDPATH
	  environment variable.  This state variable is read/write.
	+ The components of $CDPATH are glob'd before use, which means that
	  specifying things like:
	      Unix:
		export CDPATH="~/srcdir:~/blddir" # quotes prevent tilde expn
	      Win32 (using a unix clone of the Bourne shell):
		export CDPATH=c:/pro*/dev*/vc;e:/cm/projects
	  will work.

 (tom) 991004 (v)
	+ remove the VT52-style fallback_arrows[] entry, from 8.3u, since it is
	  too easy to confuse it with type-ahead (reported by Clark Morgan).
	+ change testing order in configure script for 'const', to build on
	  HP-UX (reported by Michael Finken ).
	+ make functions attributeregion() attribute_cntl_a_sequences() and
	  attribute_from_filter() interruptible.
	+ correct limits of ^X-Q using goto-char function; it was not clearing
	  the last line since the region-shape is set to EXACT unless
	  overridden.
	+ merge clear-attributes-til with attribute-normal-til.
	+ fix (partly) the lack of syntax highlighting when editing filters.rc
	  or other initialization file by reevaluating the majormode of the
	  current buffer after all buffers are loaded during initialization.
	+ change a typealloc(CMDFUNC) to use typecalloc, so the c_args pointer
	  is initialized.
	+ change ifdef in tgetc() which relates to older Linux kernels (up to
	  early 2.0) to BUG_LINUX_2_0_INTR, so it is disabled.  This does not
	  appear to malfunction with 2.0.36, so we can enter quoted ^C's.
	+ remove ABORTED() check from read_quoted(), since that prevents us
	  from entered an escape or similar character (such as intr) when
	  quoted (see 8.3k).
	+ change sysmapped_c() to return early if term.getch() returns a -1,
	  since we don't want to try to map that: an indefinite stream of
	  EOF's can come out of ttgetc in at least one instance on Linux.
	+ eliminate use of yytext in local functions of filters, since that does
	  not work with SCO's lex (fdl-filt.l, xs-filt.l).
	+ add vile-txt-filt, vile-xs-filt to makefile.wnt
	+ modify makefile.wnt to set related $(cdebug) and $(ldebug) when
	  DBG symbol is set.
	+ modify expansion of tilde by winvile to take into account $HOMEDRIVE,
	  used on WinNT to denote the drive on which a user's desktop is
	  located.
	+ add mode 'cd-on-open', to set working directory to a given file when
	  reading it into a buffer.  Use related logic to make winvile cd to
	  the directory of the last-specified file when invoked, so it is
	  consistent with drag/drop behavior.
	> patches by Clark Morgan:
	+ sever vile/winvile's dependence on $COMSPEC and additionally permit
	  launching apps that are neither blocked by the editor nor launched by
	  a shell.
	+ add command to swap the Ctrl+Insert and Alt+Insert bindings.  Patch
	  triggered by Alex Wetmore's comments (many months ago) that he felt
	  the current clipboard bindings were not optimal for use:
	  a) with the left mouse button (which always copies text to the
	     unnamed buffer), and
	  b) by experienced Windows users who will expect Ctrl+Insert (a
	     Windows Standard key binding) to copy data to the clipboard
	     without being prompted for a region.
	+ include rms.h from estruct.h to make nefsms.h compile properly on
	  VMS (fixes a problem introduced by restructuring of modetbl in 8.3o).

 (tom) 990926 (u)
	+ allow adjustment of window size in win32 versions (vile, winvile) by
	  dragging the modeline.  Clicking on a modeline clears the selection.
	+ modify drag/drop logic in winvile to set the current working
	  directory to the last dropped file.
	+ add alarm on attempt to paste selection into a readonly buffer
	  (reported by Clark Morgan).
	+ correct logic in glob_match_leaf(), which did not allow a pattern
	  to end with '*', e.g,. ":e make*in*" would not match makefile.in
	  (reported by Clark Morgan).
	+ add fallback definitions for cursor keys in tcap.c.  When running
	  'screen' 3.7.6 on Redhat 6.0, which is linked with ncurses, screen
	  makes a bogus $TERMCAP from the terminfo entry, which doesn't
	  necessarily correspond with the actual termcap entry.  I found that
	  my cursor-down was not recognized since the $TERMCAP said it would
	  not be provided, while 'screen' actually delivered OB.
	+ integrated winvile's popup menu with the system menu, adding an entry
	  to enable/disable the popup menu so that the right mouse button can
	  be used for copying selections to the clipboard.
	+ improve vile-make-filt by coloring variables in strings.
	+ minor fix for single-quoted strings in vile-sh-filt, to handle
	  escaped newlines, which are not needed, but terminated the pattern
	  early.
	+ correct handling of default color in color-schemes; it was being
	  internally set to the actual color rather than the special code for
	  'default', so one could not reset the colors automatically.
	+ correct a typo in setting color schemes that used the background
	  color where the cursor color was intended.
	+ fix for ccolor mode in xvile, for 8-bit displays: the cursor is not
	  necessarily colorable if we do not allocate enough GC's.

 (tom) 990920 (t)
	+ implement drag/drop for winvile.
	+ ensure that win32 and termcap versions do not allow paste into buffer
	  that is marked 'view'.
	+ correct background in os2vio.c (the 980930 change for blink versus
	  bright does not apply to OS/2 full-screen windows, but only the
	  stand-alone mode).
	+ modify dummy functions for setting fcolor, bcolor, ccolor to restore
	  the default value rather than allow setting misleading value to be
	  set when the corresponding mode is not really supported.
	+ ifdef'd out with OPT_POPUP_WINOPEN popup menu for winopen command,
	  added it to the system menu.  This gets in the way of mouse
	  selection/extension and (for 2-button mice) prevents pasting with the
	  middle button.
	+ implement double- and triple-click selection with win32 console and
	  gui, as well as pasting with button-2.  There's no simple way to
	  implement button-3 extension as in tcap.c, however, for win32 console.
	+ correct a spurious decrement of bp->b_bytecount in
	  strip_if_dosmode(), from 8.3q changes.
	+ implement 'default' color for all drivers, to simplify ccolor.
	+ add term.setccol(), to allow changing the cursor color for
	  drivers that support it, e.g., xvile, along with mode ccolor.
	+ change OPT_TITLE's action routine to show $progname value rather
	  than "vile".
	+ make OPT_TITLE apply to xvile, using X resources rather than WM
	  properties (patch by Rick Sladkey, modified by suggestion from Kevin
	  Buettner to integrate it with existing $title logic).
	+ fix:  xvile doesn't recognize XK_KP_* keypad keys such as the arrow
	  keys on the numeric keypad when numlock is off.  This is particularly
	  bad for users with Sun Type 4 keyboards where there is only a single
	  numeric/cursor keypad.  (The Solaris X server may not return XK_KP_*
	  keysyms by default, the OpenBSD one does.) (patch by Christian
	  Weisgerber ).
	+ add a note to the VMS build scripts (descrip.mms and vmsbuild.com)
	  to caution installers to delete generated headers and object files
	  between building vile.exe and xvile.exe (patch by Clark Morgan).

 (tom) 990914 (s)
	+ modify list mode to show the actual record separator rather than ^J.
	+ correction to change in 8.3q, to writereg() and getregion(), to
	  account for length of recordseparator when it is crlf.  This also
	  affects (because the r_size value changes) wordcount(), ldelete(),
	  and several places in perl.xs
	+ modify text color model in x11.c to work like tcap.c, adding explicit
	  fcolor0 and bcolor0 resources and changing logic that implements the
	  fcolor and bcolor modes to update GC's at runtime.
	+ modify find_in_path_list() to use caseless comparison on systems that
	  need this.
	+ modify inout_popen() to convert pathname to backslashes on DOS, etc.
	+ modify HighlightFilter to check if the filter is found in $PATH before
	  deciding to build up the pathname.
	+ modify logic in tcap.c to prefer AF/AB over Sf/Sb even if the number
	  of colors is greater than 8.  That makes the $palette strings for
	  xterm-16color easier to work with.
	+ add "cs" as abbreviation for color-scheme; updated vile.hlp and add
	  palettes.rc to show examples.  correct expression in chgd_scheme()
	  for selecting the color-scheme.  Add "use=" clause to color schemes
	  to simplify construction of black and white schemes.
	+ convert as needed slashes to backslashes in displayed pathnames in
	  which-source and which-exec commands.
	+ modify dofmt() to make its repertoire closer to printf's: remove 'D'
	  format code, and change 'p' to 'Q', 'u' to 'f'.
	+ modify logic in tcap.c to use 'reverse' mode in preference to
	  'standout', and either in preference to color when there is a
	  conflict.  This works around an error in several termcap entries
	  (including screen's), which do not mention NC (no_color_video).  This
	  error made selection highlighting not work.
	+ correct my recent cleanup of tracing TGETSTR calls in tcap.c, which
	  broke the merging of similar control sequences.
	+ correct typo in PutModename() call that shows recordseparator,
	  which caused GPF on NT.

 (tom) 990907 (r)
	+ correct oversight in 'eval' command, which evaluated only the first
	  token.
	+ revised macro-parameter logic to rely on parameter template in the
	  store-procedure command rather than accepting unsolicited parameter
	  lists.  This works better with command-completion (fixes a problem
	  reported by Duncan Sargeant).
	+ set txtmode in manpage buffers to simplify further optional
	  highlighting
	+ check if vile_is_busy, suppress menu operations if true.
	+ corrected problem in perl.xs introduced by changes for definition of
	  VILE_LIBDIR_PATH which dropped the trailing '/', by modifying logic
	  in perl.xs to use pathcat() function.  This also avoids modifying the
	  corresponding environment variable.
	+ modify lock.pl to work when the system uses shadow passwords.  Also,
	  modify menu.c and x11.c to ignore mouse operations while the editor is
	  locked.
	+ add ®ister function, so the contents of an internal register may
	  be manipulated in macros (request by Otavio Exel).
	+ add configure check for , needed for SCO which defines
	  FIONREAD there.  This fixes screen output, avoiding the fcntl bug,
	  but still does not make arrow keys work since the FIONREAD ioctl does
	  not work on SCO.  Using select or poll makes it much slower.

 (tom) 990904 (q)
	+ modify check for curses/termcap library for FreeBSD to exclude
	  curses library, preferring either ncurses or termcap.
	+ rename isspecial to isSpecial because FreeBSD 3.1's ctype.h conflicts
	+ make ^X-^X command interruptible
	+ modify majormode logic so that when a user sets a majormode for a
	  given buffer, the side-effects that are performed for each of the
	  modes associated with the majormode are performed in this context
	  as well.  Previously the mode values were simply attached.
	+ recount buffer size after set-dos and set-unix commands to take into
	  account the length of the line-ending.
	+ force a null on the end of the result from special_formatter(), which
	  is used to display the ^G command.  Sometimes there was no null,
	  causing the output line to get trashed.
	+ add buffer mode recordseparator to set dos/unix modes like the
	  set-dos and set-unix commands, i.e., not delayed til the next buffer
	  read like the 'dos' mode.
	+ add vile-tbl-filt to makefile.wnt
	+ add *.ksh to shmode
	+ workaround in exec_sh_c() for OS/2 EMX special requirements for
	  slash/backslash conversion.
	+ reduce compiled-in Unix $startup-path to the path on which we
	  install the filter programs, incidentally correcting path
	  separator in default value for $startup-path on OS/2 EMX
	+ add commands which-source and which-exec to show which file would
	  be source'd and exec'd from $startup-path and $PATH + $libdir-path,
	  respectively.
	+ add logic, also used for type-ahead testing to catnap for BeOS, making
	  the cursor and function keys work.
	+ modify catnap() to use its select/poll logic for tty type-ahead tests.

 (tom) 990829 (p)
	+ modify test for terminfo/termcap library support to look for curses
	  library first.  SCO's native termlib does not support color, though
	  the UDK's termlib does.
	+ eliminate SCO-specific ifdef SYSTEM_LOOKS_LIKE_SCO, which really
	  applied to v4.  Tested with sco3.2v5.0.5 (aka v5).
	+ correct a negative array index for ctrans[] in show-colors command.
	+ remove unneeded putnpad() from tcap.c
	+ fix excess initialization of kbindtbl when --disable-extensions is
	  configured using macro KBIND_LINK.
	+ modify htmlfilt.l to highlight aliases for special characters, e.g.,
	  "<".
	+ minor fixes for tc-filt.l, to allow for entries that are missing the
	  trailing '\', and to allow for entries without a description.  Also,
	  allow '.' and '_' in alias names.
	+ correct typo in suffix expression for cshmode.

 (tom) 990822 (o)
	+ add &pquote function to simplify use of &lookup when the result might
	  contain spaces, and $exec-suffix variable.
	+ add &cclass function, and set-char-class, unset-char-class and
	  reset-char-classes commands.
	+ add tbl-filt.l, for modetbl and cmdtbl highlighting.
	+ add .login and .logout to csh mode.
	+ modify pictmode to use ~local.
	+ modify HighlightFilter and ShowManpage, ShowFormatted macros to use
	  &lookup and related functions to construct the pathname of the filter
	  program, bypassing possible reset of $PATH in the subshell.
	+ add FL_LIBDIR to cases in cfg_locate(), corresponding to $libdir-path
	+ add $pathlist-separator variable.
	+ add functions &word and &token for simple parsing of strings.
	+ add functions &lookup, &path and &pcat to provide support for
	  external pathname manipulation.
	+ moved symbol table for DIRECTIVE to modes.c, to generate it from
	  modetbl and incidentally fix an ambiguity in name resolution, since
	  the old table was not automatically sorted.  Since it is handled as
	  by the enumerated-mode value code, directive names are now processed
	  ignoring case.
	+ add &execable test for files.
	+ add "&random" as alias for "&rnd", "&readable" as alias for "&rd",
	  make all &function names long enough to be more readable.
	+ add check for menufile-not-found in do_menu, to avoid passing a null
	  pointer to fopen (reported by Graeme Miller).

 (tom) 990817 (n)
	+ if .vilemenu is not found, return status to main.c so we can popup
	  appropriate message.
	+ remove const qualifiers from some functions whose data really are
	  modifiable: next_buffer_line(), get_token(), tokval (), user_reply().
	+ BeOS has nonworking 'select()', and no corresponding fd_set
	  declaration.  Add CF_TYPE_FD_SET configure check to handle this.
	  (I'll write some BeOS-specific code to make cursor-keys work).
	+ BeOS does not define O_NDELAY; undef'd USE_FCNTL in this case.
	+ correct ifdef for ttyname(), was HAS_TTYNAME, to use this on BeOS.
	+ add fdl syntax highlighter.

 (tom) 990805 (m)
	+ add vile-perl-filt to makefile.wnt
	+ minor improvement to txt-filt.l, to reset quoted mode when a blank
	  line is found.
	+ minor correction to bat-filt.l, workaround for apparent bug in flex
	  which is treating a '?' as '+'.
	+ minor correction to difffilt.l, forcing word boundary after "diff"
	  and "Binary".
	+ modify complex fence matching so that if too many iterations are
	  needed for the match, that it can still try the simple fence matching.
	  A warning message will be displayed if the fence-limit timeout
	  expires.
	+ modify perlmode complex fences by merging "do" and "while" groups,
	  making that a little faster.
	+ change fences-limit from a scale factor to timeout in seconds to make
	  it simpler to understand/configure.  (This and the perlmode change
	  address a problem reported by Chris Sherman ).
	+ correct vilemode complex fence patterns (the patterns were not
	  anchored to "^").
	+ modifications for egcs 2.91 (compiler warnings about missing
	  initializers for structs where 0's are fine).  egcs 2.91 also has a
	  bug causing it to emit a lot of warnings when it saw a missing const
	  in the qsort comparison functions.

 (tom) 990717 (l)
	+ turn off OPT_CACHE_VCOL, still too experimental.
	+ correct flag that would force window repainting in set-dos-mode
	  command, lost by optimization in 8.3k.
	+ correct a syntax error in configure script's --with-no-leaks option.
	+ fix several memory leaks in majormodes with new function
	  free_sm_vals(), etc.
	+ correct logic in write_string(), an infinite loop would result if the
	  string contains a null (filters.c)
	+ suppress $read-hook in readin() if we are not reading the current
	  buffer.  This can happen as a side-effect of the :tags command, and
	  would cause the prompt to be overwritten by the message from
	  highlighting the current buffer.
	+ add HighlightClear macro, bound to ^X-Q (request by J Chris Coppick).
	+ add goto-char command, bound to ^X-G.
	+ add variable $bwindows
	+ add variable $curchar
	+ add variable $lcols
	+ add variable $position-format
	+ implement a simple 'eval' or 'execute-string' command, allowing users
	  to construct commands dynamically.
	+ use new function vms_fseek_ok() to check if quickreadf() would not
	  successfully read a file whose record structure prevents VMS's read()
	  function from reading it in one call (patch by Clark Morgan, reported
	  by Adam Denton).

 (tom) 990705 (k)
	+ correct logic of read_quoted() from 8.3j, which no longer accepted
	  nondigits after a control/V, e.g., ^V^D.
	+ add commands to move the cursor up/down by rows on the screen, ignoring
	  wrapping: next-row or ^X-^D and previous-row or ^X-^U.
	+ add a check for negative array index in l_to_vline(), which would
	  cause a core dump when changing a buffer with very long lines to
	  linewrap mode and back again.
	+ make wrapper for the most frequently called form of mk_to_vcol(),
	  dot_to_vcol() and in that function cache a location on the current
	  line "close" to DOT, so we can make fewer calls to mk_to_vcol().
	  Ifdef'd this with OPT_CACHE_VCOL.
	+ correct sign of shift-parameter in call of mvleftwind() from
	  gotobol().
	+ correct test before calling updall(), which was updating the whole
	  window each time WFMODE was set, e.g., when updating the ruler.
	+ minor optimization (2-3 times faster) of calls to mk_to_vcol() to
	  reuse the ruler's column value in updpos() if it is up to date.
	+ modify calls to mk_to_vcol() so we show the effective column
	  consistently in [Registers], which has a left margin.

 (tom) 990703 (j)
	+ implement set-window command (request by Adam Denton).
	+ implement show-marks command.
	+ rename 'quote()' to 'quote_next()', split-out 'read_quoted()' to
	  reuse the logic that recognizes ^V followed by a number in input.
	  Now the minibuffer can accept any character except for nulls
	  (originally requested by Sean Ahern, but Adam Denton reminded me).
	+ modify txt-filt.l to highlight strings in double-quotes.
	+ change kbd_reply() to ensure that last_eolchar is set either to
	  a newline or a blank if we are interpreting a macro.
	+ correct array limit in save_arguments(), which was one too small,
	  and added a double-check against that limit.
	+ add a sample of .indent.pro (i.e., doc/indent.pro) to use with indent
	  2.x (we're not planning to use this wholesale, but piecemeal, since
	  even indent 2.0 has bugs ;-).
	+ undefine 'dofile' in perl.xs, to build with perl on Redhat 6.0 (Kevin
	  Buettner).
	+ correct two minor, but annoying warning messages in perl.xs:
		Attempt to free unreferenced scalar
	  by incrementing a reference count, and
		BUG: getregion: no mark set in this window
	  by checking for null MK before call to getregion.
	+ add ShowFormatted macro to manpage.rc, bound to ^X-n, which renders
	  the current buffer with nroff.
	+ rename manpage macro to ShowManpage
	> patches by Paul Fox:
	+ make the Entering/Leaving nesting work correctly if you jump into the
	  middle of an error buffer.  previously selecting a line partway
	  through the buffer would cause vile to skip parsing the preceding
	  change-directory directives, so it wouldn't know where the referenced
	  file was to be found.  now, if you don't use ^X^X to traverse the
	  buffer linearly, the preceding lines are re-parsed as needed.
	+ changed fence.c over to 4 column indents, using indent, plus some
	  hand editing on continuations and comment alignment.
	+ modify vilefilt.l to accept hyphens in identifiers

 (tom) 990621 (i)
	+ add vile-pager to install rule.
	+ add macros (e.g., manpage.rc) to install rule.
	+ implement $(DESTDIR) variable in Unix makefiles to simplify packaging
	  binary distributions.
	+ corrections to CF_MAKEFLAGS configure macro, to work with POSIX
	  'make', which may pass assignments in the $(MAKEFLAGS) variable.
	+ update some configure script macros: CF_CHECK_ERRNO, CF_HEADER_PATH,
	  CF_LIBRARY_PATH, from lynx/xterm changes, as well as mkdirs.sh
	  and install.sh adapted from autoconf.
	+ make the [Variables] buffer partly animated; updating after
	  set-variable commands, and as a side effect of the save/restore
	  function for macro arguments.  Most variables are set internally,
	  however, so do not expect the buffer to jitter as you move the cursor
	  around.
	+ implement parameters for procedures (see macros.doc).
	+ modify ifdef's for hooks to use new symbol OPT_HOOKS, since they are
	  not really dependent on OPT_PROCEDURES anymore.
	+ change run_a_hook() to use docmd() rather than run_procedure(), so
	  the hook can be an arbitrary command, rather than only procedures
	  (suggested by Brendan O'Dea).
	+ correct call on screen_string in ask_for_bname, which had the wrong
	  length, hidden in screen_to_bname macro.  This made ^X-k use a length
	  of 4, rather than the actual buffer length.
	> perl scripts by Kuntal Daftary (from his notes):
	+ lock.pl is a simplistic extension to allow you to lock your vile
	  sessions, say while temporarily leaving your terminal or something
	  like that.
	+ spell.pl is a spell checker within vile that behaves (almost) like
	  ispell (and in fact does use ispell internally).  This one is
	  inspired out of recent mail Christian Lindig providing a spell
	  filter.  Also thanks to Tom for the -a flag :-)
	+ pod documentation is within the files themselves. just dump all the files in
	  your ~/.vile/perl
	+ spell.pl also required me to rig up a mlreply_opts command as an
	  addition to the mlreply_* family of commands already offered in the
	  Vile package.  Tho the invocation is quite similar to the builtin
	  mlreply_* commands, the behavior is simplistic, and does not exactly
	  match that of other Vile commands, e.g., mini-buffer editing is not
	  supported and TAB-completion behavior is different.

 (tom) 990614 (h)
	+ updated example in menus.doc, dropping references to macros not in
	  our source distribution.
	+ add no_errs flag to suppress bells when ~force is in effect.
	+ implement clear-attributes-til, to allow reset of all video attributes
	  and highlighting.
	+ implement wildcard matching in :kill-buffer, so one can do
		:ki *.log
	  to discard all files ending with ".log".  I used filename wildcards
	  rather than regular expressions.  If no wildcard matches, the normal
	  matching is used, e.g., filename or buffer number.
	+ implement name-completion for killbuffer(), usebuffer(), finderrbuf()
	  and execbuf().
	+ correct logic in x11.c which sets window manager hints for icon; it
	  did not first ask for the existing hints.  This caused some window
	  managers (olvwm, for instance) to ignore FocusIn events (Mark
	  Robinson ).
	+ modify logic of insert_namebst() and delete_namebst() to allow
	  redefinition of builtin commands.  The builtin command is moved to
	  the redefns table until the user deletes the command that redefined
	  it (request by Alex Wetmore).
	+ modify c-filt.c to highlight floating point constants.
	+ modify write_string() function in filters.c to avoid writing a
	  newline that's beyond the limit of the string passed as parameter.
	  This fixes a case in m4-filt.l that would write an extra newline
	  after comment lines containing only a "#".
	+ add "/**/#" lines to imakemode preamble pattern, to accommodate old
	  (i.e., obsolete) Imakefile's that rely on pre-ANSI cpp's.
	+ suppress blank messages in perl.xs

 (tom) 990607 (g)
	+ add distinct prefixes to warnings written in perl.xs with write_message
	  to aid in debugging.
	+ restore ability of Vile::get to return values of internal variables
	  without requiring the '$', e.g., Vile::get('$seed').
	+ remove a check in Vile::set which tested if we can get a variable's
	  value before attempting to set it.  A few variables (e.g., $cryptkey)
	  may be writeonly, and temporary variables (e.g., %foo) have no
	  predetermined value.
	+ add numbers, email addresses and urls to txt-filt.l
	+ tweak diffmode suffixes, adding .dif and .diffs
	+ implement ":set video=reverse" for tcap.c, correct rendition of
	  selection in ntwinio.c as well.
	+ add Perl extensions syntax filter xs-filt.l and associated xsmode.
	+ tweak perlmode preamble to allow relative paths.
	+ add a note in vile.hlp explaining how to use $shell=/bin/sh to
	  circumvent reset of $PATH in ".cshrc", so value in $VILE_LIBDIR_PATH
	  is inherited automatically.  I didn't mention there, but I have been
	  using this for several years, having found that SunOS's make program
	  would dump core when running in vile if I left $shell=/bin/csh.
	  It's faster anyway...
	+ add ftp site info to vile.hlp
	+ add ifdef in ntwinio.c to support wheel-mouse, must add
	  -D_WIN32_WINNT=0x400 to makefile.wnt (patch by Alex Wetmore).
	+ correct ifdef in x11.c to so wheel-mouse support compiles properly
	  when menus are not used (patch by Kevin Buettner).
	> patches by Clark Morgan:
	+ minor patch to forces wvwrap to pop winvile to the foreground
	  (convenient when winvile does not currently have focus).
	+ a new "sync-file" command enables synchronization of winvile's
	  current buffer with the DevStudio text editor.  When this command is
	  used in conjunction with visvile's key redirection feature, it's now
	  possible to set a breakpoint in DevStudio from winvile like so:
	  + use winvile's search capabilities (including tags) to find the
	    program location where a breakpoint is desired, and
	  + press F9 (standard DevStudio shortcut that sets/clears a
	    breakpoint).

 (tom) 990602 (f)
	+ implement fcolor and bcolor options for xvile.
	+ add missing case for VALTYPE_ENUM in listvalueset(), which caused
	  very long enum values to be run-on in [Settings].
	+ add mode 'video-attrs', mainly to implement bold text as part of the
	  color schemes.  I tried implementing reverse, but this is hard to do
	  in tcap.c
	+ add color schemes, associating fcolor, bcolor, $palette and an
	  optional video attribute.  This adds new commands to manipulate the
	  schemes:
		define-color-scheme
		remove-color-scheme
		show-color-schemes
	+ allow ':' for first line of Bourne shell
	+ recognize \f1 and \f4 in nr-filt.l
	+ modify preamble pattern for tclmode to allow version number, e.g.,
	  wish4.1 vs wish.
	+ improve sh-filt.l so that option strings such as "--with-8bit" do not
	  highlight the "8".
	+ modify sel_yank() to set curtabval temporarily so tab/offset
	  computations in yankregion work properly when user has selected a
	  rectangle in one buffer, then clicks the mouse into a buffer with a
	  different tabstop setting (reported by Clark Morgan).
	+ improve makefile.l, handling escaped newlines in quoted strings and
	  in target lists.

 (tom) 990523 (e)
	+ add/use new function restore_dot() to guard against restoring DOT to
	  a value which no longer points into the current buffer, e.g., after
	  modifying it.  This fixes a core dump in xvile when selecting in the
	  [Registers] buffer.
	+ improve perl syntax filter by parsing patterns following =~ and =!
	  operators.  (Patterns may also be in other places).
	+ comment-out save/restore of $CFLAGS in configure.in via the
	  saved_CFLAGS, since that interferes with configuration on HP-UX 10.20
	  with HP's ANSI compiler, which does not support ANSI C without
	  specifying an option.  As a result, all of the checks for missing
	  function prototypes failed, as well as the checks for terminfo vs
	  termcap (reported by Micheal Finken).
	+ simplify mlerror, allowing for the possibility that strerror may
	  return a null pointer.
	+ correct quoting for configure script's --with-exec-macros option,
	  which prevented users from setting that values (reported by Michael
	  Finken ).
	+ turn off crypting during reads/writes to a pipe.  This is needed in
	  crypt mode in order to support macros that pipe text to an external
	  program for filtering.  Without this change, instead of the actual
	  text, the encrypted text is sent to the external programs which will
	  most likely result in incorrect behavior.  (patch by Daniel Palermo
	  ).
	+ provide default colors for xvile similar to those used by vile for
	  fcolor1 through fcolor15 (patch by Brendan O'Dea).
	> patches by Clark Morgan:
	+ removed duplicate winopen and winopen-nocd documentation from
	  vile.hlp
	+ winvile only paints its frame once at startup.
	+ added logic to ensure the the winvile frame is completely exposed on
	  the desktop (i.e., not clipped by taskbar or painted offscreen).
	+ further changes to permit a winvile user to specify any geometry that
	  lies within the region bounded by the current desktop screen.
	+ setting winvile font via dialog box now repaints screen (in all
	  cases) and flushes status message to mini-buffer.
	+ fixed a couple of minor problems with wvwrap when setting winvile's
	  current working directory.  Wvwrap also makes sure the editor is
	  visible.
	+ finally, a rather big change, I've dumped the oleauto Open method.
	  As it turns out, this was a bad idea.  I saw cases 2nite where the
	  editor was "simultaneously" changing its working directory and
	  opening a file.  Not good.  This kind of race condition is avoided
	  when VileKeys() "drives" the editor because all of winvile's commands
	  are serialized via a Windows message queue.

 (tom) 990519 (d)
	+ remove fragment of code in c-filt.c which left it incorrectly parsing
	  "string1""string2" (reported by Alex Wetmore).
	+ implement $palette for xvile, allowing colors to be permuted.
	+ add show-colors command, to show the color names and $palette values
	+ change get_token() and mac_tokval() to use TBUFF's, making them
	  independent of buffer length.
	+ change replacepat to a TBUFF.
	+ correct logic for $kill, which did not account for killbuffer
	  rotation and was always pointing to the same index.
	+ change statevar.c to return results in TBUFF's, making it independent
	  of the caller's buffer size.  This fixes some trash after the display
	  of $kill in show-variables.
	> patches by Clark Morgan:
	+ add winopen and winopen-cd commands to w32 vile.
	+ hook the winvile right mouse button to the new winopen command.
	+ Add an Open method to winvile ole automation server, which may be
	  used to directly open a filename in the editor (thus avoiding the
	  overhead of VileKeys).
	+ Added wvwrap.exe to the Win32 distribution.  This utility opens one
	  or more files in a _single_ winvile instance via a right mouse click
	  in the Windows Explorer.  For more details, please read
	  doc/oleauto.doc .
	  [ Note: wvwrap.exe is Ed Henderson's brainchild and he wrote the
	    original version of the program.  Thanks, Ed! ]

 (tom) 990510 (c)
	+ fix an overlooked reset of lines read if we are reading via
	  attribute-from-filter
	+ add logic to pathname completion to supply slash if given an
	  environment variable that evaluates to a directory name, e.g., $HOME
	  (request by Kuntal Daftary).
	+ add warn-blanks mode, to allow users to be prompted if they give a
	  filename which has nonprinting characters (request by Tom Serkowski
	  )
	+ correct (supply) class-inheritance in filters.c function keyword_attr.
	+ modify filters.c to support arbitrary strings as .class values, used
	  this to parameterize m4 filter.
	+ minor resync of autoconf macros with xterm and lynx.
	+ add M4 syntax filter.
	+ correct handling in makefilt.l of escaped quotes outside a string.
	  Also, highlight $(name), like ${name}.
	> patch by Clark Morgan:
	+ remove race condition in winvile (in ole-auto mode) when keystrokes
	  are redirected to DevStudio (noticed on a networked, NTFS drive).
	+ fix typo in filters/makefile.wnt -- nmake won't allow use of both
	  ':' and '::' for the same target.
	> patch by Gary Ross to add support to xvile for wheel mouse:
	+ modified x_process_event to scroll up/down for Button4 and Button5
	  button press events.
	+ added a new resource XVile.wheelScrollAmount to set the number of
	  lines scrolled for each occurrence of these events.  (Default is 3).

 (tom) 990503 (b)
	+ correction to SSTRING and DSTRING symbols in perl, other syntax
	  highlighters.  The backslash character was not given as part of the
	  excluded character range, making escaped quotes and escaped
	  backslashes handled improperly.
	+ improve mlerror() function for VMS.  Any errno with the special value
	  EVMSERR requires special translation.  This translation was not being
	  done by vile, which caused the editor to occasionally display an
	  "unknown error" message.  Example:
		  $ vile x.y.z    ! invalid file syntax not flagged by vile
	  (patch by Clark Morgan).
	+ add RCS majormode and syntax filter.
	+ add SCCS syntax filter.
	+ rename sccsmode to SCCSmode, to workaround majormode's name
	  resolution; suffixes are done alphabetically.

 (tom) 990429 (a)
	+ minor tweak to c-filt.c so it can be used on gcov output:  the GNU
	  coverage tool puts a count down the left margin to show lines
	  executed, and "######" where they're not.  c-filt.c did not expect
	  the latter, and omitted some of the #'s.
	+ correct install rule in filters/makefile.wnt, which combined the
	  rules that should have gone to VILE_STARTUP_PATH with the ones
	  for VILE_LIBDIR_PATH.
	+ remove/correct obsolete description in vile.hlp for syntax filters
	  (reported by Clark Morgan).
	+ update README to describe 8.3 (patch by Clark Morgan).
	+ correct use of $(MAKEFLAGS) in makefile.in, which is all of the
	  makeflags including assignments, not like $(MFLAGS) which was only
	  the flags without '-'.  This made "make EXTRA_FLAGS=-O" fail
	  (reported by Jeff Morriss ).
	+ add -v option to filters, to show files opened and keywords/classes
	  defined, for debugging.  Repeat the -v option for more details.
	+ correct expressions for sccsmode; the ^A characters were given as
	  \001's.

Changes for vile 8.3 (released Fri Apr 23, 1999)

 (tom) 990420 (v)
	+ modify winvile.rc to use VILE_ICON definition, overlooked in previous
	  patch.

 (tom) 990420 (u)
	+ add 32x32 monochome versions of the .ico files, for completeness
	  because automatically generated versions do not work well for color
	  icons.
	+ improved vile.ico by adding 16x16 section (Rick Sladkey).
	+ correct reversed logic for no_msgs variable in perl.xs, from
	  8.2s changes (reported by Ed Henderson).
	+ correct missing return in var_TITLE() on win32 (Clark Morgan).

 (tom) 990418 (t)
	+ add configure option --with-xpm, to support color icons in xvile.
	  Not all window managers support xpm icons.
	+ remove configure test and ifdef's for CC_CANNOT_OFFSET_CASES, since
	  rewrite of eval.c left only one place where we care about this
	  compiler limitation.
	+ add .ico, .xbm and .xpm versions of the most popular icons for xvile
	  and winvile.
	+ use SMG to get control sequences for 80/132 column switching (Clark
	  Morgan, request by Tom).
	+ rewrote vmsopen() in vmsvt.c (patch by Clark Morgan).
	+ update vile-pager script to find vile-manfilt according to the
	  VILE_LIBDIR_PATH setting, etc.
	+ modify majormode suffixes check to exclude pipes and internal names
	+ add ".hlp" to txtmode suffixes (note that the :h command bypasses
	  $read-hook).
	+ add cindent to lex, yacc majormodes.
	+ add sccs majormode.
	+ implement imake mode using C filter.
	+ add syntax filter txt-filt.l, for highlighting simple textfiles.
	+ add syntax filter spellflt.l, for highlighting misspelled words with
	  ispell.  Source "spell.rc" to get the ^X-i spelling highlighter.
	+ add syntax filter difffilt.l for diff output
	+ use "seed" in ucrypt.c rather than rand().

 (tom) 990414 (s)
	+ add "DBG=" option to makefile.wnt to simplify building with OPT_TRACE.
	+ add VILE_LIBDIR_PATH to $PATH on WinNT, as on Unix to find syntax
	  filters more simply.
	+ minor fixes to filters: makefilt.l to handle $$name, sh-filt.l to
	  refrain from highlighting keywords in contexts that look like
	  options, e.g., -enable.
	+ modify makefile.wnt to accommodate Win95: its shell doesn't grok "&&"
	  as a command separator (patch by Clark Morgan).
	+ add 'dist' rules to makefile.wnt
	+ fix core dump for uninitialized $palette in statevar.c (reported by
	  Brian Moore).
	> patches from Paul Fox
	general:
	+ trimmed some old README text
	+ removed margin and scrollsize values from term structs.  they
	  were deterministic constants everywhere anyway.
	+ eliminated TTxxxx() macros, in favor of simple term.xxxx()
	  usage.  ANSI C says the (*term.xxxx)() format isn't necessary.
	  we'll see.
	+ renamed elements of term struct, since the element names are
	  now exposed.  eliminated redundant t_ prefix.
	+ renamed null_xxxx() routines to match.
	+ renamed some globals to better describe their function (e.g.
	  pat, rpat, sres)
	+ in a couple of places globals were lurking in macros (e.g.
	  nexttabcol) and i made them visible.
	+ cleaned up and corrected comments which no longer described the
	  code correctly.
	+ renamed tokenizing #defines, for better mnemonics.
	+ suppressed a couple of arg-unused warnings when building X11 by
	  tweaking ifdefs.

	ibmpc.c:
	+ cleaned up a bunch of code -- moved private defines from estruct.h.
	+ collapsed screen address defines to simplify.
	+ did some renaming for mnemonic clarification.
	+ eliminated unused global flags.
	+ eliminated global "regs" struct/union.
	+ eliminated all support for flicker suppression.  it was cga-only,
	  and wasn't needed on reasonable cards anyway.  we can resurrect
	  it if needed, but i doubt we will.  (also eliminated $flickcode
	  variable which enabled it.)
	+ updated some copyright statements.

	exec.c:
	+ simplified logic surrounding while-loop processing -- a single
	  list is now maintained, rather than the double list shuffling
	  that went on before, and endwhiles now get their own struct on
	  the loop descriptor list.
	+ eliminated recursion when freeing while-loop descriptors.
	+ move save/restore of no_msgs (formerly discmd) inside dobuf().
	+ simplified flags that indicate that macro creation is in progress.

	+ use mlforce() rather than mlprompt() in pressreturn(), and eliminate
	  flag setting no longer required. (spawn.c)
	+ use rand() rather than global "seed" for encryption purposes.
	  (ucrypt.c)
	+ add second %% line to lex "states" check -- it hangs on solaris
	  otherwise.  (aclocal.m4)

 (tom) 990404 (r)
	+ add filters/mms-filt.l
	+ change filters/makefile.in to work when configuring with --srcdir
	  (patch by Brendan O'Dea).
	+ include XBM and XPM versions of [J.] Richard's ``vile screen'' sample
	  icon, ifdef'd with OPT_X11_ICON (patch by Brendan O'Dea).
	+ rename GetEnv to vile_getenv, since VMS linker does not distinguish
	  that from getenv (patch by Clark Morgan).
	+ ignore case in VMS majormode suffix and preamble.
	+ make C-style indent logic available as a mode 'cindent', so it can be
	  assigned as part of a majormode.  It is part of the builtin cmode.
	+ collect logic for read/etc., hooks into common functions to make it
	  simpler to see them.  Save/restore the count of lines read so that
	  the read-hook does not cause vile to report confusing total number
	  of lines read, i.e., the actual file plus the highlighting.

 (tom) 990327 (q)
	+ add filtername mode, to handle special filter cases for java, js, csh
	  majormodes.
	+ modify makefiles to allow vile to compile on *IX systems with the gnu
	  make -j option, to run several C compilers at the same time.  The -t
	  option to lex is at least portable to Solaris lex and flex.  Uses
	  redirection (patch by Ryan Murray).
	+ correct a couple of VMS-specific problems:  assignment through a
	  const pointer in cfg_locate, and implicit string concatenation in
	  personals (patch by Clark Morgan).
	+ rename VILE_LIBRARY_PATH to VILE_LIBDIR_PATH
	+ correct limit-expression in add_brackets() function, which left
	  trash on the end if the buffer name was too long.
	+ update the list of files suppressed by --disable-extensions.
	+ add configure option --with-purify.
	+ modify configure-script so --with-no-leaks option does not require
	  --with-trace.
	+ correct error in 8.2p changes to ucrypt.c, i.e., incorrect workaround
	  for a case where a cast was needed.
	+ revised change to HighlightFilter to add HighlightFilterMsg which
	  writes the "Attaching attributes..." message, leaving the
	  HighlightFilter macro quiet and more suitable for use in $read-hook.
	+ minor changes to make Paul's changes build with perl, tracing
	  and disabled extensions/shell.
	> patches from Paul Fox (includes some documentation from Clark Morgan):
	+ combined eval.c/sindex() and bind.c/ourstrstr() into single
	  routine.
	+ remove redundant mktrimmed() calls when doing buffer lookup.
	  (buffer.c)
	+ moved code for grabbing next line from buffer from eval.c to
	  new routine next_buffer_line() in buffer.c
	+ give credit to Roger Ove for scroll optimization code in
	  display.c
	+ random number generator now based on rand() -- it's present
	  in MSDEV and all UNIXes i know of, but we may need a configure
	  check eventually.  (eval.c)
	+ removed mostly redundant numeric token type.  explicit check
	  for digits in exec.c instead.
	+ major overhaul of how vile's $state (formerly "environment")
	  variables are implemented.  new file, statevar.c, contains
	  support routines, each of which is responsible for both
	  getting and setting a single variable.  dispatch is handled
	  by new table set up by mktbls.c.  this eliminates two of
	  the big switches in eval.c.  the result pointer arg to
	  these routines should probably be a tbuff, which would allow
	  unlimited variable lengths.  (eval.c, mktbls.c)
	+ the code that runs vile &functions has become more table-driven
	  as well.  modetbl now contains information on the return
	  type of the functions, and the types of the arguments.  this
	  cleans up the per-function code somewhat.  (eval.c, mktbls.c)
	+ code for @interactive variables and &query function collapsed
	  to single new user_reply() routine.  (eval.c, statevar.c,
	  input.c)
	+ various other cleanup and name revisions in eval.c:  "user"
	  variables are now "temporary" variables, and "environment"
	  variables are now "state" variables.  utility routines (like
	  ltos(), i_ltoa(), stol()) renamed to render_xxx() to create
	  a string, and scan_xxx() to decode a string.
	+ collapsed the stenv() and set_variable() routines into a single
	  entrypoint usable from both exec.c and modes.c.
	+ split temp and state variable lookup from their evaluation,
	  so the lookup can be done in just one routine.  (eval.c)
	+ token evaluation (tokval()) now table driven.  i don't know
	  if it's much cleaner, but i think it's better.  it's certainly
	  different.  (no, modetbls is not involved, nor should it be. :-)
	+ minor change to HighlightFilter in filters/filters.rc to cause
	  it to not try and color [Special] buffers.
	+ quoting fix in macros/pic.rc
	+ supporting changes:  estruct.h, makefile.in, vile.hlp.

 (tom) 990320 (p)
	+ add an install-rule to filters/makefile.wnt
	+ eliminate restriction on number of command-line arguments in winvile
	  (reported by Ed Henderson).
	+ make VILE_LIBDIR_PATH settable from the environment, as per
	  documentation (patch by Brendan O'Dea).
	+ add/use init_b_traits() function, to ensure that switching to a
	  buffer which was source'd while hidden does not copy bogus values
	  for the associated line pointers back to the window traits (fixes
	  a core dump reported by Paul Fox).
	+ modify addline(), bclear(), ifile() to prevent malloc/free from being
	  interrupted by 'working' mode.
	+ minor fixes to mail highlighting filter, to allow "To: " prefix
	  (reported by Paul Fox).
	> patches from Clark Morgan:
	+ modify home_path() to work around problem on VMS where
		$ vile ~/com/defs.com
	  does not work, nor does tab completion, e.g.,
		:e ~/com/d
	  (the latter was also reported by Ed Henderson).
	+ vile restores original terminal width when it exits (mimics the eph
	  editor's behavior).
	+ added "-132" and "-80" command-line switches to set screen width from
	  command line.
	+ correct computation of prog_arg for VMS, which is used as part of the
	  command-line help message.
	+ modify definition of FOPEN_READ for VMS to allow shared reads from
	  files (reported by Ed Henderson, analysis by Clark Morgan).
	> patches from Paul Fox:
	+ revised macros.doc, touching all previously untouched parts.
	  it's now a little more vile-specific, and a little "tighter".
	+ rewrite strinc() in terms of strcmp()/strncmp(), rename.
	  (bind.c)
	+ converted confusing (to me) do/while() loops to simple while()
	  (search.c)
	+ collapsed keyboard polling code (fcntl version) to single place.
	  (termio.c)
	+ fixed imdying() to:  a) leave a core even if there's a problem
	  saving buffers, b) try all temp directories, rather than quitting
	  on first failure, c) try $TMPDIR first, and current directory
	  last, on all systems, d) warn user that files may be in current
	  directory.  future:  on write error, should try again in other
	  directories.  (file.c)
	+ fix bug where assigning BFEXEC in dofile() was tromping possibly
	  existing flags (like BFCHG, leading to loss of buffer changes)
	  (exec.c)
	+ revised/rewrote entabline/detabline algorithms.  entabline() no
	  longer needs to calle detabline() first.  (region.c)
	+ fixed return status of nextbuffer()/prevbuffer when in
	  noautobuffer mode.  previously did swbuffer to current buffer,
	  which succeeds.  now you can safely loop through the buffers, and
	  know when to stop.  (this makes the new example in macros.doc
	  work.) (buffer.c)
	+ rationalize comments, comment wording, and code grouping (basic.c
	  line.c buffer.c file.c edef.h eval.c bind.c random.c fences.c
	  insert.c search.c window.c word.c display.c main.c input.c)
	+ collapse updext_before()/updext_past() into single routine.
	  purely mechanical -- could perhaps be improved.  show keyboard
	  macro "[recording]" state on modelines (display.c)
	+ begin in state HEADER rather than state BODY (filters/mailfilt.l)
	+ add new &query function, to (eventually) replace interactive
	  @variables.  (eval.c)
	+ collapse starting/stopping of keyboard macro into single
	  function, which acts as toggle.  leave both key-bindings ( '^X-('
	  and '^X-)' ) but one is now redundant.  (input.c vile.hlp)
	+ changed sense, somewhat, of kbd and dot macro state variables:
	  now a two state boolean, rather than a three state.  well, i
	  think it's nicer.  (input.c line.c)
	+ simplify macbug code to take advantage of vararg-capable
	  mlforce() (eval.c exec.c)
	+ revised window grow/shrink algorithms (window.c)
	+ more logical variable naming/grouping (file.c edef.h select.c
	  npopen.c eval.c insert.c search.c display.c bind.c)
	+ change all BUG mlwrites to mlforce (file.c undo.c others)
	+ further encapsulate "crypting" knowledge -- create as ffdocrypt()
	  accessor for "ffcrypting".  (file.c ucrypt.c)
	+ renamed rewritten functions, minor algorithm changes (e.g.  use
	  castrealloc() rather than castalloc()/memcpy() (line.c, file.c)
	+ added lreplc() function, which can safely replace single
	  characters on a line.  (line.c)
	+ eliminated old "#ifdef BEFORE/#if NEVER/unused" code and
	  variables.  (buffer.c, file.c edef.h spawn.c)
	+ uniform use of tb_xxx prefix on TBUFFs.  (edef.h)
	+ removed $truth variable (eval.c)
	+ removed $ramsize variable (eval.c)
	+ guard against possible null pointer dereference of b_fname (eval.c)
	+ remove ENVFUNC ifdefs -- i think all our systems have them (eval.c
	  bind.c)
	+ removed OPT_AEDIT ifdefs.  they weren't protecting much.
	  (region.c opers.c)
	+ added more generic null TERM struct routines, deleted unneeded
	  screen-specific ones.  (termio.c ansi.c vmsvt.c x11.c tcap.c)
	+ hmmm.  should i even mention this one?  :-) (you guys should
	  clearly follow suit.) (version.c)
	+ minor supporting changes (proto.h estruct.h tags.c filec.c
	  w32reg.c menu.c cmdtbl modetbl1 tbuff.c history.c)
	+ comment cleanup, formatting, vestigial code and ifdef removal,
	  increased NSTRING/NPAT.  who needs powers of two?  (estruct.h)
	+ moved incremental search support def'ns to isearch.c (estruct.h
	  isearch.c)
	+ removed id.wing.net from suggested site list from README

 (tom) 990309 (o)
	+ rewrite logic of newwidth() and newheight() (Paul Fox).
	+ modify treatment of 'fillcol' mode so that a zero is interpreted to
	  use the 'wrapmargin' value, and negative values are, like
	  'wrapmargin', counted from the current right-margin (prompted by
	  discussion with Kuntal M Daftary).
	+ minor fixes for ti-filt.c (handle "\\," and terminfo entries without
	  aliases or descriptions).
	+ remove crypt-til operator; this would not work properly on portions
	  of a file.
	+ write ucrypt.c to use Unix crypt(1) if available.
	+ rename crypt.c, move it to filters as ecrypt.c, for building
	  standalone vile-crypt.  will be phased out.
	+ set "vilemode" for macros and procedure buffers, to simplify syntax
	  highlighting of internal buffers.
	+ modify syntax filters so that keyword classes and their instances
	  can be treated distinctly.
	+ correct missing backslash in QUOTDEFS in makefile.in
	+ review/simplified/corrected comment-prefixes and comments modes
	  in filters.rc
	+ correct logic of version_of() function, which did not ensure that
	  the text really looks like a VMS version specification.  From
	  a bug report by Clark Morgan, who said that this works:
		:e ../buf*.c     # look for buffer.c
	  but this doesn't:
		:e subdir/buf*.c
	  Workaround:
		:e [.subdir]buf*.c
	  After fixing version_of(), my fakevms driver processes this properly.
	+ update vile.hlp description of filter programs and renamed section to
	  "Syntax coloring" (patch by Paul Fox).
	> patches by Clark Morgan:
	+ only enable vtflash on hosts that support it (Unix, VMS).
	+ clarify vile/winvile build instructions when using MS tools.
	+ add $pid environment variable for VMS

 (tom) 990212 (n)
	+ increase size of underline cursor for OPT_ICURSOR in ntconio.c
	+ correct dcl-filt.l to handle inline comments
	+ add bash-specific keywords to sh.key (reported by Paul Fox).
	+ add missing assignment to save pre_op_dot in fences.c (reported by
	  Clark Morgan, from VC++ 6.0 warnings)
	+ correct check for return-value of open_region_filter(), which did
	  not look for abort of command, resulting in hanging while trying
	  to close a pipe that was not open (reported by Paul Fox).
	+ change cast in CF_CC_OFFSETOF_CASES to 'long', to accommodate SGI's
	  64-bit compiler.
	+ restore "perldo" cmdtbl entry, for compatibility (Paul Fox).
	+ relax iteration limit for complex fences a little, using new mode
	  fence-limit times the buffer length as the hard limit.  This is
	  still proportional to the buffer length, rather than allowing
	  geometric increase with the fences groups.
	+ add configure option --with-libdir-path to allow override of the
	  default $(libdir)/vile.  Make this alterable with new variable
	  $libdir-path.
	+ change install-directory for filter programs to $(libdir)/vile, to
	  avoid clutter (suggested by Paul Fox).
	+ modify some filters to avoid incrementing yytext since it may be an
	  array.
	+ add configure-check for state support in lex/flex, so we do not
	  try to compile with programs that will not succeed.
	+ correct limit-check in dname_to_dirnum(), missed a case when fixing
	  for 8.2l, which caused pictmode.rc to not read properly.
	> patches by Clark Morgan:
	+ correct codes for 8-bit PF1-PF4 in vmsvt.c
	+ update vile.hlp for vmsvt.c's function key definitions, as well as
	  a note about tilde-expansion on VMS.
	+ add vtflash mode, for tcap.c and vmsvt.c

 (tom) 990202 (m)
	+ suppress TTtypahead() call in sysmapped_c_avail() when we have made
	  characters available in mapungetc().  This fixes a problem where
	  type-ahead would get into the data copied from mapgetc_ungottenchars,
	  breaking arrow key interpretation on slow connections.  (This was
	  reported a few times since 971205, when the problem was introduced,
	  but is difficult to reproduce.  Reported/tested by Clark Morgan).
	+ implement mode mcolor, which lets user set the color of the
	  modelines.  The choices are the same as for visual-matches (request
	  by Han Leushuis ).
	+ update 'doingsweep' in one place only, do_sweep(), to ensure that the
	  TTcursor() calls nest properly when a selection is aborted.
	+ add vt220 7- and 8-bit function key definitions to vmsvt.c (request
	  by Clark Morgan).
	+ removed a FIXME in termio.c for read_vms_tty's assignment to nibuf,
	  having confirmed that the document for the sys$qiow()'s read function
	  says the device-dependent data stores a count of terminator
	  characters (needed for VMS's equivalent to cbreak or cooked modes)
	  rather than data that vile should process (patch by Clark Morgan).
	+ prevent dobuf() from being interrupted by 'working' mode.

 (tom) 990126 (l)
	+ add "~elsewith" directive to simplify use of fences in vile macros.
	+ minor change to kbd_reply to allow abortc to be ,
	  though otherwise nulls are still ignored in that function (request by
	  Christian Lindig )
	+ implement crude iteration-limit for complex fences to guard against
	  blowup in error-handling.
	+ correct/restore handling of keyboard interruption in complex fences
	+ add rules to filters/makefile.wnt so that if $(LEX) is set, the
	  build will use that for the lex/flex program and make the lex-based
	  filters.
	+ add yywrap() dummy function to filters.c to reduce dependency on libs.
	+ change casts in Member_Offset macro to long from int to avoid
	  compiler warnings on IRIX 6.x with 64-bit architecture (reported by
	  Steen Savstrup Kristensen ).

 (tom) 990124 (k)
	+ modify VMS logic in ttopen to use "SYS$COMMAND" rather than "TT:"
	  since the latter does not work with the PIPE command added in VMS 7.x
	  to mimics unix cmdline pipe functionality.  Vile couldn't use this
	  command, though.  For example:
		$ pipe dir | vile
	  failed with an "illegal i/o function" error.  This change allows vile
	  to read from the pipe stream as well as retaining its ability to read
	  from a redirected stdin (patch by Clark Morgan).
	+ reset eofflag in inout_popen, since attribute_from_filter may
	  otherwise see the EOF from the previous file reading operation, e.g.,
	  if the file did not end with a newline.  Likewise set fileispipe,
	  just in case it would be needed.
	+ correct inconsistent spelling of cache variable in CF_TERMCAP_LIBS,
	  which caused the configure script to ignore a predefined termcap or
	  terminfo library.
	+ correct order of -lXmu vs -lXext in Athena-widget configure test.
	+ resync configure scripts against autoconf 2.13 + patches
	+ modify is_vms_pathname(), is_version() to accept a '.' to delimit
	  version number (reported by Clark Morgan).
	+ implement $sres, i.e., 80/132 column switching for vmsvt.c (patch
	  by Clark Morgan).
	+ update version number for Vileserv, missed in 8.2j
	+ rename some operators that accept a range to end with "-til", for
	  consistency (reported by Paul Fox, Clark Morgan).
	+ other improvements to perlfilt.l, e.g., underscores in numbers,
	  a POD-format,, suggested by Brendan O'Dea.
	+ simplify HighlightFilter macro - there is no need to report if no
	  filter exists, after all.  This required renaming nroffmode to nrmode
	  and pascalmode to pasmode (adapted from example by Brendan O'Dea).
	+ apply "group" feature to complex fences, i.e., fence-if, ...,
	  fence-fi.  This allows vile to match both while{...} and if{...}
	  blocks, for a test-case by Kuntal M Daftary.  It works, but is very
	  slow when choosing between patterns that are ambiguous, e.g., the
	  different groups of patterns all end with a "}".
	+ add "group" feature to majormodes, which allows user to define new
	  instances of certain submodes.
	+ ensure GCC_UNUSED is defined in filters.h for platforms that do not
	  use the configure script (reported by Brian Moore).
	+ minor fix to listvalueset() to avoid getting a double-newline.
	+ improve makefilt.l, making it read keyword file.
	+ add latexflt.l to install rule; various improvements to that
	  filter.
	+ improved perlfilt.l symbol table and symbol-parsing based on
	  vile-pfilt.pl (John P Cavanaugh ).

 (tom) 981229 (j)
	+ modify majormode preamble logic to set ignorecase if the majormode
	  sets ignorecase.
	+ modify tcap.c to use no_color_video capability to avoid overwriting
	  colors with nonfunctioning video attributes.
	+ modify html syntax filter to handle embedded JavaScript.
	+ add filters for ada, awk, DOS batchfile, VAX DCL, Java, JavsScript,
	  mail, nroff, sql, tcl/tk, termcap, terminfo, yacc
	+ correct dependencies in filters/makefile.in for keywords files, which
	  live in $(srcdir) (report by Brendan O'Dea, patch by Kevin Buettner).
	+ workaround a parsing problem in lex-filt.l so that STATES and PATTERN
	  can be distinguished.
	+ various fixes to "e!", which did not prompt or repaint properly if
	  the current buffer was from standard input, the unnamed buffer, or a
	  temporary buffer.
	+ correct a missing pointer increment in rewritten c-filt.c, which
	  caused an infinite loop in some cases after '#'.
	+ correct a couple of places where missing '\' character in lex files
	  was interpreted as \a rather than \\a.
	+ correct comparison in is_keyword (filters.c) which caused html
	  keywords to not be highlighted.
	+ add csh mode to filters.rc

 (tom) 981222 (i)
	+ modify expand_pattern() to handle Unix-style wildcards on VMS (reported
	  by Clark Morgan).
	+ add configure option --with-fakevms, for testing VMS port.
	+ change Cpp keyword in vile-c-filt to Preproc, for consistency.
	+ move filter programs to filters subdirectory.	 Split-out the keyfile
	  and symbol management to new file filters.c, and used that to
	  enhance the original vile-c-filt so it no longer has line-length
	  limitations.  Added lex-based filters for cwebx, html, latex, make,
	  perl, sh and vile macros.
	+ prevent repeated call to free from old_namebst from memory-leak fix
	  in 8.2g
	+ add directives ~with and ~endwith, to simplify majormode expressions.
	+ minor refinement to gui_isprint()
	> patches by Clark Morgan:
	+ add pattern to finderr.c to use with DEC C compilers.
	+ modify file globbing so that vile can read these two files from the
	  command line (it already did read them via ":e"):
		../readme or ~/vile.rc
	+ documentation updates for README, README.VMS and README.PC

 (tom) 981214 (h)
	+ simplify some trace-code using new functions visible_buff, lp_visible.
	+ add trace-code for fences.c
	+ correct check for zero-sized window, from 8.2e, which made it
	  impossible to switch to a window with exactly one line (patch by
	  Kevin Buettner).
	> patches by Clark Morgan:
	+ modify ffsize() for VMS so that it returns a 0 rather than -1 if a
	  call to 'fstat()' fails to get the size.  The file exists, so a zero
	  makes vile read if via slowreadf, which works.
	+ modify estruct.h to build using descrip.mms alone: the vmsbuild.com
	  script defines logical "SYS" so that  can be included,
	  but the descrip.mms script does not do that.
	+ update ifdef's to make vile build with VAX C (the 8.0b changes added
	  CC_CANNOT_INIT_UNIONS, which is needed for that compiler).
	+ document problem with DEC C, which causes vile to update revision
	  dates on files even without writing the file.

 (tom) 981201 (g)
	+ fix minor memory-leaks (main.c, bind.c, select.c)
	+ modify finderr.c to use the given filename and ignore the associated
	  buffer name when looking for matching buffers in case we have multiple
	  files with similar names.  Modify getfile() to check first if the
	  given parameter is a filename, rather than preferring match on a
	  buffer name.
	+ optimize tb_bappend and tb_sappend using memcpy rather than loop on
	  tb_put.
	+ add checks for empty/missing filename to dobuf() and getfile() and
	  menu.c to prevent core dump when using "Edit .vilerc" menu entry and
	  no .vilerc exists (reported by John Gotts ).
	+ modify key-mappings in vmsvt.c to avoid defining VT52-style sequences,
	  which introduce the possibility of confusing A for an arrow
	  key (patch by Clark Morgan).
	+ restore part of logic in C/C++ comment formatting modified in 8.0p;
	  which introduced the undesired behavior of not formatting the first
	  line of a comment (patch by Clark Morgan).
	+ implement VMS-specific modes for record-format and record-size
	  (initiated/tested by Clark Morgan).
	+ change default search pattern for VMS to include only current
	  versions of each file, unless mode "allversions" is set (request by
	  Clark Morgan).

 (tom) 981124 (f)
	+ updated CF_IMAKE_CFLAGS macro for configure script, fixes a problem
	  configuring with --srcdir.
	+ updated config.guess, config.sub from Lynx, adds cases for os390 and
	  clix.
	+ update documentation to indicate that vile has been tested on NT 3.51
	  (patch by Clark Morgan).
	+ correct path separator in default $startup-path for VMS, which would
	  prevent vile from reading vile.rc from a system directory (patch by
	  Clark Morgan).
	+ remove definitions for off_t, making ffsize() return B_COUNT.
	+ modify fileio.c to trace return value from ffaccess(), ffexists(),
	  ffronly(), ffropen() and ffsize().
	+ modify vmsvt.c to support video attributes bold, underline and
	  flash (initiated/tested by Clark Morgan).
	> new version of vileget from J Chris Coppick:
	+ Vileserv now checks for the existence of ~/.vilesock, but not for the
	  file type.  May be more portable.
	+ Vileget has a -w option that causes it to wait until the given
	  file(s) are written by xvile before it exits.  This could be used in
	  conjunction with a mail program for instance.  To use this option,
	  you have to set up a write-hook procedure.  See the doc for vileget.

 (tom) 981114 (e)
	+ corrected TTcursor logic interaction with xterm-mouse so the cursor
	  does not remain invisible after extending a selection.
	+ modify so that xvile can be build with --disable-extensions
	+ correct ifdef for SYS_VMS which was hiding ifdefs for setsid
	+ add sinstall.sh script to fix perl-path when installing scripts such
	  as vileget.
	+ document 'sentences' mode in vile.hlp (patch by Clark Morgan).
	+ correct logic in previous-sentence, which checked for end-of-line
	  state rather than empty-line in one place, causing the function to
	  return the end of the previous line when starting on leading
	  whitespace rather than the actual beginning of the sentence (reported
	  by Clark Morgan).
	+ add "~hidden" macro directive, to suppress 'update()' logic and
	  status check for the current macro line.
	+ add check for zero-sized window to 'update()' function, to guard
	  against attempts to display an incomplete window as a result of
	  a read-hook (reported by Sean Ahern).
	+ add directory browser extension for vile written with the perl interface
	  (from Kuntal M Daftary).
	+ add Vileserv.pm, vileget perl scripts, which give you the ability to
	  send edit requests to a running Vile, like gnuserv does for Emacs
	  (From J Chris Coppick )
	+ correct parameter passed to 'access()' function to use symbols.  The
	  ffaccess() function relied on coincidence between values for
	  FL_EXECABLE, FL_WRITEABLE, FL_READABLE and X_OK, W_OK, R_OK, which
	  did not hold for djgpp.  If all copies of vile.hlp were readonly, it
	  was not "found" (reported by George.Young.gryoung@nt.com, this
	  fixes a similar problem reported by Paul Laub 
	  stating that readonly-on-readonly did not work on DOS).

 (tom) 981112 (d)
	+ correct/simplify handling of string literals in vile-c-filt, which did
	  not treat single quotes and double quotes symmetrically.
	+ correct an error in vile-c-filt which caused the ending quote of
	  a string to be ignored if it appeared in the first column.
	+ add new terminal function TTcursor, to disable cursor display during
	  screen updates and during multimotion.  This makes vile display
	  better on FTP Software's TNVTPlus wyse50 emulation.
	+ restore visual-matches after attribute-from-filter.

 (tom) 981110 (c)
	+ implement a new macro directive, "~local" which saves the current
	  value of $variables and %variables, restoring them at the end of the
	  buffer/macro which is being executed.  This does not (yet) apply to
	  mode values.
	+ rename some functions to make them easier to grep (token to get_token,
	  macarg to mac_tokval, macliteralarg to mac_literalarg).
	+ free old attributes in attribute_from_filter() before adding new ones.
	+ correct an off-by-one error in attribute_from_filter() which caused
	  the second and following attributes to be shifted by one position.
	+ change patmatch to a TBUFF to simplify buffer-overrun checks, fix an
	  off-by-one error in 'savematch()' which caused a core dump.
	+ modify so that Perl interpreter processes END blocks and global
	  destructors when vile exits (patch by Brendan O'Dea).
	+ updated example for C filter to use attribute-from-filter (patch by
	  Clark Morgan).


 (tom) 981106 (b)
	+ add new command attribute-from-filter.
	+ modify allocation of hypercmd value in select.c to use TBUFF's, fixing
	  a use of uninitialized memory.
	+ disable keyboard translation in Motif version of xvile (Gary Ross).
	> patches by Clark Morgan:
	+ correct key translation in ntwinio.c so that pressing '^' (i.e.,
	  shift+6) will no longer cause winvile to flash/beep.
	+ README.PC updated to talk about creation and location of startup
	  file.
	+ win32 versions of editor now support the $title env var (users can
	  now set and display title from a macro).  appropriate documentation
	  updated.
	+ macros/doc and vile.hlp tweaked to show that $title is set using env
	  var syntax.  although, surprisingly, the original example syntax
	  works (i.e.,  set title "string").  i'm surprised because this is yet
	  another undocumented aspect of the macro language--env vars are
	  available via the set command.  i'm not sure I want to document this
	  feature--there's quite a bit to digest in this language as it is,
	  now.
	+ the my_cd_action stored procedure example in vile.hlp has been
	  changed to my-cd-action to prevent users from being surprised that
	  '_' is a command terminator.
	+ makefile.wnt modified so that the ole-automation version of winvile
	  will suck up the new winvile icon (the linker won't accept multiple
	  .RES files).
	+ document environment variables in vile man-page.

 (tom) 981101 (a)
	+ add icon for winvile (V-eyes 'pumpkin').
	+ corrections to hilite.pl and syntax.pl, so it works for C comments
	  (patch by Ryan Murray).
	+ modify tokval() function to eliminate fixed-buffer limits for
	  '@' prompts and '<' buffer-variables (reported by Clark Morgan).
	+ add 'undoable' mode, as a performance convenience for filtering.
	  Note that this purges the undo stack, because it suppresses update
	  of the undo stack while changes may occur to the buffer.  Also,
	  during filtering it prevents vile from retaining the buffer's contents
	  in the kill buffer (prompted by a report by Holger Kummert
	  ).
	+ minor fixes for memory-leaks & test code for that (main.c, fileio.c,
	  modes.c)
	+ modify dfputli and dfputi to output unsigned values to use in $pid
	  conversion.
	+ correct storeproc() so that it detects if tokens follow a macro's
	  name on lines read from source'd file.  These tokens are used for
	  annotating macros in describe-bindings (report by Clark Morgan, patch
	  by Brendan O'Dea).
	> patches by Clark Morgan:
	+ modify so that preceding :! with an argument suppresses the
	  [Press return to continue] prompt for winvile,
	+ update/expand macros.doc
	+ correct a limit-check when returning a buffer variable (eval.c).
	+ convert $pid to unsigned hex rather than decimal on Win32.
	+ make it possible to create vile-perl-api.doc on a win32 host.
	+ add detail to README.PC with respect to building embedded perl.

Changes for vile 8.2 (released Sun Oct 25, 1998)

 (tom) 981025 (c)
	+ check for null top_widget in x_close; other xvile crashes on VMS
	  if I simply run xvile -"V".

 (tom) 981024 (b)
	+ modify glob-expansion to always recognize "~" as a synonym for
	  $HOME if Unix-style passwd interface does not return anything
	  useful (adapted from a patch by Ed Henderson).
	+ rename vile.spec to vile-8.1.spec, change configure option to use
	  Athena widgets so xvile is built with menu support (Radek Liboska).
	  ** This is not an 8.3 filename, but is used only on Linux.
	+ modify to use X11R6 input method and dead key support (patch by
	  Stanislav Meduna ).
	+ correct click-timeout value for xvile, overlooked in 8.1u (reported
	  by Ryan Murray).
	+ minor fixes to menu.c so that xvile builds on OpenVMS 7.2 with DEC C.
	> patches by Clark Morgan (mostly for visvile):
	+ modified the w32 versions of vile so that during clipboard copy
	  operations any character, c, in the following range:
	      c > '~' && c >= val(printing-low) && c <= val(printing-high)
	  is not translated to a hex representation (\xdd).
	  I didn't use any other criteria (e.g., setlocale()) because I
	  received no feedback from the person reporting the bug.
	  Consequently, I don't know what particular locale value I should test
	  (e.g., locale not "C" and not "" ??).  I also explored whether or not
	  the w32 paste operations should similarly not translate data when
	  copying from the clipboard.  For console vile, translation appears to
	  be useful and necessary regardless of the printing-low or
	  printing-high settings.  For winvile, translation is not strictly
	  necessary because when printing-low is >= 128 and printing-high is <=
	  255, winvile properly renders "highbit" ansi characters, such as
	  these:
	      opening quote
	      closing quote
	      ellipsis
	      trademark
	      copyright
	      etc.
	  However, the rendering of each highbit character is so small that the
	  resultant text is extremely difficult to read.  Consequently, I
	  elected to continue my small set of translations (refer to the "map"
	  array in w32cbrd.c for a complete list).
	  (from report by Jukka Keto )
	+ extended/updated README.PC
	+ add explanation of filterregion() portability (spawn.c)
	+ modify in conjunction with visvile, to have the ability to redirect
	  user-specified keystrokes to DevStudio.  For example, from winvile
	  you can start the debugger, step the debugger, start a build, etc.  I
	  think visvile is pretty useful now.  There's one more wrinkle I can
	  envision adding at a later date (see visvile/readme.txt for details),
	  but this feature is not a high priority (to _me_ :-) ).  The
	  documentation of the redirected key feature is included in
	  doc/visvile.doc .
	+ add a new file called visvile/visvile.dsm (a collection of DevStudio
	  macros).
	+ added an environment variable called $cfgopts to the editor.  From
	  the help file:
		$cfgopts  comma-delimited list of "interesting" compiled options
			  (read only).  Currently tracked options include:
		perl    -> editor includes perl interpreter
		oleauto -> editor supports OLE automation.

 (tom) 981008 (a)
	+ add logic to ins_anytime() to prevent recursion or use in minibuffer,
	  e.g., when pressing the insert-key.
	+ correct an ifdef for SYS_VMS in main.c from 8.0s which left other
	  platforms using vfork (reported by Ryan Murray and Billy Little
	   ).

Changes for vile 8.1 (released Fri Oct 02, 1998)

 (tom) 981002 (w)
	+ modify xterm mouse-click handling so that clicking on the left margin
	  when the window is right-shifted always shifts it left.  Before, if
	  a tab fell on the left margin, the effective column was still in the
	  visible part of the window.
	+ back out redundant limit-check in display.c from 8.0u that caused
	  an extra cell to be highlighted when doing full-line selection.

 (tom) 981001 (v)
	+ updated install-rules for perl scripts.
	+ set was_clean flag in all instances of ttclean(), fixing a problem
	  where TTkopen() was not invoked on return from :sh command (reported
	  by Ryan Murray).
	+ strip trailing ^M's from hilite.pl and syntax.pl, add those to the
	  list of Perl scripts in vile.hlp and makefiles (report/patch by
	  Clark Morgan).
	+ pass-through $(OPT) value in recursive-make in makefile.wnt (patch
	  by Clark Morgan).
	+ move logic to reset regionshape out of multimotion, to main.c's loop(),
	  since commands such as "y2qq" would otherwise be yanked
	  in EXACT mode (reported by Ed Henderson).

 (tom) 980930 (u)
	+ modify :ww command to ignore readonly buffers (reported by Chris
	  Sherman).
	+ add sample Redhat RPM spec file "vile.spec" (from Radek Liboska
	  ).
	+ add code to allow user to color Motif pulldown menus, ifdef'd with
	  OPT_MENUS_COLORED, normally off since I prefer the toolkit's color
	  scheme (patch by Mark D Robinson )
	+ modify multimotion to reset regionshape to the original value on
	  return after a selection is made, or to EXACT if the selection is
	  aborted.  This corrects a case where performing quoted fullline
	  motion would cause a succeeding "cw" command to affect the whole line
	  (reported by Yuri Antonik ).
	+ add syntax.pl, hilite.pl, which support syntax highlighting for perl,
	  c and tcl (Kuntal M Daftary).
	+ modify os2vio.c so that when running vile in fullscreen mode, bright
	  colors are used rather than blinking colors.
	+ undo incorrect use of VFCOL mask from my 7.2q change, which caused
	  the pscreen array to record VAREV attributes on shifted-in rows.
	+ minor optimization in vtset function to perform better on very long
	  lines.
	+ modify x11.c to give xvile CDE-like quad-click support.  CDE's
	  dtterms select the entire window (including scrollback) on a quad
	  click.  Increased the timeout slightly to be able to repeatedly
	  select this (patch by Ryan Murray).
	+ documentation updates for visvile (patch by Clark Morgan).
	+ fix a bug that prevented -font option from working on winvile
	  (patch by Clark Morgan).

 (tom) 980925 (t)
	+ correct two errors in AdjustedWidth and AdjustedHeight, making
	  winvile resize properly when maximized, as well as not jumping when
	  resizing after changing fontsize.
	+ keep caret in winvile invisible until ttrow,ttcol point to a legal
	  position, i.e., until initialization is complete.

 (tom) 980922 (s)
	+ correct caret position and size in winvile after changing fontsize.
	+ modify putctext() function to support setv of $word, $identifier,
	  $qidentifier and $pathname.
	+ rename "$wline" to "$wlines", add "$bchars" and "$blines" to return
	  the number of characters and lines in the current buffer,
	  respectively (request by Paul Askounis ).
	+ modify select.c to allow de-attributing attributed regions.  It takes
	  care of the following scenarios now:
	  - Non-overlapping regions were decided earlier on the basis on just
	    line offsets and as a result worked correctly only for FULLLINE
	    regions.  Now they are decided based on line and column offsets and
	    so work correctly for all three region types.
	  - when de-attributing a region, partially or completely overlapping
	    with a previously attributed region, the whole of previous region
	    was de-attributed instead of only the overlapping portion.  Now
	    only the overlapping portion is de-attributed as long as we don't
	    have any RECTANGLE regions.  The fix still does not include
	    RECTANGLE regions.
	  (patch by Kuntal M Daftary)
	+ modify c-filt.c to allow color and text attributes simultaneously
	  (patch by Gary Ross )
	+ add watch.obj to descrip.mms and vmsbuild.com; change ifdef's for
	  VMS consistently to SYS_VMS and comment-out Motif xvile definitions
	  in descrip.mms in favor of X toolkit (reported by Andy Harper).
	  This may make xvile build with DEC C, however Andy reports also that
	  his library lacks XmCreatePullDownWindow, which is not simple to fix.

 (kev) 980919 (r)
	+ buffer.c (zotbuf): Kill any fake windows associated with
	  the buffer we're about to kill.
	+ select.c (hyperspray): Only execute the first found hypertext
	  command.
	+ window.c (delwp): Added support for deleting fake windows.
	  (push_fake_win, pop_fake_win): Removed #if 0'd out code.
	+ x11.c (is_color_cursor):  Added this field back to
	  TextWindowRec; Also added back code to initialize it in
	  x_preparse_args() and test it in flush_line().  Without this
	  code in place, non-color cursors will not blink properly
	  when they are within selections.  [This was removed in
	  vile-7.3w.  We should address the reasons for removing this
	  code in some other way.]

 (tom) 980910 (q)
	+ correct parenthesis for test of F4 change in 8.0l (winvile.c)
	+ modify so that xvile builds with --disable-shell (eval.c).
	+ correct off-by-one in scrollbar position for winvile.
	+ correct computation in AdjustResizing function so that starting a
	  window resizing does not change the initial window size (ntwinio.c).
	+ improved ":!command" for winvile, by creating a transient console
	  which closes when the user presses any key (patch by Clark Morgan).

 (tom) 980908 (p)
	+ modify attribute rendition in win32 drivers (ntconio.c, ntwinio.c)
	  to make highlighting work with colored text by reversing fg/bg.
	+ modify colors in winvile to make lightgray distinct from gray
	  (reported by Clark Morgan).
	+ further modify shell_complete() to continue splitting command lines
	  on blanks, e.g., ^X!command did not do filename completion just like
	  :!command.
	+ minor lint fixes, e.g,. signed/unsigned values (buffer.c, input.c).
	> patches by Clark Morgan (mostly for visvile):
	+ implement logic to return $font value on winvile.
	+ simplified some expressions in vile's comment-formatter to make it
	  format C++ comments.
	+ if visvile disabled, no other dialog options are editable
	+ added more document type checking to avoid occasionally opening such
	  things as dialog box resource scripts.
	+ implemented "CWD set from opened document's path" option
	+ implemented "Write all modified buffers to disk prior to build"
	  option.  This feature doesn't work as well as it could due to a
	  DevStudio (v5) bug.  Refer to ../doc/visvile.doc for further details.
	+ implemented "Build log -> errbuf if build reports errs/warnings"
	  option.

 (tom) 980903 (o)
	+ correct 8.0n change for highlighting, fixing an off-by-one error in
	  visual-matches (reported by Alex Wetmore).
	+ remove SetCursor calls from ntwinio.c, since they obstruct WinNT from
	  showing the resize-cursor, as well as causing the cursor to flicker
	  around the window border.
	> patches by Clark Morgan:
	+ add the ability to set winvile's font from the command line or via
	  the environment variable "$font" (a la xvile).
	+ modify OLE automation registration to accept a font specification,
	  making it possible to configure both the font and screen geometry of
	  future instances of winvile OLE automation servers.
	+ remove some compiler warnings in ntwinio.c and correct the OLE
	  registration logic for the "-geometry" switch (file w32reg.c).

 (tom) 980902 (n)
	+ modify updattrs function so that video attributes applied to tabs and
	  other nonprinting characters will paint all of the cells used to
	  display those characters (request by Richar A Ward).
	+ modify win32 drivers (ntconio.c and ntwinio.c) to make visual-matches
	  override syntax highlighting (reported by Clark Morgan).
	+ correct unstacking behavior for next-tags as per original request.
	+ modify shell_complete() function, which is used in both normal
	  filename completion, and in completing shell commands so that for at
	  least the former case it will handle filenames with embedded blanks
	  (analysis by Rick Sladkey ).

 (tom) 980901 (m)
	+ add a check to keep initial TTkopen from trashing the command-line
	  help or version (termio.c).
	+ implement token-type for macro label linenumber, e.g., tokens
	  beginning with an '*'.
	+ modify behavior of next-tags so that continued matches do not push
	  the tags stack, but remain at the same level as the initial match
	  (requested by Ed Henderson).
	+ correct typo in change to imdying for the non-Unix case (patch by
	  Clark Morgan).

 (tom) 980831 (l)
	+ modify dbgwrite() message to show how to get out of the loop, since
	  more than one person has thought vile is hung when it is awaiting
	  a ^G after reporting a keyboard problem.
	+ modify imdying() function to search for a temp-directory, preferring
	  $TMPDIR, /var/tmp and /usr/tmp over /tmp.  Lengthened cmd buffer in
	  that function since it was too small.  (reported by Duncan Barclay
	  ).
	+ correct logic for dragging scrollbar thumb in winvile which also
	  moved cursor position unnecessarily (reported by Ed Henderson).
	+ correct handling of Alt-F4 in winvile, which did not close the window
	  because it was hidden by logic to support Win32 key modifiers
	  (reported by Clark Morgan).
	+ correct rendering of color 8 in winvile, which was black rather than
	  gray (reported by Clark Morgan).
	+ add gui_isprint() function to x11.c to test for characters which are
	  nonprinting in xvile, override printing-low and printing-high modes
	  to keep, for example, \80 to \A0 in printable form (main.c, x11.c)
	+ added a TTkopen call to ttunclean to match the TTkclose in ttclean,
	  fixes a problem where arrow keys did not work in the termcap version
	  after a :sh command (reported by Ryan Murray).
	+ modify configure script tests for termcap/terminfo libraries to allow
	  $LIBS to have the corresponding libraries (for Ryan Murray, who wants
	  to override the check for -lcurses).
	+ correct handling of configure --without-perl, which still tried to
	  use perl (reported by Ryan Murray).
	+ add autoconf macro CF_PROG_PERL, based on macro from Brendan O'Dea.
	+ remove x_quit function, using normal imdying function to handle
	  SIGHUP and SIGTERM for xvile (reported by Shawn Halpenny).
	> patches by Clark Morgan:
	+ remove spurious rumor in doc/visvile.doc
	+ winvile shows file name in title bar
	+ winvile ole automation server now catches bogus command line
	  arguments before attempting to process -Or switch.

 (tom) 980827 (k)
	+ add gui_version() function for winvile, to handle -V option (reported
	  by Clark Morgan).
	+ set flags for bminip and wminip so that all control characters except
	  for newline are echoed as in list-mode (display.c, window.c).
	+ correct rendering of termcap color while highlight-selection is
	  active (tcap.c)
	+ corrected logic of '<' register so it captures both calls on TTgetc
	  in map.c, otherwise it missed the 'M' in xterm mouse clicks.
	+ revise xterm mouse code to support movement of modelines by
	  "dragging" button 1, and selection/extension with buttons 1 and 3.
	  Integrated with multimotion() function (select.c, tcap.c).
	+ fix a couple of memory leaks
	> patches by Clark Morgan:
	+ adds _some_ winvile integration to DevStudio Version 5.  In
	  particular, this patch creates a component called visvile.dll, which
	  is a DevStudio-compatible add-in that invokes an OLE-compatible
	  version of winvile when editing/browsing text/source documents.
	  Visvile.dll, a work in progress, is heavily based on visvim.dll.
	  Full documentation is included in the new file doc/visvile.doc.
	+ add InsertMode and IsMinimized functions for OLE interface.
	+ remove unneeded assert's (winreg.c).
	+ always set force-console mode for Win95 (main.c).
	+ add command-line options to winvile to support OLE (ntwinio.c).

 (tom) 980816 (j)

	+ implement a simple usage/popup for winvile.
	+ correct a problem with cursor-droppings in winvile when the mouse
	  is clicked on the modeline.
	+ implement scrollbars for winvile (ntwinio.c)
	> patches by Clark Morgan:
	+ changes to allow winvile to be built as an OLE automation server.
	  Included with this patch are several new files, including one called
	  doc/oleauto.doc, which describes the build process and the relevant
	  server options/features.

 (tom) 980727 (i)
	+ modify makefile.djg to use -f option of rm, to work with djgpp 2.x
	+ updated dependencies in makefile.wnt (patch by Clark Morgan).
	+ restore old functionality for win32 ^X-!  (see 8.0c), but make a
	  special check for its use in getting directory listings to avoid
	  lockup with Thompson Toolkit Shell (patch by Clark Morgan).
	+ change "%u" in lsprintf call in w32cbrd.c to "%d", fixes _snprintf
	  change in 8.0h (reported by Clark Morgan).

 (tom) 980726 (h)
	+ updated config.guess, config.sub based on automake 1.3.
	+ combine some logic in file.c with new function strip_if_dosmode().
	+ correct typo in perl.xs from 8.0g
	+ change win32 _snprintf calls to lsprintf, to build with Borland C++.
	+ modify makefile.wnt to build with Perl 5.004, which is missing a
	  global for 'rs' on win32 (patch by Clark Morgan, analysis by Kevin).
	+ modified Clark's change so that the Win32-specific keycodes are returned
	  only when combined with key-modifiers (shift/alt/ctrl) that are specific
	  to Win32.
	+ mods to cause apropos and show-bindings to display proper binding
	  strings for the Win32 clipboard-related features.  Also, modified
	  ntconio to support noticed that winvile allows the user to sweep out
	  a rectangular region when a control key is pressed during mouse-based
	  text selection as in winvile, and documented in vile.hlp (patch by
	  Clark Morgan).
	+ correct message in win32 clipboard paste reporting the number of
	  bytes transferred to the clipboard (patch by Clark Morgan).
	+ updated makefile.blc, modified ifdefs to build with with Borland C++
	  5.02 (patch by Ryan Murray ).
	+ rename update_scrollbar to gui_update_scrollbar as part of ongoing
	  work on scrollbars for winvile.
	+ move autoconf tests for OpenLook and Motif libraries into aclocal.m4,
	  for reuse in other applications (e.g., xterm).

 (kev) 980725 (g)
	+ perl.xs (incgv, rs, ofslen, ofs, ors, orslen): Added PL_ prefix
	  to these for perl5.005.  Defined these in terms of the old
	  non-prefixed names for older versions of perl5.

 (tom) 980717 (f)
	+ corrected return-value of do_a_submode(), which was hiding a problem
	  in the call on new_regexval() from set_mode_value().
	+ correction to fences-begin and fences-end logic, to account for the
	  size of the matched text when doing a reverse sweep.  Only one
	  character from fences-end was selected, so that deleting a C-style
	  comment would leave a '/' (reported by Clark Morgan).
	+ add a couple of null-pointer checks in modes.c, to fix a case
	  when 'comments' submode is not initialized.
	+ implement previous-buffer command (requested by Quang Ngo
	  ).
	+ modify doindent() to adjust dot to point to the same text on exit as
	  it did on entry.  This fixes an instance of autoindent in cmode where
	  inserting a right-brace character at the wrapmargin caused the brace
	  to be inserted _before_ the wrapped word (reported by Michel Oey
	  ).
	+ corrected missing brackets in configure.in that caused --with-scr=xm
	  to be misinterpreted.
	+ modify win32 clipboard support to enable the copying of an arbitrary
	  region or named register to the windows clipboard (patch by Clark
	  Morgan).

 (tom) 980710 (e)
	+ correct recompilation of [Error Expressions], by adding a check if
	  the buffer is marked as changed, or if the number of lines in it
	  has changed.  If [Error Expressions] was popped up to view its
	  contents, that worked, but otherwise (e.g., in .vilerc), it did not
	  trigger the recompile (reported by Brian Moore).
	+ change winvile -geometry parameter to COLSxROWS, for consistency with
	  X Window applications (e.g., xterm), and documented in vile.hlp.
	+ correct parsing of line-specification when a leading ',' is used,
	  e.g., ":,$d" (reported by hymie! ).
	+ documentation updates (patch by Clark Morgan).
	+ modify logic in tags.c so that tags completion works when some of the
	  tags files are missing (patch by Clark Morgan).

 (tom) 980708 (d)
	+ correct offset for ending null in kbd_string(), which was beyond
	  buffer limit - bug from 7.3f (patch by Chris Sherman
	  ).
	+ implement -geometry command-line option for winvile, and corresponding
	  modifiable $pagelen and $pagewid values.
	+ modify configure script to accept --with-screen=xaw and
	  --with-screen=xm, i.e., lowercase screen values (reported by Ryan
	  Murray ).
	+ modify winvile to read stdin when there's data available, e.g.,
	  dir|winvile.  Tested on Win95 _and_ NT (patch by Clark Morgan).

 (tom) 980703 (c)
	+ remove spurious 'void' in perl.xs which caused items to be miscounted
	  (report by Kuntal M Daftary, patch by Kevin Buettner).
	+ shorten identifiers to no more than 31 characters (reported by
	  Graeme Miller).
	> patches by Clark Morgan:
	+ fix for a problem reported by Paul Fox:  when a dos box has scroll
	  bars (window size smaller than buffer size), then :! displays
	  its output in a switched screen context that the user can't examine.
	  This applies to console vile only (winvile has much worse problems in
	  the same scenario :-).
	+ changes to make ^X-!  use the same code path as filter-region and
	  read-pipe when the host is win32-based.
	+ implement paste-from-clipboard for win32, bound to Shift+Insert
	+ add a new documentation file (doc/w32modes.doc) that describes the
	  optimum settings for win32 modes when the host OS is not NT4.

 (tom) 980702 (b)
	+ change highlighting rule in vile-c-filt to highlight only the
	  "#" and keyword on preprocessor lines (patch by Paul Fox).
	+ dynamically allocate pm_buffer array in menu.c, eliminating limit on
	  number of menu items (reported by William Yuan
	  ).
	+ new configure macro CF_CC_INIT_UNIONS checks for compilers that
	  cannot initialize a union, e.g, a K&R compiler using unproto.
	  Ifdef'd union in CMDFUNC to work in that case.
	+ correct spelling of EXTRA_LOAD_FLAGS in CF_IMAKE_CFLAGS configure
	  macro.
	+ set VIEWOK flag on stored-procedure buffers, otherwise they cannot
	  be used in buffers set "view" (reported by Larry Gensch).
	+ rename character-type names to use "vl" prefix, to avoid conflict
	  with ctype.h names on Digital Unix 5.0 (patch by Larry Gensch).
	+ note that $progname may be "winvile" (patch by Clark Morgan).
	+ modify configure.in and makefile.in so that $(datadir)/perl is not
	  created unless vile is configured --with-perl (patch by Brendan
	  O'Dea).
	+ require perl 5.004 since the XS interface is dependent upon tied file
	  handles, which are not completely implemented in 5.003 (request by
	  Brendan O'Dea).

 (kev) 980606 (a)
	+ perl.xs (svrs): No longer a global static variable.
	  (perl_init): Don't initialize svrs here anymore.  Also, stifle
	  compiler warning.
	  (READLINE): Declare and initialize svrs here, but only for
	  platforms on which it's broken.
	  (perl_default_region, do_perl_cmd, set_region): Adjust r_size
	  field in region returned by getregion to account for buffers
	  which don't have a trailing newline.
	  (newVBrv): call gv_IOadd() in order to be able to use $. with
	  the filehandles.
	  (newVBrv, do_perl_cmd, set_region): Initialize $. .
	  (READLINE): increment (or advance) $. as appropriate.

	  [Brendan O'Dea sent me patches for much of the above.]

This change log started on Monday Jun 8, 1998.
vile-9.8v/COPYING000066400000000000000000000442161415556424100135700ustar00rootroot00000000000000previous versions of vile were limited to non-commercial use due to 
their inclusion of code from versions of MicroEMACS which were 
restricted in that way.  in the current version of vile, every attempt 
has been made to ensure that this later code has been removed or 
rewritten, returning vile's original basis to public domain status.  
the current version of vile, however, is _not_ in the public domain -- 
it is released under the provisions of the specific version of
the GNU General Public License, below.

-------------------------------------------------
		    GNU GENERAL PUBLIC LICENSE
		       Version 2, June 1991

 Copyright (C) 1989, 1991 Free Software Foundation, Inc.
                       51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 Everyone is permitted to copy and distribute verbatim copies
 of this license document, but changing it is not allowed.

			    Preamble

  The licenses for most software are designed to take away your
freedom to share and change it.  By contrast, the GNU General Public
License is intended to guarantee your freedom to share and change free
software--to make sure the software is free for all its users.  This
General Public License applies to most of the Free Software
Foundation's software and to any other program whose authors commit to
using it.  (Some other Free Software Foundation software is covered by
the GNU Library General Public License instead.)  You can apply it to
your programs, too.

  When we speak of free software, we are referring to freedom, not
price.  Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
this service if you wish), that you receive source code or can get it
if you want it, that you can change the software or use pieces of it
in new free programs; and that you know you can do these things.

  To protect your rights, we need to make restrictions that forbid
anyone to deny you these rights or to ask you to surrender the rights.
These restrictions translate to certain responsibilities for you if you
distribute copies of the software, or if you modify it.

  For example, if you distribute copies of such a program, whether
gratis or for a fee, you must give the recipients all the rights that
you have.  You must make sure that they, too, receive or can get the
source code.  And you must show them these terms so they know their
rights.

  We protect your rights with two steps: (1) copyright the software, and
(2) offer you this license which gives you legal permission to copy,
distribute and/or modify the software.

  Also, for each author's protection and ours, we want to make certain
that everyone understands that there is no warranty for this free
software.  If the software is modified by someone else and passed on, we
want its recipients to know that what they have is not the original, so
that any problems introduced by others will not reflect on the original
authors' reputations.

  Finally, any free program is threatened constantly by software
patents.  We wish to avoid the danger that redistributors of a free
program will individually obtain patent licenses, in effect making the
program proprietary.  To prevent this, we have made it clear that any
patent must be licensed for everyone's free use or not licensed at all.

  The precise terms and conditions for copying, distribution and
modification follow.

		    GNU GENERAL PUBLIC LICENSE
   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION

  0. This License applies to any program or other work which contains
a notice placed by the copyright holder saying it may be distributed
under the terms of this General Public License.  The "Program", below,
refers to any such program or work, and a "work based on the Program"
means either the Program or any derivative work under copyright law:
that is to say, a work containing the Program or a portion of it,
either verbatim or with modifications and/or translated into another
language.  (Hereinafter, translation is included without limitation in
the term "modification".)  Each licensee is addressed as "you".

Activities other than copying, distribution and modification are not
covered by this License; they are outside its scope.  The act of
running the Program is not restricted, and the output from the Program
is covered only if its contents constitute a work based on the
Program (independent of having been made by running the Program).
Whether that is true depends on what the Program does.

  1. You may copy and distribute verbatim copies of the Program's
source code as you receive it, in any medium, provided that you
conspicuously and appropriately publish on each copy an appropriate
copyright notice and disclaimer of warranty; keep intact all the
notices that refer to this License and to the absence of any warranty;
and give any other recipients of the Program a copy of this License
along with the Program.

You may charge a fee for the physical act of transferring a copy, and
you may at your option offer warranty protection in exchange for a fee.

  2. You may modify your copy or copies of the Program or any portion
of it, thus forming a work based on the Program, and copy and
distribute such modifications or work under the terms of Section 1
above, provided that you also meet all of these conditions:

    a) You must cause the modified files to carry prominent notices
    stating that you changed the files and the date of any change.

    b) You must cause any work that you distribute or publish, that in
    whole or in part contains or is derived from the Program or any
    part thereof, to be licensed as a whole at no charge to all third
    parties under the terms of this License.

    c) If the modified program normally reads commands interactively
    when run, you must cause it, when started running for such
    interactive use in the most ordinary way, to print or display an
    announcement including an appropriate copyright notice and a
    notice that there is no warranty (or else, saying that you provide
    a warranty) and that users may redistribute the program under
    these conditions, and telling the user how to view a copy of this
    License.  (Exception: if the Program itself is interactive but
    does not normally print such an announcement, your work based on
    the Program is not required to print an announcement.)

These requirements apply to the modified work as a whole.  If
identifiable sections of that work are not derived from the Program,
and can be reasonably considered independent and separate works in
themselves, then this License, and its terms, do not apply to those
sections when you distribute them as separate works.  But when you
distribute the same sections as part of a whole which is a work based
on the Program, the distribution of the whole must be on the terms of
this License, whose permissions for other licensees extend to the
entire whole, and thus to each and every part regardless of who wrote it.

Thus, it is not the intent of this section to claim rights or contest
your rights to work written entirely by you; rather, the intent is to
exercise the right to control the distribution of derivative or
collective works based on the Program.

In addition, mere aggregation of another work not based on the Program
with the Program (or with a work based on the Program) on a volume of
a storage or distribution medium does not bring the other work under
the scope of this License.

  3. You may copy and distribute the Program (or a work based on it,
under Section 2) in object code or executable form under the terms of
Sections 1 and 2 above provided that you also do one of the following:

    a) Accompany it with the complete corresponding machine-readable
    source code, which must be distributed under the terms of Sections
    1 and 2 above on a medium customarily used for software interchange; or,

    b) Accompany it with a written offer, valid for at least three
    years, to give any third party, for a charge no more than your
    cost of physically performing source distribution, a complete
    machine-readable copy of the corresponding source code, to be
    distributed under the terms of Sections 1 and 2 above on a medium
    customarily used for software interchange; or,

    c) Accompany it with the information you received as to the offer
    to distribute corresponding source code.  (This alternative is
    allowed only for noncommercial distribution and only if you
    received the program in object code or executable form with such
    an offer, in accord with Subsection b above.)

The source code for a work means the preferred form of the work for
making modifications to it.  For an executable work, complete source
code means all the source code for all modules it contains, plus any
associated interface definition files, plus the scripts used to
control compilation and installation of the executable.  However, as a
special exception, the source code distributed need not include
anything that is normally distributed (in either source or binary
form) with the major components (compiler, kernel, and so on) of the
operating system on which the executable runs, unless that component
itself accompanies the executable.

If distribution of executable or object code is made by offering
access to copy from a designated place, then offering equivalent
access to copy the source code from the same place counts as
distribution of the source code, even though third parties are not
compelled to copy the source along with the object code.

  4. You may not copy, modify, sublicense, or distribute the Program
except as expressly provided under this License.  Any attempt
otherwise to copy, modify, sublicense or distribute the Program is
void, and will automatically terminate your rights under this License.
However, parties who have received copies, or rights, from you under
this License will not have their licenses terminated so long as such
parties remain in full compliance.

  5. You are not required to accept this License, since you have not
signed it.  However, nothing else grants you permission to modify or
distribute the Program or its derivative works.  These actions are
prohibited by law if you do not accept this License.  Therefore, by
modifying or distributing the Program (or any work based on the
Program), you indicate your acceptance of this License to do so, and
all its terms and conditions for copying, distributing or modifying
the Program or works based on it.

  6. Each time you redistribute the Program (or any work based on the
Program), the recipient automatically receives a license from the
original licensor to copy, distribute or modify the Program subject to
these terms and conditions.  You may not impose any further
restrictions on the recipients' exercise of the rights granted herein.
You are not responsible for enforcing compliance by third parties to
this License.

  7. If, as a consequence of a court judgment or allegation of patent
infringement or for any other reason (not limited to patent issues),
conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License.  If you cannot
distribute so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you
may not distribute the Program at all.  For example, if a patent
license would not permit royalty-free redistribution of the Program by
all those who receive copies directly or indirectly through you, then
the only way you could satisfy both it and this License would be to
refrain entirely from distribution of the Program.

If any portion of this section is held invalid or unenforceable under
any particular circumstance, the balance of the section is intended to
apply and the section as a whole is intended to apply in other
circumstances.

It is not the purpose of this section to induce you to infringe any
patents or other property right claims or to contest validity of any
such claims; this section has the sole purpose of protecting the
integrity of the free software distribution system, which is
implemented by public license practices.  Many people have made
generous contributions to the wide range of software distributed
through that system in reliance on consistent application of that
system; it is up to the author/donor to decide if he or she is willing
to distribute software through any other system and a licensee cannot
impose that choice.

This section is intended to make thoroughly clear what is believed to
be a consequence of the rest of this License.

  8. If the distribution and/or use of the Program is restricted in
certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Program under this License
may add an explicit geographical distribution limitation excluding
those countries, so that distribution is permitted only in or among
countries not thus excluded.  In such case, this License incorporates
the limitation as if written in the body of this License.

  9. The Free Software Foundation may publish revised and/or new versions
of the General Public License from time to time.  Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.

Each version is given a distinguishing version number.  If the Program
specifies a version number of this License which applies to it and "any
later version", you have the option of following the terms and conditions
either of that version or of any later version published by the Free
Software Foundation.  If the Program does not specify a version number of
this License, you may choose any version ever published by the Free Software
Foundation.

  10. If you wish to incorporate parts of the Program into other free
programs whose distribution conditions are different, write to the author
to ask for permission.  For software which is copyrighted by the Free
Software Foundation, write to the Free Software Foundation; we sometimes
make exceptions for this.  Our decision will be guided by the two goals
of preserving the free status of all derivatives of our free software and
of promoting the sharing and reuse of software generally.

			    NO WARRANTY

  11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW.  EXCEPT WHEN
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.  THE ENTIRE RISK AS
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU.  SHOULD THE
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
REPAIR OR CORRECTION.

  12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
POSSIBILITY OF SUCH DAMAGES.

		     END OF TERMS AND CONDITIONS

	    How to Apply These Terms to Your New Programs

  If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.

  To do so, attach the following notices to the program.  It is safest
to attach them to the start of each source file to most effectively
convey the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.

    
    Copyright (C) 19yy  

    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA


Also add information on how to contact you by electronic and paper mail.

If the program is interactive, make it output a short notice like this
when it starts in an interactive mode:

    Gnomovision version 69, Copyright (C) 19yy name of author
    Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
    This is free software, and you are welcome to redistribute it
    under certain conditions; type `show c' for details.

The hypothetical commands `show w' and `show c' should show the appropriate
parts of the General Public License.  Of course, the commands you use may
be called something other than `show w' and `show c'; they could even be
mouse-clicks or menu items--whatever suits your program.

You should also get your employer (if you work as a programmer) or your
school, if any, to sign a "copyright disclaimer" for the program, if
necessary.  Here is a sample; alter the names:

  Yoyodyne, Inc., hereby disclaims all copyright interest in the program
  `Gnomovision' (which makes passes at compilers) written by James Hacker.

  , 1 April 1989
  Ty Coon, President of Vice

This General Public License does not permit incorporating your program into
proprietary programs.  If your program is a subroutine library, you may
consider it more useful to permit linking proprietary applications with the
library.  If this is what you want to do, use the GNU Library General
Public License instead of this License.
vile-9.8v/INSTALL000066400000000000000000000143121415556424100135600ustar00rootroot00000000000000
This is a generic document provided with most packages which use
the GNU autoconf/configure system to achieve system portability.
For vile-specific build/installation information, see doc/config.doc.

$Id: INSTALL,v 1.7 1998/05/22 00:55:14 tom Exp $
--------------------------------

   This is a generic INSTALL file for utilities distributions.
If this package does not come with, e.g., installable documentation or
data files, please ignore the references to them below.

   The `configure' shell script attempts to guess correct values for
various system-dependent variables used during compilation, and
creates the makefile(s) (one in each subdirectory of the source
directory).  In some packages it creates a C header file containing
system-dependent definitions.  It also creates a file `config.status'
that you can run in the future to recreate the current configuration.

To compile this package:

1.  Configure the package for your system.

   Normally, you just `cd' to the directory containing the package's
source code and type `./configure'.  If you're using `csh' on an old
version of System V, you might need to type `sh configure' instead to
prevent `csh' from trying to execute `configure' itself.

   Running `configure' takes awhile.  While it is running, it
prints some messages that tell what it is doing.  If you don't want to
see any messages, run `configure' with its standard output redirected
to `/dev/null'; for example, `./configure >/dev/null'.

   To compile the package in a different directory from the one
containing the source code, you must use a version of `make' that
supports the `VPATH' variable, such as GNU `make'.  `cd' to the
directory where you want the object files and executables to go and run
the `configure' script.  `configure' automatically checks for the
source code in the directory that `configure' is in and in `..'.  If
for some reason `configure' is not in the source code directory that
you are configuring, then it will report that it can't find the source
code.  In that case, run `configure' with the option `--srcdir=DIR',
where DIR is the directory that contains the source code.

   By default, `make install' will install the package's files in
`/usr/local/bin', `/usr/local/man', etc.  You can specify an
installation prefix other than `/usr/local' by giving `configure' the
option `--prefix=PATH'.  Alternately, you can do so by consistently
giving a value for the `prefix' variable when you run `make', e.g.,
     make prefix=/usr/gnu
     make prefix=/usr/gnu install

   You can specify separate installation prefixes for
architecture-specific files and architecture-independent files.  If you
give `configure' the option `--exec-prefix=PATH' or set the `make'
variable `exec_prefix' to PATH, the package will use PATH as the prefix
for installing programs and libraries.  Data files and documentation
will still use the regular prefix.  Normally, all files are installed
using the same prefix.

   Some packages pay attention to `--with-PACKAGE' options to
`configure', where PACKAGE is something like `gnu-as' or `x' (for the
X Window System).  They may also pay attention to `--enable-FEATURE'
options, where FEATURE indicates an optional part of the package.  The
README should mention any `--with-' and `--enable-' options that the
package recognizes.

   `configure' also recognizes the following options:

`--help'
     Print a summary of the options to `configure', and exit.

`--quiet'
`--silent'
     Do not print messages saying which checks are being made.

`--verbose'
     Print the results of the checks.

`--version'
     Print the version of Autoconf used to generate the `configure'
     script, and exit.

`--x-includes=DIR'
     X include files are in DIR.

`--x-libraries=DIR'
     X library files are in DIR.

   `configure' also accepts and ignores some other options.

   On systems that require unusual options for compilation or linking
that the package's `configure' script does not know about, you can give
`configure' initial values for variables by setting them in the
environment.  In Bourne-compatible shells, you can do that on the
command line like this:

     CC='gcc -traditional' LIBS=-lposix ./configure

On systems that have the `env' program, you can do it like this:

     env CC='gcc -traditional' LIBS=-lposix ./configure

   Here are the `make' variables that you might want to override with
environment variables when running `configure'.

   For these variables, any value given in the environment overrides the
value that `configure' would choose:

 - Variable: CC
     C compiler program.  The default is `cc'.

 - Variable: INSTALL
     Program to use to install files.  The default is `install' if you
     have it, `cp' otherwise.

   For these variables, any value given in the environment is added to
the value that `configure' chooses:

 - Variable: DEFS
     Configuration options, in the form `-Dfoo -Dbar...'.  Do not use
     this variable in packages that create a configuration header file.

 - Variable: LIBS
     Libraries to link with, in the form `-lfoo -lbar...'.

   If you need to do unusual things to compile the package, we encourage
you to figure out how `configure' could check whether to do them, and
mail diffs or instructions to the address given in the README so we
can include them in the next release.

2.  Type `make' to compile the package.  If you want, you can override
the `make' variables CFLAGS and LDFLAGS like this:

	make CFLAGS=-O2 LDFLAGS=-s

3.  If the package comes with self-tests and you want to run them,
type `make check'.  If you're not sure whether there are any, try it;
if `make' responds with something like
	make: *** No way to make target `check'.  Stop.
then the package does not come with self-tests.

4.  Type `make install' to install programs, data files, and
documentation.

5.  You can remove the program binaries and object files from the
source directory by typing `make clean'.  To also remove the
makefile(s), the header file containing system-dependent definitions
(if the package uses one), and `config.status' (all the files that
`configure' created), type `make distclean'.

   The file `configure.in' is used to create `configure' by a program
called `autoconf'.  You only need it if you want to regenerate
`configure' using a newer version of `autoconf'.
vile-9.8v/MANIFEST000066400000000000000000001056441415556424100136710ustar00rootroot00000000000000MANIFEST for vile, version v9_8v
--------------------------------------------------------------------------------
MANIFEST                        this file
AUTHORS                         list of authors, with nicknames in CHANGES
CHANGES                         Change-log for VILE
CHANGES.R3                      Vile 3.0 change-log
CHANGES.R4                      Vile 4.0 change-log
CHANGES.R5                      Vile 5.0 change log
CHANGES.R6                      Vile 6.0 change-log
CHANGES.R7                      Vile 7.0 change-log
CHANGES.R8                      Vile 8.0 change-log
COPYING                         GPL copyright (for 'configure')
INSTALL                         installation instructions for VILE
README                          overview of VILE (read first)
README.PC                       instructions for PC's (MS-DOS, etc.)
README.VMS                      instructions for VAX's (OpenVMS)
aclocal.m4                      VILE-specific autoconf macros
ansi.c                          ANSI terminal driver
api.c                           nvi-like api to perl and tcl
api.h                           interface of api.c
basic.c                         basic cursor-movement
bind.c                          key-bindings & low-level command-completion
blist.c                         binary-searches for pre-sorted arrays
blist.h                         interface of blist.c
borland.c                       BORLAND terminal driver
btree.c                         balanced-binary (AVL) tree functions
btree.h                         interface of btree.c
buffer.c                        buffer-management
buglist                         bug-list
builtflt.c                      interface from vile to built-in filters
charsets.c                      multibyte-character set support
chgdfunc.h                      prototypes for mode-functions with side-effects
cmdtbl                          used by 'mktbls' to generate VILE's command-tables
config.guess                    guess configuration
config.sub                      substitute configuration
config_h.in                     template for config.h
configure                       Configuration script for UNIX
configure.in                    used by 'autoconf' to generate 'configure'
csrch.c                         current-line character-scanning commands
curses.c                        terminal driver using curses
descrip.mms                     VAX/VMS MMS build-script
df-install.in                   desktop-file installer, adapted from xterm
dirstuff.h                      interfaces for UNIX-like directory functions
display.c                       message & screen formatting & display
djhandl.c                       CTL/C & interrupt handling for DJGCC
dumbterm.c                      DUMB terminal driver
edef.h                          global variable definitions
eightbit.c                      character translation for "8bit" mode
encrypt.c                       Jochen Obalek's unix-style crypt function
estruct.h                       master include/struct definitions
eval.c                          expression-evaluation
exec.c                          command (':', macros) execution
externs.c                       external data (via edef.h)
fences.c                        functions for parenthesis/ifdef balancing
file.c                          read/write/lookup disk files (high-level)
filec.c                         filename-completion functions
fileio.c                        low-level file I/O functions
finderr.c                       error-finder
glob.c                          globbing (wildcard & environment-variable substitution)
globals.c                       ed/vi/ex style global commands
gnreight.h                      generated data for single-byte encodings
gppconio.c                      patched console I/O support for DJGCC
history.c                       command-history
input.c                         various input-routines
insert.c                        functions for character-insertion
install-sh                      install-script, needed for configure
isearch.c                       incremental-search commands
itbuff.c                        support functions for wide-character strings
lckfiles.c                      locked-files support
line.c                          line-management functions
main.c                          main program of VILE
makeargv.c                      parse string to argc/argv[]
makeargv.h                      interface of makeargv.c
makefile.blc                    makefile for Win32 with Borland C++
makefile.djg                    makefile for DJGCC
makefile.icc                    makefile for C Set++ 2.x (OS/2)
makefile.in                     used by 'configure' to generate a makefile
makefile.wnt                    makefile for Win32 with Microsoft Visual C++
makeflag.wnt                    replacement for win32.mak, for newer Visual Studio C++
map.c                           map and map! commands
menu.c                          menu-support for xvile
mkprlenv.wnt                    vile-7.4h
mktbls.c                        utility for constructing VILE's command & mode tables
modes.c                         mode-command support
modetbl                         used by 'mktbls' to generate mode tables
msgs.c                          pop-up message support
npopen.c                        pipe-command support
ntconio.c                       Win32 console terminal driver
ntwinio.c                       GUI terminal driver for WinNT
nullterm.c                      null device-driver
oneliner.c                      commands that operate upon single lines
opers.c                         operator-commands (that use motions)
os2keys.h                       function-key definitions for OS/2
os2pipe.c                       OS/2 pipe support
os2vio.c                        OS/2 video terminal driver
patchlev.h                      patch-level
path.c                          functions that manipulate pathnames
perl.xs                         Perl/C interface wrapper
plink.sh                        script to trim unneeded libraries from a link-command.
plugin.c                        command interface to plugins
plugin.h                        interface of plugin.c
proto.h                         function prototypes
pscreen.h                       interface for PSCREEN struct
ptypemap                        perl-interface type map
random.c                        miscellaneous functions
regexp.c                        regular expression functions
region.c                        region-manipulation
revlist                         revision-list for VILE
search.c                        functions for search-commands
select.c                        selection-handling functions
spawn.c                         functions for spawning subprocesses
statevar.c                      functions to set/get state-variables
tags.c                          support for vi-style "tags"
tbuff.c                         temporary-buffer management functions
tcap.c                          TERMCAP terminal driver
tcap.h                          interface of tcap.c
termio.c                        low-level terminal I/O support
test_io.c                       I/O stub for testing linkage requirements
trace.c                         development: trace to logfile
trace.h                         development: trace to logfile
ucrypt.c                        interface to Unix crypt(1)
undo.c                          support for "undo"
version.c                       version & usage messages
version.sh                      print version for current sources
vile.1                          man-page for VILE
vile.hlp                        help-file
vile.wmconfig                   windowmaker config file for vile
vl_alloc.h                      malloc-macros for vile
vl_crypt.h                      interface to Unix crypt(1)
vl_ctype.c                      vile's ctype functions
vl_ctype.h                      character-set tests for vile
vl_regex.h                      interface for vile's regexp.c
vl_stdio.h                      customized stdio.h definitions for vile.
vms2unix.c                      VMS/UNIX compatibility support functions
vmsbuild.com                    VAX/VMS DCL build script
vmspipe.c                       pipe-filter support for VMS
vmsvt.c                         VMS terminal driver
w32cbrd.c                       Win32 clipboard support
w32cmd.c                        win32 command-specific code
w32info.rc                      win32 version info
w32misc.c                       vile-7.4h
w32ole.cpp                      interface for Winvile OLE
w32ole.h                        interface of w32ole.cpp
w32ole.rc                       resource-control for ole configuration
w32oo.cpp                       various C++ support functions for winvile
w32pipe.c                       Win32 native pipe support
w32reg.c                        Winvile OLE registration code
w32reg.h                        interface of w32reg
w32vile.h                       includes , but adds pragmas to stifle the -W4 warnings.
watch.c                         watch file-descriptors & timers
wcwidth.c                       wcwidth, from xterm
wcwidth.h                       wcwidth, from xterm
window.c                        window-management functions
winvile.h                       definitions for winvile
winvile.odl                     interface description for Winvile OLE
winvile.rc                      resource definitions for winvile
word.c                          commands that operate upon words or paragraphs
wordmov.c                       cursor-movement commands (e.g., word, spaces)
wvwrap.cpp                      wrapper for winvile, e.g., from NT Explorer
x11.c                           X11 (Xt, Motif or Openlook) terminal driver
x11menu.c                       X11-specific part of menu support
x11plain.c                      draw text for xvile using X11, no fontsets
x11vile.h                       common definitions for xvile modules
xftplain.c                      draw text for xvile, using Xft
xshell.sh                       wrapper/sample script for xvile
xterm.c                         xterm-specific I/O driver support
xtermkeys.h                     generate bindings for xterm key-modifiers
xvile.wmconfig                  windowmaker config file for xvile
doc                             subdirectory
doc/Vileserv.doc                overview of Vileserv and vileget scripts
doc/Vileserv.html               overview of Vileserv and vileget scripts
doc/config.doc                  configuration-instructions for VILE
doc/config.html                 vile's configure script information
doc/dir.doc                     description of perl directory-browser
doc/dir.html                    description of perl directory-browser
doc/filters.doc                 overview of syntax filter programs
doc/filters.html                description of vile's syntax filters
doc/macros.doc                  documentation for VILE macros
doc/macros.html                 description of vile's macro language
doc/make-hlp.pl                 script to format vile.hlp from dump
doc/make-hlp.sh                 script to generate vile.hlp
doc/make-toc.pl                 script to generate table-of-contents
doc/make-toc.sh                 script to generate table-of-contents
doc/makefile                    script to manage the ".doc" files
doc/menus.doc                   description of xvile (Xm and Xaw) menus
doc/menus.html                  description of xvile (Xm and Xaw) menus
doc/modes.doc                   overview of modes/majormodes
doc/modes.html                  description of vile's majormodes
doc/oleauto.doc                 document Winvile OLE
doc/oleauto.html                description of winvile's OLE automation support
doc/perl.doc                    notes about perl interface to vile
doc/perl.html                   notes about perl interface to vile
doc/vile-hlp.html               html version of help-file
doc/vile-man.html               html formatted manpage
doc/vile-man.sed                script to fixup id's for vile-toc.html
doc/vile-toc.html               generated table-of-contents
doc/visvile.doc                 document visvile.dll
doc/visvile.html                description of VisVile
filters                         subdirectory
filters/ada-filt.l              ada syntax highlighter for vile
filters/ada.key                 Ada95 keywords
filters/ant.key                 keywords for "ant" mode
filters/as-filt.l               syntax filter for (GNU) assembler
filters/as.key                  keywords for assembler-filter
filters/as386.key               assembler keywords for i386
filters/asm-filt.l              syntax filter for M$ assembler files
filters/asm.key                 keywords for M$ assembler files
filters/atr2ansi.c              convert attributed text to ANSI escape sequences
filters/atr2html.c              translate encoded text to html
filters/atr2text.c              convert attributed text to nroff-output
filters/au3-filt.l              syntax highlighter for AutoIt version 3
filters/au3.key                 keywords for AutoIt version 3
filters/awk-filt.l              awk syntax highlighter for vile
filters/awk.key                 keywords for awk syntax highlighting
filters/bas-filt.l              syntax filter for BASIC
filters/bash.key                bash keywords
filters/basic.key               keywords for basic syntax filter
filters/bat-filt.l              dos batchfile syntax filter for vile
filters/bat.key                 dos batchfile keywords
filters/bnf-filt.l              BNF filter
filters/bnf.key                 keywords for BNF filter
filters/c-filt.c                c filter
filters/c-filt.flx              original flex-based c-filter
filters/c.key                   keywords for C
filters/cfg-filt.l              syntax filter for Lynx config file.
filters/conffilt.l              syntax-filter for config-files
filters/cpp.key                 C++ keywords
filters/cs.key                  keywords for C#
filters/csh.key                 keywords for csh/tcsh syntax highlighting filter
filters/css-filt.l              syntax filter for CSS files
filters/css.key                 keywords for css mode
filters/cweb.key                keyword table for cweb syntax filter
filters/cwebfilt.l              cwebx syntax filter for vile
filters/dcl-filt.l              VAX dcl syntax highlighting filter for vile
filters/dcl.key                 dcl keywords
filters/def-filt.l              syntax filter for Windows ".def" files
filters/def.key                 keywords for Windows ".def" files
filters/delphi.key              keywords for delphi
filters/diff.key                keywords for 'diff' syntax filter
filters/difffilt.l              syntax filter for 'diff' output
filters/docbook.key             keywords for docbook
filters/ecl-filt.l              syntax filter for ECLiPSe
filters/ecl.key                 keywords for ecl-filt.l
filters/ecrypt.c                uemacs-derived encryption
filters/erl-filt.l              erlang syntax filter
filters/erl.key                 erlang keywords
filters/esql.key                keywords for embedded SQL with C/C++
filters/esqlfilt.l              syntax filter for embedded SQL with C/C++
filters/est-filt.l              syntax-highlighter for enscript syntax descriptions
filters/est.key                 keywords for enscript syntax-descriptions
filters/fdl-filt.l              syntax filter for forms-definition
filters/fdl.key                 keywords for forms-definition
filters/filterio.c              main program and I/O for external filters
filters/filters.c               common utilities for filtering
filters/filters.h               interface/definitions for filtering utilities
filters/filters.rc              sample majormodes, and corresponding filters
filters/flt_defs.h              split-out the include stuff from filters.h
filters/fltstack.h              simple state-stack for lex filters
filters/genmake.c               parse/substitute from genmake.mak
filters/genmake.mak             makefile template-data for genmake.awk
filters/genmake.sh              script to generate genmake.mak
filters/go.key                  keywords for "go"
filters/hs-filt.l               syntax filter for Haskell
filters/hs.key                  Haskell keywords
filters/html.key                keywords for vile-html-filt
filters/htmlfilt.l              HTML syntax filter for vile
filters/imake.key               keywords for imake-filter
filters/imakeflt.l              syntax filter for Imakefile's
filters/infofilt.l              syntax filter for GNU info files
filters/ini-filt.l              syntax filter for ".ini" files
filters/ini.key                 keywords for ini-filters
filters/iss-filt.l              syntax filter for Inno Setup
filters/iss.key                 keywords for Inno Setup
filters/java.key                java keywords
filters/js.key                  javascript keywords
filters/json.key                JSON keywords
filters/jsonfilt.l              syntax highlighter for JSON
filters/key-filt.c              syntax filter for vile keyword files
filters/ksh.key                 keywords for ksh
filters/latex.key               latex keywords
filters/latexflt.l              LaTeX syntax filter for vile
filters/lex-filt.l              lex syntax filter for vile
filters/lex.key                 keywords for lex + c
filters/lisp.key                keywords for lispmode
filters/lispfilt.l              syntax filter for lisp
filters/lua-filt.l              lua syntax highlighter
filters/lua.key                 lua keywords
filters/m4-filt.c               syntax filter for M4
filters/m4.key                  keywords for M4 syntax filter
filters/mail.key                keywords for mail-filter
filters/mailcap.key             keywords for mailcap mode
filters/mailfilt.l              mail syntax highlighting filter for vile
filters/make.key                keywords for makefile syntax highlighter
filters/makefile.2nd            rules for filters/makefile
filters/makefile.djg            makefile for DJGPP (vile-utilities)
filters/makefile.emx            makefile for OS/2 EMX (vile utilities)
filters/makefile.icc            makefile for OS/2 IBM CSet (vile utilities)
filters/makefile.in             makefile for vile filters
filters/makefile.wnt            makefile for filters with Visual C++
filters/makefilt.l              makefile syntax filter for vile
filters/makelist.sh             script to construct a list of filter names
filters/manfilt.c               manpage-filter
filters/mc-filt.l               mailcap syntax filter
filters/mcrl.key                filters for mCRL/mCRL2
filters/mcrlfilt.l              filters for mCRL/mCRL2
filters/midl.key                keywords for MIDL
filters/midlfilt.l              syntax filter for MIDL
filters/mk-0th.awk              construct builtflt.h
filters/mk-0th.bat              generate builtflt.h from genmake.mak
filters/mk-1st.awk              script to generate lists of built-in/external filters
filters/mk-1st.bat              generate lists for makefile.wnt
filters/mk-2nd.awk              script to generate rules for building filters
filters/mk-2nd.bat              generate rules for makefile.wnt
filters/mk-key.awk              generate install/uninstall rules for keyword files
filters/mms-filt.l              mms syntax filter for vile
filters/mvn.key                 keywords for mvn (maven) mode
filters/nmake.key               keywords for nmake
filters/nmakeflt.l              syntax filter for nmake
filters/noclass.sh              script to support lex's w/o character-classes
filters/nr-filt.l               nroff syntax highlighting filter for vile
filters/nr.key                  keywords for nroff filter
filters/nsis.key                keywords for NullSoft installer
filters/objc.key                keywords for objective-c (objc) mode
filters/pas-filt.l              Pascal syntax filter for vile
filters/pas.key                 keywords for pascal highlighting filter
filters/pc.key                  keywords for printcap syntax highlighting
filters/perl.key                keywords for perl syntax filter
filters/perl6.key               keywords for perl6 syntax filter
filters/php-filt.l              syntax filter for php
filters/php.key                 keywords for phpmode
filters/pl-filt.c               syntax highlighter for perl
filters/pl6filt.c               syntax highlighter for perl6
filters/pot-filt.l              syntax filter for gettext ".po" files
filters/pot.key                 keywords for pot (gettext) mode
filters/prolog.key              keywords for prolog
filters/ps-filt.l               syntax filter for PostScript files
filters/ps.key                  keywords for PostScript syntax filter
filters/ps1-filt.l              syntax highlighter for powershell
filters/ps1.key                 keywords for powershell mode
filters/py-filt.l               syntax filter for Python
filters/py.key                  keywords for Python syntax filter
filters/rb.key                  keywords for Ruby syntax filter
filters/rc-filt.l               syntax filter for Windows ".rc" files
filters/rc.key                  keywords for Windows ".rc" files
filters/rcs-filt.l              syntax filter for RCS archives
filters/rcs.key                 keywords for RCS syntax filter
filters/rexx.key                keywords for REXX syntax filter
filters/rexxfilt.l              syntax filter for REXX
filters/rpm-filt.l              syntax highlighter for rpm spec-files
filters/rpm.key                 keywords for rpm spec files
filters/rtf-filt.l              syntax filter for RTF files
filters/rtf.key                 control keywords for RTF
filters/ruby.key                alias for rb.key
filters/rubyfilt.c              syntax filter for Ruby
filters/rust.key                keywords for rust
filters/rustfilt.l              syntax filter for rust
filters/sccs.key                keywords for SCCS syntax filter
filters/sccsfilt.l              syntax filter for SCCS files.
filters/scheme.key              keywords for scheme
filters/scm-filt.l              syntax highlighter for "scheme"
filters/sed-filt.c              highlighting filter for sed-scripts
filters/sh-filt.l               a sh/ksh/csh syntax filter for vile
filters/sh.key                  keywords for "sh" syntax filter
filters/sml-filt.l              filter for Standard ML
filters/sml.key                 keywords for Standard ML
filters/spell.rc                defines a filter for spell-checking
filters/spellflt.l              ispell filter to highlight misspelled words
filters/sql-filt.l              sql syntax highlighting filter for vile
filters/sql.key                 sql keywords
filters/syntax.key              demo of the keyword file syntax
filters/tags.key                keywords for tags files
filters/tagsfilt.c              syntax highlighter for tags files
filters/tbl-filt.l              syntax filter for vile's mktbls program
filters/tbl.key                 keywords for tbl-filt.l
filters/tc-filt.l               termcap syntax highlighting filter for vile
filters/tc.key                  termcap keywords for syntax highlighting
filters/tcl-filt.l              tcl/tk syntax highlighting filter for vile
filters/tcl.key                 tcl/tk keywords
filters/tex.key                 keywords for TeX
filters/texi.key                keywords for texinfo syntax filter
filters/texifilt.l              syntax filter for texinfo
filters/ti-filt.l               terminfo syntax highlighting filter for vile
filters/ti.key                  terminfo keywords
filters/tpu-filt.l              syntax filter for TPU (DEC text-processing utility)
filters/tpu.key                 TPU keywords
filters/ts.key                  keywords for typescript mode
filters/txt-filt.l              syntax filter for ordinary text
filters/unfilter.c              main program, parsing for un-filters
filters/unfilter.h              common definitions for un-filters
filters/vb.key                  keywords for Visual Basic .Net
filters/vb6.key                 keywords for Visual Basic 6
filters/vbs.key                 keywords for vbsmode
filters/vcproj.key              keywords for older Visual Studio project-files
filters/vcxproj.key             keywords for Visual C++ project-files
filters/vile.key                fallback template for highlighting colors
filters/vilefilt.l              syntax filter for vile macros
filters/vim.key                 keywords for vim syntax files
filters/vl-filt.l               Verilog syntax highlighting filter
filters/vlog.key                verilog keywords, from vgrind definition
filters/wbt-filt.l              syntax highlighter for winbatch
filters/wbt.key                 WinBatch keywords
filters/xml-filt.l              syntax filter for xml
filters/xml.key                 keywords for xml syntax highlighter
filters/xq-filt.l               syntax filter for XQuery
filters/xq.key                  keywords for XQuery
filters/xres.key                keywords for X resource filter
filters/xresfilt.l              syntax filter for X resource files
filters/xs-filt.l               syntax filter for Perl extensions
filters/xs.key                  keywords for Perl-extension syntax filter
filters/xsl.key                 keywords for xsl files
filters/yacc.key                yacc keywords
filters/yaccfilt.l              yacc syntax highlighting filter for vile
filters/yaml.key                yaml keywords
filters/yamlfilt.l              syntax filter for yaml
filters/zsh.key                 zsh keywords
icons                           subdirectory
icons/pumpkin.ico               V-eyes pumpkin icon
icons/pumpkin.xbm               X bitmap, for vile icon
icons/pumpkin.xcf               Gimp-formatted pumpkin-icon
icons/pumpkin.xpm               pumpkin icon, in Xpm form
icons/pumpkin_48x48.png         png-formatted pumpkin-icon 48x48
icons/pumpkin_48x48.svg         svg-formatted pumpkin-icon on 48x48 grid
icons/pumpkin_48x48.xcf         Gimp-formatted pumpkin-icon scaled to 48x48
icons/sink.ico                  kitchen-sink icon (J.R.Sladkey)
icons/sink.xbm                  X bitmap, for vile icon
icons/sink.xcf                  Gimp-formatted sink-icon
icons/sink.xpm                  X bitmap for vile icon
icons/sink_48x48.png            png-formatted sink-icon 48x48
icons/sink_48x48.svg            svg-formatted sink-icon on 48x48 grid
icons/sink_48x48.xcf            Gimp-formatted sink-icon scaled to 48x48
icons/vile-mini.svg             just the tildes from vile_48x48.svg, resized.
icons/vile-mini_16x16.xpm       16x16 pixmap from vile-mini.svg
icons/vile-mini_32x32.xpm       32x32 pixmap from vile-mini.svg
icons/vile-mini_48x48.xpm       48x48 pixmap from vile-mini.svg
icons/vile.ico                  Windows icon, for vile
icons/vile.xbm                  sample icon, for X bitmap
icons/vile.xcf                  Gimp-formatted vile-icon
icons/vile.xpm                  sample icon, for xpm library
icons/vile_48x48.png            png-formatted vile-icon 48x48
icons/vile_48x48.svg            svg-formatted vile-icon on 48x48 grid
icons/vile_48x48.xcf            Gimp-formatted vile-icon scaled to 48x48
macros                          subdirectory
macros/UXVile.ad                X resources for uxvile
macros/XVile.ad                 sample X resource file for vile
macros/color-ls.rc              sample macro: read output of "color ls"
macros/complete.rc              example for insert-mode completion
macros/dates.rc                 demo of &date function
macros/digraphs.rc              macros for inserting digraphs
macros/gnugpg.rc                GNU gpg macros
macros/loaderrs.rc              macro to perform load-error-expressions
macros/lxvile                   locale-sensitive wrapper for xvile
macros/lxvile-fonts             wrapper for xlsfonts which shows the fonts matched by lxvile's query.
macros/lxvile.desktop           desktop file for lxvile
macros/manpage.rc               macros for man-page filtering/display
macros/modes.rc                 settings for majormodes (except filtername)
macros/palettes.rc              sample color schemes
macros/pictmode.rc              macros to support "picture-mode" editing
macros/search.rc                find a file in one of several locations
macros/shifts.rc                macros to shift words left/right
macros/showeach.rc              show-each-buffer
macros/uxvile                   wrapper script to run xvile in UTF-8 locale
macros/uxvile.desktop           desktop file for uxvile
macros/vile-libdir-path         utility to print PATH updated to include vile's helpers.
macros/vile-pager               use vile as a pager
macros/vile-to-html             convert files to html
macros/vileinit.rc              sample initialization file
macros/vilemenu.rc              sample menu for xvile
macros/vileperl.rc              sample initialization for perl scripts
macros/which.rc                 script to show which keyword file is found by filters
macros/xvile.desktop            desktop-file for xvile
package                         subdirectory
package/convile.nsi             NSIS package for convile
package/debian                  subdirectory
package/debian/README.Debian    debian build script
package/debian/changelog        debian build script
package/debian/compat           debian build script
package/debian/control          debian build script
package/debian/copyright        debian build script
package/debian/overrides        subdirectory
package/debian/overrides/vile   debian build script
package/debian                  subdirectory
package/debian/rules            debian build script
package/debian/source           subdirectory
package/debian/source/format    build-script
package/debian                  subdirectory
package/debian/vile-common.docs debian build script
package/debian/vile-common.examples  debian build script
package/debian/vile-common.files  debian build script
package/debian/vile-common.manpages  debian build script
package/debian/vile-filters.files  debian build script
package/debian/vile-filters.links  debian build script
package/debian/vile.files       debian build script
package/debian/vile.links       debian build script
package/debian/vile.menu        debian build script
package/debian/vile.mini.xpm    debian build script
package/debian/vile.postinst    debian build script
package/debian/vile.prerm       debian build script
package/debian/xvile.files      debian build script
package/debian/xvile.links      debian build script
package/debian/xvile.menu       debian build script
package/freebsd/vile            subdirectory
package/freebsd/vile/Makefile   build-script
package/freebsd/vile/distinfo   build-script
package/freebsd/vile/pkg-descr  build-script
package/freebsd/vile/pkg-plist  build-script
package/freebsd/xvile           subdirectory
package/freebsd/xvile/Makefile  build-script
package/freebsd/xvile/distinfo  build-script
package/freebsd/xvile/pkg-descr build-script
package/freebsd/xvile/pkg-plist build-script
package                         subdirectory
package/minvile.nsi             NSIS package for minvile
package/pkgsrc/vile               subdirectory
package/pkgsrc/vile/ALTERNATIVES  build-script
package/pkgsrc/vile/DESCR       build-script
package/pkgsrc/vile/Makefile    build-script
package/pkgsrc/vile/PLIST       build-script
package/pkgsrc/vile/distinfo    build-script
package/pkgsrc/vile/options.mk  build-script
package/pkgsrc/xvile            subdirectory
package/pkgsrc/xvile/DESCR      build-script
package/pkgsrc/xvile/Makefile   build-script
package/pkgsrc/xvile/PLIST      build-script
package                         subdirectory
package/vile.spec               sample RPM spec file for vile
package/winvile-wide.iss        Inno Setup script for winvile-wide
package/winvile.iss             Inno Setup script for winvile
package/winvile.nsi             NSIS package for winvile
package/winvile64-wide.iss      build-script
package/winvile64.iss           build-script
perl                            subdirectory
perl/Breadcrumbs.pm             manages bookmarks for a set of files
perl/CaptHook.pm                manage various types of hooks from perl
perl/Glob2re.pm                 perl: convert wildcard (glob) to regular expression
perl/Help.pm                    a help-script.
perl/Vile.pm                    utility functions for perl scripts
perl/Vile                       subdirectory
perl/Vile/Exporter.pm           provides an import method for vile's Perl5 extensions
perl/Vile/Manual.pm             display perl (pod) documentation like a manual-page
perl                            subdirectory
perl/Vileserv.pm                provides file-load server capability for xvile
perl/Visit.pm                   perl: utility for visiting files
perl/capture.pm                 Perl script that improves on vile's capture-command
perl/dict.pm                    dictionary lookup via dict.org
perl/directory.pm               directory-browser extension
perl/dirlist.pm                 perl: create a flat directory listing
perl/gdb.pm                     run gdb in a window, tracking changes
perl/hgrep.pm                   Perl utility: recursive grep, makes hypertext links
perl/lock.pm                    Perl: screen-lock script
perl/man.pm                     a manpage-script
perl/mime.pl                    mime-aware file viewer support
perl/plugins.pl                 plugins extension to the mime library
perl/search.pm                  Perl: lookalike for vile's search commands
perl/shell.pm                   Perl: spawn a shell via a pty
perl/spell.pm                   Perl: interactive spelling checker/corrector
perl/vileget                    pass file-edit request to xvile session running Vileserv
perl/winops.pm                  window-operations for testing the Perl5 interface
plugins                         subdirectory
plugins/Makefile                makefile for plugin samples
plugins/test.c                  example of a plugin
plugins/test.rc                 script to exercise plugin sample
visvile                         subdirectory
visvile/commands.cpp            implement commands for visvile.dll
visvile/commands.h              implement commands for visvile.dll
visvile/dsaddin.cpp             developer-studio add-in support
visvile/dsaddin.h               developer-studio add-in support
visvile/oleauto.cpp             manage winvile OLE automation server
visvile/oleauto.h               interface for oleauto.cpp
visvile/readme.txt              overview of visvile.dll
visvile/resource.h              generated definitions for visvile.dll
visvile/stdafx.cpp              standard-includes interface for visvile.dll
visvile/stdafx.h                standard-includes interface for visvile.dll
visvile/tbarlrge.bmp            large toolbar icons for visvile
visvile/tbarmedm.bmp            medium toolbar icons for visvile
visvile/visvile.cpp             initialization routines for visvile.dll
visvile/visvile.def             declares module parameters for visvile.dll
visvile/visvile.dsm             DevStudio macros for visvile
visvile/visvile.dsp             developer-studio-project file
visvile/visvile.dsw             developer-studio-workspace file
visvile/visvile.h               interface/common defs for visvile
visvile/visvile.odl             OLE definition for visvile
visvile/visvile.rc              resource-file for visvile
visvile/visvile.rc2             resource-file for visvile
vile-9.8v/README000066400000000000000000002255031415556424100134150ustar00rootroot00000000000000
README for vile, version 9.8
----------------------------

vile is a text editor which is extremely compatible with vi in terms
of "finger feel".  in addition, it has extended capabilities in many areas,
notably multi-file editing and viewing, key rebinding, real X window
system support, an optional embedded perl interpreter, and robust
support for non-Unix hosts.

the authors of vile are Paul Fox, Tom Dickey, and Kevin Buettner.

many patches have been contributed by a lot of users.  we thank them.

more recent additions to this README appear near the bottom.  that is, most
of the newest stuff is at the end, not up here where you are.

visit
	ftp://ftp.invisible-island.net/vile
	http://invisible-mirror.net/archives/vile/
to be sure it's still the latest.

impatient?  just type "./configure; make", and get a cup of coffee, decaf
if necessary.

want to know more about configure options?  type "./configure --help"
and then read doc/config.doc for further details.

want X11 support?  you'd better look at doc/config.doc, although
"./configure --with-screen=x11"; make" may well do what you want.

want syntax coloring?  add "--with-builtin-filters" to your configure
options and then read the topics "Color basics" and "Syntax coloring" in
the file vile.hlp.

want PC support?  look for precompiled binaries at the various ftp sites.

want to build vile on a PC host?  refer to the file README.PC .

want VMS support?  some precompiled binaries are available at
	ftp://ftp.invisible-island.net/pub/vile
otherwise, you'll need to build vile yourself.  In either case, refer to the
file README.VMS .

if you like vile, and wish to be informed of new releases, let me know -- i
maintain a mailing list for that purpose (scroll down a bit for details).
don't worry -- the volume won't fill your inbox.

paul fox, pgf@foxharp.boston.ma.us (original author)
kevin buettner, kevin@buettner.to
tom dickey, dickey@invisible-island.net (current maintainer)

------------------------------------------------------
Up-to-date copies of vile, including executables for DOS, Win32 and
OS/2 are found at
	ftp://ftp.invisible-island.net/vile/

which is mirrored at
	http://invisible-mirror.net/archives/vile/

Development patches are found at
	ftp://ftp.invisible-island.net/vile/patches/
	http://invisible-mirror.net/archives/vile/patches/

In addition, we have distributed copies at other sites, including
metalabs.unc.edu, hobbes.nmsu.edu (OS/2) and the VMS Freeware
CDROM's.

------------------------------------------------------

There is a project mailing list.  You can subscribe to it here:
    https://savannah.nongnu.org/projects/vile/

To submit bug reports, either subscribe to the list (since
non-subscribers aren't allowed to post) or use the bug system at
that same URL.

------------------------------------------------------

extracts from the original README, from February, 1992:

VILE -- VI Like Emacs: a vi workalike put together from Micro-Emacs by Paul Fox
-------------------------------------------------------------------------------

	This editor grew out of a frustration that although lots of
	eager programmers have tackled rewrites of Emacs, with new and
	better features (not to mention free source), I've not seen
	anything similar done with the Second True Editor.  (The
	First, of course, being /bin/ed)

	...

	vile retains the multiple buffer/multiple window features of
	MicroEMACS, but the "finger-feel", if you will, is very much
	that of vi.  It is definitely not a clone, in that some
	substantial stuff is missing, and the screen doesn't look
	quite the same.  But what matters most is that one's "muscle
	memory" does the right thing to the text in front of you, and
	that is what vile tries to do for vi users.  THIS IS NOT A
	"CLONE"!  But it feels good.  (Put another way, the things
	that you tend to type over and over probably work -- things
	done less frequently, like configuring a .exrc file, are quite
	different.)

	...

	The collective developers of Micro-Emacs should be
	complimented that the changes were as easy as they were.
	...

	Paul G. Fox	June, 1991, and February, 1992

p.s. By the way, I'm _not_ the same Paul Fox who wrote Crisp, the Brief
	work-alike.


-----------------------

September, 1992

I don't have much to add to the original README -- vile has gotten a lot
better since I first released it, thanks to a lot of users and a lot of
bug reports.  It compiles and runs without modification on most major UNIXes,
and under DOS.  It offers vi finger feel, and most (not all) of its features.
I hope it fills someone's need out there.  -pgf 9/92

(Special thanks to Dave Lemke and Pete Rucszinski, for X and DOS support,
and (in no particular order) to Eric Krohn, Willem Kasdorp, J.C.Webber,
Warren Vik, Julia Harper, Chris Sherman, Thomas Woo, Yanek Martinson, Miura
Masahiro, Tom Dickey for lots of bug reports and suggestions and patience.)

------------------------------

April, 1993

Well, here's an update on vile.  The first release was a long time
ago (a couple of years?).  Tom Dickey has been contributing a _whole_ lot
of good changes.  vile now runs on VMS, and is much more stable on DOS
thanks to Tom.  For me, vile is becoming an "old" program -- I first worked
on it in 1989 sometime.  So it's been fun to have someone contributing
fixes so energetically.  Thanks Tom.

One thing that's changed since I first started vile is that "lots of eager
programmers" have now tackled rewrites of vi.  There are several good work-
alikes out there: elvis (the "king" :-), xvi, vim, stevie, and recent
versions of vip-mode in GNU emacs.  [add "nvi" to that list.  and whatever
happened to xvi?  -pgf 12/94]  From what little I've used any of
these, they all seem like real good programs.  vile feels different from
most of them, mainly due to its roots in MicroEmacs.  You may or may not
like it.  If you don't, try one of the others.  There's certainly no reason
to not have a vi-like editor on just about any machine you choose.  (yeah,
I know -- I'm assuming you _want_ a vi-like editor...  :-)  Enjoy.

Oh yes -- building it.  On UNIX, type "make", and choose one of the predefined
targets.  Like "make linux". [ not anymore -- use "configure; make"  -pgf 12/94]

DOS makefiles are named after the compiler they support:  makefile.tbc for
Turbo-C, makefile.wat.  There is support in "makefile" for Microsoft-C, but
it's next to useless -- if anyone puts together a good "nmake" makefile,
could you pass it along?  [that support isn't there anymore.  -pgf 12/94]

The Watcom C/386 v9.0 compiler should also work -- the makefile to use is
makefile.wat.

The latest version of vile is usually available for ftp at "ftp.cayman.com",
in the pub/vile directory.  [not anymore -- it's at "id.wing.net" in the
"pub/pgf/vile" directory.  -pgf 12/94] Sometimes there's a compiled DOS
binary there too.  I don't maintain a mailing list, or anything like that
to inform folks of new releases -- you just sort of have to check once in a
while, or send me mail...  [ I've set up a mailing list -- contact me to be
added -pgf 7/93]

paul

------------------------------

July, 1993

More new features:  infinite undo, modification time checking, and, at
long last, primitive support for the :map command.  [:map is now fully
functional -pgf, 12/94] I've also received patches that let vile compile
for DOS with the DJ GCC compiler.  Have I mentioned filename completion?
Tom Dickey provided that and variable/modename/command completion too.

If you would like to be informed, via email, of new vile releases (bearing
in mind that the newest release may be _more_ likely to be buggy, rather
than _less_), please send me mail, and I will add you to my list.  The email
will probably contain a capsule summary of the most recent changes to the
code.

Thanks to Tuan Dang for the Watcom and DJ GCC work.  I don't know much
about djgpp, the DOS port of djgcc, but take a look at makefile.djg.


pgf


-------------------------------

March, 1994

The X support in xvile has been given a huge boost with contributions from
Kevin Buettner -- scrollbars, Motif widget support make it feel like a real
application...  We now have rectangular regions.  DOS support is getting
better all the time.  The major version number got bumped to 4 somewhere
along the line, because Tom and I were getting tired of 3.  There are quite
a few new "modes", some to support vi functionality, some altogether new.
We should have keyboard selections and highlighted regions soon...

pgf, pgf@foxharp.boston.ma.us


-------------------------------
December, 1994

hmmmm -- lets see.  new stuff.  see the CHANGES and help files for details.

	- vile is now completely autoconf'ed -- you should be able to type
	either "./configure; make" or "./configure --with-screen=x11" to build
	it on any (unix-like) platform.

	- :map and :map! are now much more complete, but still by no means
	done.  expect to have to edit your favorite macros to make
	them work.

	- :abbr now works.

	- along with proper :map support comes proper function key support.
	function keys defined for your terminal in the termcap/info database
	are now premapped and can be bound to as #-1 etc.  so those of
	you with ESC [ 10 ~ style function keys should be happy now.

	- mouse clicks which move the cursor now count as proper motion
	commands in both xvile and vile-in-an-xterm.  this means, for
	instance, that '' or `` will get you back to where you were before
	you clicked the mouse, and you can apply operators to mouse
	movements.  for example -- click the mouse somewhere, hit 'd' to
	start a delete operation, and click the mouse somewhere else.  the
	text between the two mouse-click locations will be deleted.

	- on-line help (just a single line) for every function, available
	with describe-{bindings,function,key} commands.

	- new modes to better control beeping and the "working..." message.

	- autowrite mode now supported, on a global or buffer-by-buffer basis.

	- popup windows now adjust their size to their contents -- less screen
	space is wasted for small window, and more is used for big windows.

	- file and command completion is now more emacs/bash/tcsh-like, in
	that possible choices are shown when you hit a second TAB key.  this
	can be tuned via a new mode, "popup-choices"

	- "quoted" motions, which highlight the text they will act on.  type
	a 'q', and start moving around, then type another 'q'.

	- various fixes to the macro language, for core dumps and usability.

	- file.bak and file~ backup files now supported.

	- infinite (?) screen sizes should now be supported under X.

	- it's now possible to break lines by putting ^M in the replacement
	pattern.

	- selections, the modelines, and the cursor, under xvile, can all
	have different colors.

	- color support for termcap, at least on the linux console.

	- put'ing from registers (i.e. 'p' and 'P' commands) should be much
	faster.

	- multiple (error) messages arising from running a macro or a startup
	file will now accumulate in a new popup window.

	- a simple, probably incomplete file-locking protocol is available,
	but is not compiled in by default.  the organization which
	contributed the code (Baan Development) uses it to aid their
	multi-user development.  turn on OPT_LCKFILES in estruct.h and
	"set usefilelock" in your .vilerc to play with it.

	- Windows NT support -- console mode only.  anyone want to port this
	to the Windows95 console?  it's probably not hard, though i haven't
	looked into it very hard.

	- lots of bug fixes

-------------------------------
Febrary, 1995
	xvile now supports color attributes, which means we can do some
	primitive syntax coloring of C programs, using the external filter,
	"c-filt".  this is still pretty new stuff.  expect it to get better
	with age.


-------------------------------
November, 1995
	lots of new users in the last year, due to better advertising
	and inclusion in some of the big linux and freebsd archives.
	support for NT and OS/2 has gotten much better, and lots of
	little bugs have been fixed, and features added.  Win32 support
	is very good these days, thanks mostly to the efforts of Rick
	Sladkey.

-------------------------------
June, 1996
	gee, i don't remember _what_ we've done recently.  enjoy.

-------------------------------

September, 1996
	tom dickey has volunteered to take over releases, and maintaining
	"official" sources.  i'll still contribute, but more as part of the
	"audience".  tom has done a _huge_ amount of work over the years
	on vile -- i _really_ appreciate it...  -pgf

-------------------------------

May, 1998
    vile 8.0 is released.  Major new features include:  an embedded
    perl interpreter (available on Unix and Win32 hosts), an editable
    mini-buffer, majormodes, enhancement of user-defined procedures to
    the point that they may now be bound to user-defined keystrokes,
    tag completion, and addition of a win32 gui (called winvile).

-------------------------------

Oct, 1998
    vile 8.1 and 8.2 are released.  These are primarily bugfix releases.
    Refer to the CHANGES files for details.  Tom Dickey continues to
    improve winvile, which now supports scroll bars and two new
    command-line options that control the editor's geometry and font.

Apr, 1999
    vile 8.3 is released.  This release includes much enhanced syntax
    filter capabilities.  The filters are now much faster, mainly because
    vile uses a new command attribute-from-filter to apply their output
    directly as attributes to the buffer rather than modifying (and
    allowing undo).

    The organization of the keyword files for the syntax filters is now
    associated with majormodes.  Syntax filters are defined for most of the
    predefined majormodes which include:

        adamode                   jsmode                    perlmode
        awkmode                   keymode                   sccsmode
        batmode                   latexmode                 shmode
        cmode                     lexmode                   sqlmode
        cshmode                   m4mode                    tcmode
        cwebmode                  mailmode                  tclmode
        dclmode                   makemode                  timode
        diffmode                  mmsmode                   txtmode
        htmlmode                  nrmode                    vilemode
        imakemode                 pasmode                   yaccmode
        javamode

    Other changes of note (this is not an exhaustive list):

    + removed/rewrote code which would prevent us from making vile available
      under more liberal licensing.

    + winvile and xvile have icons.

    + new macro directives added, including:

      ~local  ~hidden  ~with  ~endwith  ~elsewith

    + many VMS bug fixes and enhancements.  8.3 is a keeper if you use VMS.

Nov, 1999
    vile 8.4/9.0 is released, distributed with GPL licensing.

    In addition to improvements to syntax highlighting, e.g., user-definable
    color schemes, vile's macro language has been extended

    	+ procedures can be parameterized.

	+ several new functions simplify handling of external filenames, and
	  parsing strings.

    Further improvements have been made to winvile: drag/drop, file open
    dialog, better integration with the Windows Explorer and DevStudio.

Jan, 2000
    vile 9.1 is released.  Highlights since 9.0:

    + continued improvement of syntax coloring (much work here)

    + add an Exporter-like mechanism to Perl5 interface. Instead
      of exposing a module's functions to the caller, it exposes them to
      vile as registered commands.  By renaming the extensions as `.pm',
      and making some minor changes to use Vile::Exporter, an extension
      becomes visible by simply adding:
          use extension;
      to vileinit.pl.  There is also provision for only including some
      commands provided by the extension, and for overriding the keybinding
      defined by the developer (documented in the attached module).
      Of course you can still say:
           require extension;
      and do the registering yourself if you so choose.

    + vile's perl interface includes a new Vile::Window module, which may
      be used to manipulate vile windows.  Examples of the use of this
      module may be found in winops.pm.

    + rename most .pl files to .pm (makefile.in).

    + add/improve several perl scripts, including

      - capture.pl - implements a perl version of capture-command.  This
        version incrementally updates the window however.

      - shell.pl - revised to use IO:Pty instead of Comm.pl (which
        seems to be no longer maintained).

      - Manual.pm - display embedded POD documentation.

    + implement watchfd support for the termcap/terminfo versions of vile.

    + added autocolor feature, which updates color syntax highlighting when
      the keyboard is inactive for a specified period.

    + Vileserv now also works for vile.

    + changed vmsbuild.com to accept a compiler specification on the VMS
      command line, which is much more convenient than editing the build
      script by hand.  compiler defaults to VAXC on Vax hosts and DECC on
      Alpha hosts.

    + Several Win32-specific improvements:

      - add the Win32 common dialog "save as" feature to both console
        vile and winvile.

      - modify directory.pm and dirlist.pm to make them work on win32, i.e.,
        by not executing portions that will not work (such as mime types).

      - implement autoscrolling feature for winvile, which makes the buffer
        scroll in the direction where the mouse leaves the window,
        automatically extending selection highlighting.

    + modify backspacelimit mode to allow backspacing through a newline
      when nobackspacelimit is specified.

    + add single-quoted strings, which eliminate the need for escaping
      backslash (useful in startup/command files)

    + Added binding / support for ^X-_ aka
      "historical-buffer-to-current-window".

    + modify logic in ins_any_time() to interpret control characters which
      are bound to GOAL or MOTION commands rather than inserting them
      without quoting.  This allows ^E and ^Y as commands within an insert.

Oct, 2000
    vile 9.2 is released.  Highlights since 9.1 (modulo bug fixes):

    + improve performance of syntax highlighting with configure option
      for compiling-in any of the syntax filters.  Use the configure
      --with-builtin-filters option.  Both internal (built-in) and
      external filters are supported.

    + add key binding functions for the different editing modes (insert,
      command, minibuffer and default), making it simpler to bind a
      space or tab to a given function without having it confused for a
      function while in insert mode.

    + Vileserv now uses the registry, so 'perl "use Vileserv"' in your
      .vilerc automagically adds the commands startserv, stopserv, and
      vileserv-help.

    + added gdb.pm, which runs gdb in a vile window and tracks changes
      in editor.  (Must be used with shell.pm.)

    Several Win32-specific improvements:

    + allow pasting of one line of text into mini-buffer.

    + winopen, winopen-nocd, winsave, and winsave-nocd accept an
      optional directory argument, which specifies the initial directory
      opened by the Open/Save Win32 common dialogs.

    Other Modes:

    + add insert-exec mode to control logic in ins_any_time() which
      interprets control characters which are bound to GOAL or MOTION
      commands rather than inserting them without quoting (see 9.0a and
      9.0b changes).  This restores the default behavior, since some
      users had control characters bound to a function which was then
      executed.

    + add unique-buffers mode, which does dev/inode checking to be sure
      files aren't edited more than once.

    Syntax Filters:

    + add syntax filters for sed, imake

    + implement abbreviations for syntax keywords, using '*' as the
      default delimiter.

    + filters now attribute multi-line regions when appropriate, e.g.,
      multi-line comments in C.

    Macros and Scripting Support:

    + add &dquery function which prompts for input with a given default
      value.

    + implement function &error, which returns true if its argument was
      an ERROR token.  Modify built-in functions to return ERROR if an
      argument was ERROR.

    + add variable $filename-expr, to specify the actual pattern used
      for %F in [Error Expressions].  On DOS and Win32, this is
      initialized to a more complex pattern, to accommodate drive
      letters.

    + make the ~local directive work for modes.

    + add ~trace directive, which sets or reports the value of the
      $debug variable.  Use this to trace into internal buffer [Trace].

    + add macros/shifts.rc, which implements left/right shifting of
      words in the current line to align with the cursor.

    Other Changes:

    + modify color support in xvile to allow the pre-8.3s color scheme
      as a special case:  setting bcolor to fcolor makes xvile use the
      bcolorN resources on syntax-highlighted text rather than the color
      selected by bcolor (which is actually taken from the fcolorN
      resource in this case).

    + added pushd, popd, dirs commands with accompanying [DirStack].

June, 2002
    vile 9.3 is released.  Highlights since 9.2 (aside from bug fixes):

    + add dirs-clear and dirs-add commands

    + added select-all and selection-clear commands.

    + change default for $XSHELLFLAGS from "-c" to "-e", which matches the
      documentation for $xshell-flags.

    + add write-all-buffers command; writes all buffers whether modified or not

    + add setenv (set-environment-variable) command.

    + added a swap-title mode and $title-format variable.

    + if the user specifies ":w!", and the file is not writable, vile will
      (try to) temporarily chmod the file for writable access.

    + added $findpath and $find-cmd state variables and, on win32 and unix
      hosts, modified capturecmd (aka ^X-!) to support find operations that
      span directory tree(s).

    + reimplement ":args" command to accept a filename expression.

    + add commands "ww!" and "wall!", to respectively write all changed
      buffers and write all buffers, using the "w!" behavior of ignoring
      readonly file permissions.

    + implement three functions for working with timestamps: &ftime, &stime,
      and &date, respectively for file modification time, system time, and
      formatted date/time.

    + extend insert-exec to allow ^A and ^X prefixes to be interpreted
      in insert mode

    + implemented support for reading/writing Macintosh files, i.e.,
      recordseparator=cr.  New commands set-rs-cr, set-rs-lf, set-rs-crlf
      extend the set-unix-mode and set-dos-mode commands to include Mac's.

    + add &stoken function, which searches for a token in a string, e.g.,
      "perl" in $cfgopts by
        &stoken  "perl"  ","  $cfgopts

    + add &translate function, e.g.,
        &trans   ","     " "  "a,b"
      to change commas to spaces

    + add commands leading-detab-til and leading-entab-til, binding those
      to ^X-' ' and ^X-^I.  Most of the logic was available internally.

    + implemented '< and '> marks, which denote the limits of the
      selection.

    Perl Interface:

    + add a new command to shell.pm called "xterm", which starts a shell in one
      of vile's buffers just as "start-shell" already does, but also starts an
      xterm through which one may (also) interact with the shell.  The shell
      output (and echoed input) is displayed in both the xterm and a vile
      buffer.

    + implement perl/Breadcrumbs.pm

    + add perl/Help.pm

    + add perl/CaptHook.pm, which provides useful wrappers for Vile's
      "hook" variables.

    Win32-Specific:

    + added basic win32 printing for winvile

    + modify ntconio.c so that default fcolor is 7

    + change paste in winvile to insert at DOT rather than after.  Also,
      when pasting in insert mode, set DOT to the end of the inserted
      text.

    + improve paste-by-right-mouse-click operation in winvile by NOT
      setting the insertion point at the position where the mouse happens
      to be when executing the right-click, but rather pasting at the
      current DOT (i.e.  right-mouse-click never sets DOT).

    + when popup-menu is inactive, if text is selected, right-click copies
      to w32clipboard; otherwise right-click pastes from w32clipboard.

    + added icursor (insertion cursor) mode.

    Syntax Filters:

    + add Verlog and ECLiPSe (Prolog dialect) filters

    + add syntax filter for BASIC, and majormodes basicmode and
      Visual Basic (vbmode).

    Other Changes:

    + add 'mouse' mode for OS/2 (CSet), to disable mouse when not wanted.

    + add $prompt variable, to allow changing the command-line prompt.

Aug, 2003
    vile 9.4 is released.  Highlights since 9.3 (aside from bug fixes):

    General changes:

    + regular expressions and searches allow null characters.

    + minibuffer editing commands are more complete, implementing all of the
      inline cursor search- and motion-commands.

    + implement new editing commands in the minibuffer:  r, ~, x, X.

    + use insert-mode bindings when mini-edit mode is active.  Use insert-key
      to toggle, rather than set mini-edit mode.

    + modify buffer- and filename-completion on Unix to escape backslashes
      which are stored in the [Completions] buffer.  Doing this allows one
      to complete a buffer or filename containing a backslash.

    + improve history-editing by quoting tokens which contain embedded blanks
      or other special characters, using that to retrieve tokens from the
      history buffer unambiguously.

    + save/restore window modes such as linewrap when rereading a file,
      or when executing a shell command.

    + use realpath() if it is available, and "$VILE_PWD" environment variable
      rather than "." as parameter to getcwd() if it is valid, to speed up
      operation on quasi-filesystems such as ClearCase.

    + add configure option --with-screen=XawPlus for XawPlus library.

    + add configure option --with-screen=ncursesw to allow building the
      curses driver using the wide-character version of ncurses.

    + add check in tcap.c for terminfo kmous capability like xterm, in case
      we are running in screen, which also supports xterm mouse protocol.

    + modify support for "^X-e" to make it use the whole line if the current
      buffer is a directory.

    Locale Improvements:

    + change default for --with-locale option to yes.  Note that this
      option is only tested if locale support is found, and it is becoming
      less common to encounter systems with broken locale support.

    + add "locale" to the "$cfgopts" variable if vile is compiled with
      locale support.

    + modify vile-manfilt to decode UTF-8 emitted by groff 1.18

    + in UTF-8 locale, adjust termcap driver to use UTF-8 to display codes
      in the 160-255 range, setting vile's locale to non-UTF-8 locale.
      (yes, this is a short-term fix).

    + add configure check for wctype functions, to work around defect in
      glibc's ctype functions: in UTF-8 locale, the latter return useless
      information on character classes.  This works on Solaris.

    + move upper/lower case-conversion into tables so that locale support can
      augment the built-in translation.

    New Commands:

    + "which-keywords" macro shows the location of files containing keywords
      for the given majormode.

    + "edit-buffer" simplifies "which-keywords" and similar macros.

    + "encode-attributes-til" and "write-encoded-til" convert the syntax
      highlighting in a region back to control/A sequences, or write the
      corresponding data to a file.  There is a corresponding alias
      "decode-attributes-til" for "attribute-cntl_a-sequences-til".

    + "substitute-all-til" implements the "^X-s" binding.

    New Modes:

    + add "overlap-matches" mode, to control whether highlighting for the
      visual-matches mode should skip to the next character, or past the
      current match when checking.

    + add "percent-crlf" mode, which controls the threshold at which the
      whole file will be considered DOS-format (CRLF record separators)
      if the given percentage already ends with CR/LF.

    + "yankmotion" mode controls whether the cursor should be moved as in vi
      after yanking text.

    + add "xterm-title" mode.

    + add logmode majormode, to distinguish some makefiles from logfiles.

    + add "texmode" majormode, as a variation of latexmode.

    New Variables and Functions:

    + add several short-named relational operators "&geq", ">", "&leq",
      "<", "&neq", "&sgeq", "&sgt", "&sleq", "&slt", "&sneq" to reduce
      the need for "¬".

    + add "$pathname-separator" variable.

    Syntax Filters:

    + add Ruby syntax filter.

    + add syntax filter for rpm ".spec" files.

    + add syntax filter for PostScript ".ps" files.

    + add syntax filter for enscript ".st" files.

    + add xml-filter based on html-filter.

    + add pot-filt.l, to highlight ".po" files.  Using sh-filt.l was
      not satisfactory since the quoting rules were not close enough.

    + add syntax filters and corresponding modes for assembler (GNU and M$),
      info and texinfo.

    + add -j option to c-filt.c, to implement some java-specific features
      such as "$" as part of an identifier, and \u escapes.

    + add un-filters (atr2ansi, atr2html, atr2text) which convert encoded
      control/A text to different forms.

    + modify spell.rc, spellflt.l and select.c to allow spell filter to
      work as a built-in filter.

    + modify built-in spell filter to work with encrypted files.

    + add a -t option to filters, to pass tabstop value.  Use this in
      makefilt.l to provide better highlighting of problems with leading
      whitespace.

    + modify manpage.rc to check if the current buffer is perl, and if so,
      to render contents using pod2man or pod2text.

    + set "vilemode" for [History] buffer.

    + reorder lex-based filters to allow building with flex 2.5.31, which
      introduces several incompatibilities with respect to flex 2.5.4
      and lex.

    + add configure check/warning for flex 2.5.31, which has broken support
      for the "-P" option used for built-in filters.

    Win32 changes:

    + implemented tilde-expansion on win32.  Actually it was present, but
      globbing did not work, and the environment variables did not match
      the Windows 2000 configuration.

    VMS changes:

    + filename matching is case-independent, allowing majormodes to be
      recognized.

July 2005,
    vile 9.5 is released.  Highlights since 9.4 (aside from bug fixes):

    General changes:

    + syntax filters can now be dynamically loaded.  This allows the
      main executable to be smaller, and is faster than external
      filters.  Loadable filters are configured using the
      "--with-loadable-filters" option to configure script.  This works
      for several platforms using gcc.

    + add configure script option for largefile support, change buffer
      size datatypes an unsigned type to allow for reading files larger
      than a signed value would allow.

    + modify historical-buffer to allow tab/back-tab to cycle through
      the first 9 buffers, solves the problem of seeing more than the
      first few possibilities on the message line.  Toggling with the
      repeated '_' selects the first buffer shown.

    + modify name-completion to allow completion of filenames containing
      a '$'.

    + relax a check in ":w" by checking if the given name differs from
      the current filename.  If so, do not require ":w!" to write a
      readonly file to a different location.  This allows one to reuse
      the filename history for ":w".

    + modify special treatment of "#" which prevents it from being
      shifted with ">>" by disabling that when cindent is unset.

    + add a few ex-commands:  nu, j!, wq!

    + modify statevars.c to make read/write of $title consistent, i.e.,
      will warn that it cannot be set in the termcap configuration.

    + modify [Messages] buffer so that it is only invisible, not a
      scratch buffer.  The latter makes it be automatically removed
      after viewing and closing the window.

    + add pattern for "ant" (Java make-program) to a few of the patterns
      in finderr.c

    + modify PromptAndSet() to allow a cancelled prompt for variable's
      value to store an ERROR token, which can be tested in scripts with
      &error.

    + split-out modes.rc from filters.rc to make configuration more
      flexible, e.g., for configure --disable-filters.

    + modify minubuffer editing to allow one to use ^Ga to toggle
      miniedit mode and append to the buffer shown from a previous
      command rather than having it erased.

    + modify name-completion for majormode names used as macro
      parameters to use the long name (with "mode" ending) rather than
      the short name, for consistency.

    + modify perl.xs to allow for $VILE_LIBDIR_PATH to be a list of
      paths.  Only add the corresponding xxx/perl names to @INC if they
      correspond to a real directory.

    + change minimum/maximum repeat counts for regular expressions from
      a byte to an integer.

    + modify interpretation of "~local", "~with", "~elsewith" and
      "~endwith" so they are within the normal "~if"/"~endif" hierarchy.

    + modify minibuffer editing to shift the display left/right as
      needed after doing the initial tab of a name-completion, in case
      that left the cursor position past the end of the line.

    + add experimental plugin support and example.

    Locale Improvements:

    + workaround for broken locale table on Solaris8 and Windows2000,
      etc., which shows tab as both as printable and a control
      character.  The ISO C standard states that control characters are
      not printable.

    + extend workaround for UTF-8 locale in termcap driver to translate
      UTF-8 input to Latin-1.

    + improve/extend checks for locales which correspond to 8-bit
      character encoding, resetting to POSIX locale (ASCII) if the
      nl_langinfo() function returns a value that does not look like
      ASCII or ISO-8859-x.  This change applies to the termcap/terminfo
      and X11 drivers.

    + show locale and encoding values in the header of the [Printable
      Chars] buffer.

    + add $encoding and $locale variables to show what vile's internal
      8-bit encoding and locale are set to.

    + turn on locale feature on win32

    New Commands:

    + add macro "which-menu" to which.rc, which shows the locations that
      xvile checks for a menu-file.

    + add macro "show-each-buffer" (file showeach.rc), which splits up
      the screen into equal chunks to display as many of the non-scratch
      buffers as possible.

    + add macro "which-filter" to show which locations would be checked
      for an external filter.  If the filter happens to be built-in,
      this is also noted, in the message line.

    + improve "eval" command, provide for mixture of functions and other
      tokens which are passed to the script interpreter.

    + modify SpellFilter macro to use the results from [Filter Messages]
      with the error-finder to step through the misspellings.

    + add macro "show-filtermsgs" to show syntax filter messages,
      setting the list to the error-buffer to provide simple stepping
      through the errors which are found.

    + add commands "popup-buffer" and "popdown-buffer", which open/close
      windows for the given buffer rather than changing the current
      window to show a different buffer.  The "popup-buffer" command is
      a wrapper for the existing logic used for help and similar
      commands.  The "popdown-buffer" command differs from
      "delete-window" by closing all windows for the given buffer.

    + add command "for-buffers", which performs the same command for the
      specified buffers.

    New Modes:

    + add "reader-policy" mode, which allows one to control whether vile
      will fall-back to line-by-line reading if it encounters an error.

    + add mode "for-buffers", which specifies whether kill-buffer (and
      for-buffers) command use globbing or regular expressions.

    + add "filtermsgs" mode, for built-in filters to report syntax
      errors into [Filter Messages] buffer so that one may use the error
      finder to locate these.

    + add mode "ignoresuffix", which tells vile to strip the given
      pattern from a filename before matching majormode suffixes against
      it.

    + add mode "showchar", which turns on a field in the modeline that
      tells what the character value is at the current editing position.

    New Variables and Functions:

    + add new operators to make it simpler for macros to check for
      features:  "&isa", "&classof" and "&mclass".

    + add "&match" and "&cmatch" functions for checking if a given
      regular expression matches a string.

    + add "$error-tabstop" variable, to allow changing the tabstop value
      used when interpreting "%C" results in the error finder.  Most
      programs assume 8, and that does not work well when editing
      buffers with other tabstops such as 4.

    + add "$goal-column" variable for debugging.

    Syntax Filters:

    + modify ".table" command in filters parsing to read the user's
      color definitions, e.g., from .vile.keywords, as is done in a
      ".source" command.

    + add a ".brief" to filters parsing, which uses "?" to match zero or
      all of the following characters, in contrast to ".abbrev" which
      uses "*" to match zero or more of the following characters.

    + several new majormodes, with corresponding syntax filters:

        + ".jsp" files are really (close to) a variety of HTML files.
          Add simple support for JSP in htmlfilt.l
        + add iss-, nsis- and ini-modes
        + add lispmode, to use vile-lisp-filt.
        + add nmakemode, for special cases such as M$'s ".dsp" files.
        + add syntax filter for AutoIt version 3 and majormode au3mode.
        + add syntax filters for iss- and ini-modes.
        + add vbsmode using ".vbs" suffix based on basmode.

    + extend suffixes for several majormodes:

        + add ".asp" to jspmode suffixes
        + add ".cls" filetype for vbmode, add symbols for Visual Basic
          class modules to vb.key
        + add ".dcl" filetype for dclmode.
        + add ".el" to suffixes for lispmode.
        + add ".hpp" to suffixes for cppmode.
        + add ".jad" suffix for javamode for Java Disassembler.
        + add ".mm" to nroff mode.
        + add ".ph" and ".pph" to esqlmode suffixes.
        + add ".shar" to shmode suffixes.
        + add ".termcap" and ".terminfo" suffixes for tcmode and timode
        + add ".tic" as a suffix for timode.
        + make "TODO" a txtmode file.
        + modify pattern for logmode to allow filenames such as gmake.out

    + add a mode-pathname setting for cppmode, so files under (for
      example) /usr/include/g++ will be treated as C++.  Newer C++
      headers have no suffixes.

    + add an "-s" option to c-filt.c, for JavaScript (to support
      jsmode).  Use this to control whether to allow regular expressions
      in certain cases.

    + modify ShowFormatted macro to support "-mm" macros.

    + modify spellflt.l to allow it to be used in winvile, using npopen,
      as a built-in filter.

    + rewrote pascal syntax filter in lex, adding highlighting for
      numbers, and TurboC, Delphi comments.

    + modify cppmode's suffixes to look for .C, .H and .CC only on
      systems where filenames are case-sensitive.

    + split up the majormode "suffixes" into suffixes, mode-filename and
      mode-pathname to make it clearer how to associated regular
      expressions with the filename for majormodes.

    + change highlighting for misspelled words to Error class.

    + add environment variable VILE_SPELL_FILT to vile-spell-filt, to
      allow overriding the compiled-in program and options used for
      performing the lookup.

    + many improvements to parsing and highlighting in existing filters
      (see CHANGES).

    X11 changes:

    + add --disable-imake option to configure script, from xterm.

    + modify xvile's wheelScrollAmount resource to scroll by pages if
      the resource value is negative.

    + revise lookup for xvile's menu file to look for dotnames in the
      current and home-directories, while non-dotnames may be found
      there and in $HOME/.vile and on $startup-path.  Combine this with
      changing the default for $menu-file back to ".vilemenu" as
      documented rather than "vilemenu.rc".  The latter name is used in
      the non-dotname locations if $menu-file is a dot-name.

    Win32 changes:

    + several changes to allow winvile to remember recent files and
      folders

      + winvile remembers up to 20 of the files it has recently
        opened/created (feature disabled by default).

      + winvile remembers up to 20 of the folders it has recently
        visited via an implicit or explicit cd (feature disabled by
        default).

      + Remembered files/folders are accessible and "replayable" from
        winvile's system menu.

      + Two new modes:  recent-folders and recent-files specify maximum
        number of folders/files that may appear in winvile's system
        menu.  Range is 0-20; a value of 0 disables feature.

      + Two new commands:  purge-recent-folders and purge-recent-files
        clear the list of folders/files that appear in winvile's system
        menu.

      + modes and commands work in console mode (minimizes conflicts
        when sharing a single vile.rc), but the files/folders that
        console vile accesses are _not_ remembered.

    + improve the winvile resize/status window:

      + make resize window wide enough to show geometries that exceed 99
        columns

      + make resize window continually center itself over the editor's
        frame (NT and XP only).

    + modify dequoting of winvile's command-line in ntwinio.c to allow
      for quoting to be within parameters, e.g.,

            winvile +"100" makefile

    + reenable SHIFT+INSERT in the win32 mini-buffer (for both vile.exe
      and winvile.exe).  Unfortunately, the cygwin shell eats
      SHIFT+INSERT for console vile (mini-buffer input only).  now, it's
      once again possible to:

            $ vile somefile
            /     <- search for string sitting on clipboard

    + modify environment variable lookup for win32 to look in the
      registry for the VILE* environment variables:

            VILEINIT
            VILE_HELP_FILE
            VILE_LIBDIR_PATH
            VILE_STARTUP_PATH
            VILE_ERROR_ABORT

      This change is made to make it more easily installable; Windows
      changes to environment variables apparently do not take effect
      until the machine is rebooted.  Registry changes take effect
      immediately.

    + add package script for winvile using Inno Setup.

    + improve cursor display in winvile:

        + when selecting text, show I-beam cursor.

        + when selecting a movable mode line, show a double-headed,
          north-south cursor.

        + when moving the mouse over a movable mode line, show a
          double-headed, north-south cursor.

    + don't allow mouse capture if the left mouse button is pressed in
      the area encompassing the editor's last two lines (message line
      and nonmovable mode line).  Don't allow mouse capture if the left
      mouse button is pressed on movable mode line.  Corrects
      long-standing winvile bugs.

    + add graphical change-directory to [win]vile via new command
      "wincd".  The graphical change-directory is also accessible via
      winvile's system menu and right mouse popup menu.

    + ensure that files created via winvile's "Save As" and vile's ":f"
      commands are remembered in winvile's "Recent Files" list.

    + make filename completion with cygwin ignore case.

    VMS changes:

    + add VMS mode record-attrs, modify logic in vms_creat() to use this
      information to make the default VFC files written from DCL
      editable.  Those use PRN (print file format) record attributes.

    + modify which.rc to use &pcat rather than $pathname-separator,
      since the latter is ambiguous on VMS.

    + modify infer_majormode() to work with VMS pathnames.

    + correct logic for VMS pathnames so that a directory buffer will,
      as on Unix, give the same buffer name as the directory leaf.

    + improve fakevms test-driver and related OPT_VMS_PATH code for VMS
      pathnames, making name-completion work for VMS pathnames on Unix.

    + modify catnap() function to use IEEE floating point on IA64, since
      that platform does not support F-floats.

    + modify vmsbuild.com and descrip.mms to work with IA64.

December 2007,
    vile 9.6 is released.  Highlights since 9.5 (aside from bug fixes):

    General changes:

    + implement basic support for Unicode (see Locale Improvements).

    + implement vi-style modeline, limited to setting buffer- and window-
      modes, or majormodes.

    + implement patterns as line-specifiers in ex-mode.

    + revised command-line option parsing to use scripting more effectively:

      + multiple startup files are allowed.

      + most command-line options are translated to their equivalent script
	and executed, rather than saving state for the most recent of each
	option.  This makes the -s, -S, -g, -G options obsolete (but still
	accepted).

      + add "-c" option (the POSIX form of "+").

    + disallow source'ing from the current directory if the source'd file
      might be writable by other users.

    + make mouse work for curses driver just like the termcap/terminfo
      driver.

    + improve majormodes for complex fences by initializing the (non-string)
      buffer mode values for submode groups according to the values in
      the submode.  This makes ignorecase work as expected in the complex
      fence matching for vbmode.

    + improve name-completion by saving/restoring the original window and
      buffer when [Completions] closes, rather than the closest window.

    + add named marks for decimal digits .

    + modify ":describe-bindings" to show whether the command accepts a
      range, and whether it is undoable.

    + correct comparisons used for handling bounds in regular expressions,
      e.g., the "2" in "\(this\|[l-m]\)\{2\}".

    + change behavior of regular expression OR'd alternatives - only the
      first match was used rather than the longest one.

    + modify "filename" shown in :show-filtermsgs to use the buffer name
      if no filename is available.

    Locale Improvements:

    + several changes to provide usable Unicode support:

      + add mode percent-utf8 to set a threshold for file-encoding mode
	"auto" detection of UTF-16/UTF-32 files.

      + file-encoding mode can be set to "auto", to detect UTF-16 files,
	which are loaded as UTF-8.

      + UTF-8 files are detected based on the file-encoding mode as well.

      + Unicode values are displayed (where no locale controls) as "\uXXXX"
	in 4 hexadecimal digits.

      + add unicode-as-hex mode to override locale, forcing Unicode values
	to display as "\uXXXX".

      + for buffers with UTF-8 encoding, show illegal bytes as "\?XX".

      + Unicode values can be inserted into buffers using ^VuXXXX form.

      + modify manfilt.c to provide UTF-8 output in a UTF-8 locale.

      Limitations:

      + terminal drivers support Unicode display in varying degrees:

	+ winvile - multicolumn characters, depends on font selection

	+ termcap/terminfo - relies on terminal emulator, knows about
	  multicolumn characters

	+ xvile - displays only single-column characters

	+ curses - depends on the curses library, e.g., ncursesw

	+ win32 console - not yet implemented

      + combining characters are not combined.

      + registers hold byte data, will show the UTF-8 encoding for data
	rather than a \uXXXX (unless the file-encoding for [Registers]
	is changed).

      + some "characters" such as the report for yanked text is still
	really a byte-count.

      + inserting a \uXXXX into the minibuffer will display the UTF-8
	encoding.

      + regular expressions are not wide-character aware.

      + UTF-16 and UTF-32 files are detected based on BOM and/or the
	contents of the first line of the file.

      + external syntax filters do not handle BOM or UTF-16, UTF-32.

    + add character classes [:ident:], [:octal:] and [:path:], and change
      the association of \w and \W to [:ident:], making [:alnum:] no longer
      include "_".

    + modify regexp.c so tab is not matched by \p or [[:print:]] for
      consistency with POSIX regular expressions.

    New Commands:

    + add rename-other-buffer command, use that to modify spell.rc so it
      can work with scratch buffers which otherwise would be lost, e.g.,
      "[Help]".

    + add "describe-&functions" and "describe-$variables" commands.

    + add ":goto-percent" command.

    + add (nvi/vim) ex-commands: a!, c!, i!

    + add ":c" as alias for ":change-til" (nvi/vim).

    New Modes:

    + UTF-8 is supported via new modes "byteorder-mark" and
      "file-encoding"

    + add mode xterm-fkeys, to allow termcap driver to generate
      shift/control/alt modifiers for function keys.

    + add "rectangle-insert-mode".

    + add "showvariables" mode, for testing expressions used in [Variables].

    + add "echo-to-clipboard" mode for Win32 hosts:
      all text selected with the mouse is automatically
      copied to the Windows clipboard.

    + add "bufname-expr", "identifier-expr" and "pathname-expr" buffer modes to
      provide regular expression parsing of $bufname, $identifier and $pathname
      in the show-variables command as well as for the related expansion of
      tokens from the cursor position.  If the expressions are empty, the code
      falls through to use the corresponding older character-class parsing.
      Default values are provided for each *-expr mode.

    + add cursor-tokens mode to control whether vile uses regular
      expressions, character classes or a combination to obtain tokens
      from the screen.

    New Variables and Functions:

    + add new symbols "$return" and "$_" which can be used to implement simple
      functions .

    + add "%n" and "%N" substitutions for $title-format

    + change "%n" in modeline substitutions to use file name (pathleaf)
      rather than relative path (shorten_path).  Use "%r" for the latter.

    + add ">motion" function for scripts.

    + add $buf-fname-expr to show the combined bufname-expr, pathname-expr
      used to interpret ^X-e.

    + improve handling of enumerated values by forcing all to lowercase,
      e.g., to eliminate the need for the special case in 9.1x to handle
      "TRUE" and "true".

    + update title when doing a "cd", in case it uses %r substitution.

    Syntax Filters:

    + modify syntax filters to use flex's character classes.

    + add configure check for lex's which support character classes, and
      add filters/noclass.sh to work around those which do not.

    + several new majormodes, with corresponding syntax filters:

	+ add confmode for "ordinary" config-files.
	+ add csmode (for C# ".cs" files).
	+ add csvmode for ".csv" files.
	+ add delphi mode
	+ add docbookmode
	+ add lua mode
	+ add mcrlmode for mCRL/mCRL2 modeling language.
	+ add midlmode, for Microsoft IDL.
	+ add rtfmode for RTF files.
	+ add wbtmode for WinBatch.
	+ add xpmmode
	+ add majormodes for bnf, css, php

    + extend suffixes for several majormodes:

	+ add ".ebuild" suffix for shmode.

	+ modify preamble for xml- and html-modes to ensure that the first
	  tag determines the type.

	+ add output from rcshist to diffmode.

	+ add ".vbp" files to inimode.

	+ add ".reg" files to inimode.

	+ add ".ddl" suffix to sqlmode.

	+ add ".dsr" suffix to vbmode.

	+ add several package-related suffixes to sqlmode.

    Other improvements to majormodes:

    + modify majormode inferencing to check preamble for [Standard Input]
      and [Output] buffers.

    + modify preamble patterns for shell modes such as awk, etc., to allow
      for programs without an absolute pathname, e.g., "#! awk".

    + improved cppmode's identifier-expr.

    + updated python keywords

    + improve bas-filt.l by not highlighting incidental matches in the
      attribute section of a Visual Basic form-file.

    + add section definitions to vbmode.

    + add complex fences to vbmode.

    + improve vl-filt.l based on Verilog LRM draft

    + fill in complete list of event names for xres.key from Xt/TMParse.c

    + fix sh-filt.l for parameter substitutions containing an escaped
      quote, e.g.,
	    VERSION=${VERSION#*VERSION \"}
	    VERSION=${VERSION%\"*}

    + change htmlfilt.l to highlight character- and URI-references as
      numbers to make them distinct from strings with ordinary text.

    + add "+", ",", "&", "@" and ";" to URL patterns in filters.

    + fixes for termcap syntax highlighter, i.e., tcmode:
      + allow description field to be empty
      + color the "|" between aliases.
      + improve string- and escape-parsing

    + fixes for terminfo syntax highlighter, i.e., timode:
      + allow description field to be empty
      + color the "|" between aliases.
      + allow aliases to contain blanks.

    + add check in m4-filt.c for unbalanced quote, show the affected area
      as an error.

    + several improvements and fixes to lex-filt.l (a rewrite which
      makes it very complete, however it now requires flex).

    + minor fixes to make most of the lex filters build with "old" lex,

    + make autocolor work for curses-driver, e.g., --with-screen=ncurses

    + improve vilefilt.l, highlighting mode names and displaying error
      for unknown mode, function and state variables.

    + modify spellflt.l to chop words according to Camel-case, so
      tokens such as "ChopWords" are treated by the spell checker as
      multiple words.

    + modify spell- and txt-filters to allow users to add words to their
      respective ".keywords" files to override the builtin highlighting.

    + make ShowFormatted macro more configurable by allowing environment
      variables $VILE_NROFF_FILT and $VILE_TABLE_FILT to override the
      choice of programs therein.

    X11 changes:

    + add -class option to xvile.

    + make cursor-adjustment after paste in xvile dependent on whether the
      pasted text ended with a newline.

    Win32 changes:

    + change winvile's registry subkey for recent-folders and recent-files
      to match environment variable settings from 9.4r, e.g., change
	    "Software\winvile\MRUFiles"
      to
	    "Software\VI Like Emacs\MRUFiles"

    + modify winvile's command-line parsing, adding "-i" option to perform
      the case used for "Send To": use the part of the command line after
      options as the filename and change working directory to match.

    + improve paste-performance in winvile by passing whole-line chunks
      to the insert-function.

    + improve repainting in winvile while processing external command.
      also modify keyboard handling to provide type-ahead while processing
      external command.

    + correct order of evaluation from 9.4w when setting record-separator,
      which was setting "crlf" ending temporarily when computing the buffer
      size, even when "lf" was intended.  That would cause an immediate
      write from winvile (without change) for a buffer to write too many
      characters.

    + add a character-class check to find_b_file() to prevent names such
      as "" from being canonicalized into "vile.1" on win32 via
      FindFirstFile().  This fixes a problem where ^X-n would sometimes
      display the wrong buffer.

    + add shifted-cursor-key bindings for winvile, like xterm.

    + add KEY_xxx definitions to OS/2 and Win32 drivers, defining up to
      KEY_F35 for the former and KEY_F24 for the latter .

    + add &pquote in manpage.rc, to allow it to format html output when
      vile-manfilt, etc., reside in directories containing spaces in their
      name.

    + correct check of return of ffread() in spellflt.l's workaround for
      platforms such as win32 which have no usable popen().  That made
      spelling checks require two ^X-i presses.

    + modify ntwinio.c to invoke build_recent_file_and_folder_menus() in
      the WM_INITMENUPOPUP event rather than WM_SYSCOMMAND.  This makes
      winvile initialize the recent-folders and recent-files if one uses a
      right-click on the title of the window.

    + modify spell filter so that it can get VILE_SPELL_FILT from the
      registry on win32.

    + improved winvile's "flash".

    + fixes for 64-bit warnings of Visual Studio .NET 2003

    + modify wvwrap.exe to work with pathnames containing "$", "&" and "'".

    + improve winvile.iss (Inno Setup):
      + use values in patchlev.h to set the package version information.
      + add context menu and Send To shortcuts
      + install the keyword files

    VMS changes:

    + minor build-fixes for VMS:

      + modify vmsbuild.com to simplify workaround for broken MMS 3.8

      + provide dummy variables for xvile to reflect modularization changes
	with respect to vmsvt.c

    + move VMS-specific code from termio.c to vmsvt.c

    Other portability:

    + use va_copy() in dofmt() to work with Linux on powerpc

    + modify configure script to omit lex-filt.l from build if lex is not
      really flex, since the tables are too large for the older program.

    + improve os2vio.c, adding a check to distinguish between fullscreen
      and VIO to allow using bright background colors in the latter .

    + modified regexp.c, add headers vl_regex.h, vl_alloc.h and vl_ctype.h
      to allow it to be easily built outside vile .

    + add KEY_BackTab to the output of show-key-names

    + fix kcod2prc() so that a shifted-tab is converted to "Shift+^I"
      rather than emitting a literal tab in the result.

    Performance:

    + modify the symbol-table lookup in filters.c to use tsearch() when
      available.  For an 8Mb rtf file this improved performance by about
      a factor of two (on Linux - Visual C++ has no tsearch).

    + use new module blist (binary search of lists) to reduce linear
      searches in the places where btree is not already used.

    + add configure check for getc_unlocked(), putc_unlocked() and
      tsearch() to use in performance improvements for syntax filters.

June 2008,
    vile 9.7 is released.  While the goal for this release is to fix
    regressions and new bugs since 9.5; there are some new/modified features. 
    Highlights since 9.6 (aside from build- and bug-fixes):

    General changes:

	+ modify prompt for new mode value to consistently show the mode's full
	  name.

	+ modify wrapmargin mode to use negative values as a count from the
	  left of the screen.

	+ modify behavior of ":ww!" to act like ":w!", allowing it to write
	  all files.

	+ trim trailing blanks from text handled in modelines in case there
	  was a ^M.

	+ modify treatment of ":setl dos" to behave the same as ":set-dos".
	  That makes it possible to put a "vile:dos" in a modeline and make
	  vile convert the line-endings.

	+ flush the standard output before writing version message using the
	  standard error, in case there was some output pending.

	+ modify curses-driver to avoid a curses-refresh (repainting the
	  whole screen) between a shell command and the "Press return to
	  continue" message.

	+ improved scripting, making it simpler to save a boolean mode-value in
	  a variable and restore it by assignment.

    Locale Improvements:

	+ improve locale initialization, checking if there is no installed
	  narrow locale corresponding to the given (wide) locale.  In that
	  case, default to either ISO-8859-1 or ASCII, depending on whether
	  there was actually a wide locale whose encoding is UTF-8 or
	  ISO-8859-1, or neither.

	+ force the [Printable Chars] buffer to use file-encoding=8bit,
	  makes it display consistently legal codes in the second column.

	+ make ISO-8859-1 data display consistently in UTF-8 buffer as "\?xx".

	+ provide workaround for systems without nl_langinfo(CODESET)).

	+ make transpose-characters work for wide-characters.

	+ make "~" (flip-character) and related case-conversion work for
	  Unicode in 0..255 range.

    New Commands:

	none

    New Modes:

	+ modify mktbls to allow special-case alias for modes which have no
	  convenient abbreviation.

	+ add "fk" alias for file-encoding mode.

	+ add a "locale" value for file-encoding, use that as the default.

    New Variables and Functions:

	+ add $buf-encoding symbol, to show the actual encoding used by the
	  current buffer vs the file-encoding which is one of vile's internal
	  names such as "8bit" or "locale".

    Syntax Filters:

	+ modify parsing of keyword files to accept an empty parameter for
	  "abbrev" and "brief", to disable the "*" and "?" feature.

	+ remove obsolete lex-filters for perl and ruby (only the C versions
	  have been supported).

	+ improved lisp filter:

	  + change class color of parentheses to "Action" to make them easier
	    to distinguish from "String".

	  + color binary, octal and hexadecimal constants, as well as parse
	    the "#\" patterns.

	+ improved perl syntax filter:

	  + make perlpod sections more readable by highlighting the control
	    lines.

	  + add double-quote to quote-delimitors.

	  + show interpreted symbols in double-quoted regular expressions.

	  + if "/e" modifier is set for regular expression, show interpreted
	    symbols for that.

	  + show regular expression modifiers in keyword-attribute, not string

	  + color &foo as a variable.

	  + color both class and member in variables such as $foo::bar

	  + add ".t" to perlmode, using $mode-pathname

	+ improved ruby syntax filter:

	  + match keywords containing '!' '?' and '=' depending on the context.

	  + remove unmatchable characters from the list of those matched
	    following $. 

	  + change the instance variable matching to @@?{KEYWORD} instead of
	    @+{KEYWORD}. 

          + highlight constants (keywords beginning with a capital) with    
            the Type attribute. 

	  + highlight binary integers (such as 0b10101).

	  + disable "*" and "?" abbreviation feature in ruby.key, allowing
	    match of "defined?", etc.

        Other improvements to filters:

	  + make vile's symbol-tables accessible to vilemode in winvile.

	  + minor improvement to vbmode's fence-if to ignore lines with
	    continuations.

	  + improve here-document parsing in sh-filt.l to work with "words"
	    which contain blanks.

    Other improvements to majormodes:

	+ strip redundant "mode" from majormode names, avoiding the potential
	  for creating foomodemode when the script says
		  define-majormode foomode

	+ remove ".scm" from c-suffixes pattern.

	+ add schememode.

    X11 changes:

	+ update input-method code, from xterm.

	+ add xvile resource setting "openIm" to control whether it tries to
	  open input-method.

	+ improved handling of runtime X errors, xvile will attempt to save
	  buffers.

    Win32 changes:

	+ simplify wvlwrap.exe by disabling globbing temporarily.  This allows
	  opening files whose names contain square brackets. 

	+ suppress part of wildcard expansion in call to expand_wild_args(),
	  e.g., for command-line of winvile, since that interferes with
	  reading files whose names contain square brackets.

    VMS changes:

	none

    Other portability:

	+ improve configure checks for iconv.

    Performance:

	none

August 2010,
    vile 9.8 is released.  The goal of this release is to fill in the remainder
    of the UTF-8 support.

    Highlights since 9.7 (aside from build- and bug-fixes):

    General changes:

	+ many improvements to UTF-8, for regular expressions and input.

	+ implement user-definable operators

	+ vile.hlp and all ".doc" plain-text files are generated from html.

	  http://invisible-island.net/vile/vile-toc.html

	+ highlight matches in which-keywords, etc., and put a hyperlink on the
	  highlighted text to view the corresponding file.

	+ add a brief mode format "%M" for modeline-format

	+ improve checks for insecure file permissions.

	+ improve which-source and which-exec commands, showing which files
	  fail the checks for insecure permissions.

	+ new configure script options:

	  + --with-symlink, which augments --program-suffix to make it
	    simple(r) to install versioned binaries.

	  + options for transforming program name upon install:
	    -- program-prefix, --program-suffix, --program-transform-name

    Locale Improvements:

	+ add environment variable VILE_LOCALE_MAPPING to help with special
	  cases of associating wide/narrow locales, e.g., where the narrow
	  locale is only available under a non-empty suffix.

	+ regular expressions support character classes for UTF-8.

	+ regular expressions support \< and \> markers for UTF-8.

	+ format-til, lower-til, upper-til and flip-til work with UTF-8

	+ xvile uses \uXXXX format when the font does not contain a glyph for a
	  given character.

	+ accept ^VUddddd input for Unicode in decimal (base ten).

    New Commands:

	+ new command-line option "-F" tells vile to only run the syntax
	  filters for the given files, writing the attributed text to the
	  standard output.  Used this option to highlight the code-examples in
	  vile's html and documentation.

	+ added several "list-XXX" aliases to match "show-XXX" commands, for
	  consistency.

	+ "append-number", "insert-number", "overwrite-number" commands work
	  with characters entered as numbers.

	+ "define-menu-entry" modifies xvile menu entries.

	+ "set-extra-colors" allows setting extra colors for special buffers
	  such as [Settings].

	+ "show-filtercolors" macro shows the class names and their colors for
	  the current majormode.

	+ "show-extra-colors" shows classes and colors modified by
	  "set-extra-colors".

	+ "show-local-modes" is an easier-to-remember variation for the
	  count+"show-modes" combination.

	+ "show-undo-stack" shows the contents of the undo-stack.

	+ "show-wide-printable" provides a way to see details for other "pages"
	  than the ASCII/Latin-1 0-255 code.

	+ "store-operator" stores a macro which is treated as an operator.

    New Modes:

	+ "spaces-after-sentence" is now a buffer mode, to allow it to be part
	  of a majormode.

	+ "check-access" makes the check for insecure file-permissions
	  configurable by the user.

	+ "percent-autocolor" can be used to override the autocolor mode for
	  very large files.

	+ "reuse-position" allows users to specify that vile should restore the
	  current line/column position when (re)displaying a scratch buffer
	  built with liststuff.

    New Variables and Functions:

	+ &bchanged, &fchanged and state variables $bchanged (same as
	  $modified) and $fchanged make it simpler for scripts to check if
	  buffer/file timestamps differ.

	+ $cfgopts now shows drivers (ansi, borland, ntcons, ntwin, os2vio,
	  vmsvt) and other useful settings (iconv, multibyte).

	+ $cmd-encoding variable allows control of minibuffer's encoding

	+ $cmd-motion variable is used in user-defined operators.

	+ $font is always available, but readonly for non-GUI configurations.

	+ $kill-size and $kill-limit variables to improve scripting with the
	  $kill variable.

	+ $latin1-expr variable specifies whether a derived narrow locale
	  really has Latin1 (ISO-8859-1) encoding.

	+ $modeline-limit limits the offset into each line that vile scans for
	  modelines.

	+ $term-cols, $term-lines and $term-resizes give the terminal
	  dimensions, and tell if it is in a resizable window.

	+ $title-encoding controls whether vile 8-bit or UTF-8 encoding is used
	  when setting xterm title.

    Syntax Filters:

	+ new "-c" option to vile-key-filt tells it to display tokens in their
	  final color rather than based on syntax.

	+ new "-Q" option for all syntax filters makes the filter write a
	  ".keyword" table to stderr to show the effect of the "-k" option.

	+ extend syntax keyword parsing to allow flags to be set for each
	  keyword, e.g., to mark keywords that are used to delimit comments.

	+ vile-awk-filt improvements

	  + highlight inline comments.

	  + highlight regular expression used as parameter, e.g., in sub().

	  + change $0, etc., to Ident2 class for consistency with other
filters.

	  + highlight some cases of unbalanced right-parenthesis or
	    curly-braces.

	  + correct DSTRING expression, to handle "\\\\" value.

	  + accept literal spaces in patterns.

	+ vile-basic-filt improvements

	  + allow continuation marker in comments

	  + support .NET-style preprocessor directives.

	+ vile-ecl-filt (ECLiPSe/Prolog)

	  + fix typo in STARTQUERY pattern

	  + parse based-numbers.

	  + highlight strings and numbers.

	+ vile-html-filt improvements

	  + "<%" "%>" are recognized anywhere - not just outside tags.

	  + ensure that "server" is the tag, not one of the named values, e.g.,
	    "" vs "".

	  + use language value in script tag, e.g., to handle C# scripts.

	  + modify check for language value to accept anything beginning
	    "javascript", e.g., "javascript1.1".

	  + check for "src" property in script tag before deciding whether to
	    use JavaScript keywords.

	  + create separate table "htmlprop" for HTML properties.

	  + highlight CSS embedded in HTML.

	+ vile-lisp-filt (also for scheme filter)

	  + highlight quasiquote/backtick (`), quote ('), unquote (,) and
	    unquote-splice (,@), including unquoted sub-expressions.

	  + highlight the parentheses of quoted expressions in a different
	    color.

	+ vile-php-filt improvements

	  + identifiers may begin with "_".

	  + color heredocs and nowdocs

	  + color comments beginning with "#".

	  + add preamble pattern for phpmode.

	+ nroff filter allows for macro-names to be used for fonts.

	+ spell filter now uses $TMPDIR rather than putting its temporary files
	  in the current directory.

	+ vile-rpm-filter improvements:

	  + recognize keywords ending with digits, such as "Source0".

	  + distinguish one-liner tags from multi-line sections.

	  + ignore case of keywords.

	  + add keywords for %XXX variants of %{XXX} names.

	  + highlight %XXX words in single-quotes.

	+ vile-ruby-filt now handles stacked here-documents.

	+ vile-scheme-filt

	  + handle combinations of quotation literals.

	  + highlight the unquote/unquote-splicing keywords.

	  + handle the optional scheme parentheses extension ('[' and ']').

	+ vile-sh-filt

	  + handle "${number}", "$(commands)", "$((expression))",
	    "${name#value}", etc.

	  + handle escape character in here-document.

	+ vile-sql-filt improvements:

	  + allow host variables in LEAD state.

	  + improve parsing of "@" character.

	  + allow newlines inside quoted strings.

	+ vile-vile-filt improvements:

	  + display numeric codes following a control/V as in a map-command as
	    numbers or errors if fewer digits were found than expected

	+ vile-yacc-filt improvements:

	  + highlight all of the terminal symbols with "Terminal" class.

	  + modify keyword ".merge" directive to make it distinct from
	    ".source".  The former reads without modifying the table name, the
	    latter builds a new table.  Use this feature in the yacc syntax
	    filter to keep the terminal names and C keywords separate.

	+ vile-xml-filt improvements:

	  + use the prefixes defined by xmlns properties to select different
	    symbol tables.

	  + modify the way keywords are loaded, to support multiple symbol
	    tables defined via the keyword files using the ".include" feature.

    Other improvements to majormodes:

	+ lots of new file suffixes added to existing modes, of course.

	+ new majormodes:

	  + "ant" and "mvn" (maven)

	  + asp

	  + dtd

	  + haskell

	  + mailcap

	  + objc (objective-c)

	  + vb6

	  + xq (XQuery)

	  + xsl

	+ add option for C# verbatim string literals to c-filter.c

	+ add to diffmode's preamble pattern to allow it to detect diff's in a
	  piped input.

	+ vbmode and vb6mode provide try-bloc,, "with" and "select" complex
	  fences.

	+ yacc.key updated to bison 2.4.1 and byacc 20100610.

	+ modify xresmode to include shell-output from appres, e.g., ^X!appres
		XTerm

	+ modify preamble settings for majormodes of the form "#!path" to make
	  them more distinct.

    X11 changes:

	+ add lxvile wrapper for xvile, which chooses a font based on locale
	  setting

	+ add uxvile script, based on uxterm.

	+ vilemenu.rc lists fonts used in uxterm for the set of ordinary fonts
	  if the $term-encoding is utf-8.

	+ vilemenu.rc is scriptable; use this to work with the --disable-shell
	  configuration by omitting menu entries which use shell features.

	+ vilemenu.rc provides a default-font entry, to restore the font to
	  whatever was given in a -fn option, or resource setting.

	+ XVile.ad now matches Debian package.

	+ handle XA_COMPOUND_TEXT and XA_UTF8_STRING selection types.

	+ use Xutf8LookupString for input of UTF-8 key-events, if available.

	+ RPM spec file configures xvile to provide menu support.

	+ RPM spec file now installs uxvile.

    Win32 changes:

	+ winvile supports Unicode select/paste.

	+ modify winvile installer to optionally refrain from putting the newly
	  installed directories first in $VILE_STARTUP_PATH, etc., if they
	  already exist in the given path.  That allows one to have vile.rc in
	  the first path, e.g.,

		c:\vile;c:\program files\vi like emacs

	+ winvile "-i" option now saves the original command string, so
	  filenames with embedded blanks now longer need quotes.

	+ change Inno Setup script to install html files rather than doc files
	  for documentation; added a shortcut to the table of contents.

	+ UNC-paths are recognized with Cygwin.

	+ modify configure script, etc., to build "minvile" and "convile"
	  flavors using MinGW.

	+ implement quick-launch rule in winvile.iss script.

	+ DJGPP version provides syntax highlighting.

	+ borland.c (used for DJGPP) now tabuluates the shift/control/alt
	  flavors of cursor- and function-keys, defining function keys up to
	  48.

    Terminal drivers:

	+ ansi driver supports color syntax highlighting.

	+ curses driver supports color-schemes.

	+ improve configuration/initialization of curses-driver to ensure that
	  no attempt is made to display UTF-8 using 8-bit curses.

	+ modeline formatting supports UTF-8 filenames.

	+ xterm-fkeys improvement:

	  + checks for existence of shifted cursor- and editing-keys when the
	    unshifted keys do not use CSI format.

	  + recognizes either form of CSI

	+ use xterm patch #251 feature for saving/restoring title in termcap
	  and curses drivers.

    Other portability:

	+ add configure check for utf8 library, needed for some platforms to
	  use iconv library.

	+ add configure check for SIGWINCH, to fix resizing on OS X

	+ optionally use rpath feature to simplify linking against libraries in
	  nonstandard locations.

	+ use pkg-config for X libraries, if available.

	+ encryption feature works with 64-bit platforms.

    Performance:

	+ improve performance for show-variables and describe-bindings.

	+ improve performance for displaying syntax highlighting of very long
	  lines by using a fast check on the left/right limits of single-line
	  regions that could be displayed, and ignoring attributed regions past
	  those bounds.

	+ improve performance of on-the-fly UTF-8 regular expressions by
	  inlining and making checks to see if a byte is ASCII before doing
	  conversions.

-------------------------------
$Id: README,v 1.107 2020/01/17 23:29:40 tom Exp $
-------------------------------
vile-9.8v/README.PC000066400000000000000000000256101415556424100137130ustar00rootroot00000000000000                          --------------------
                          Running vile on a PC
                          --------------------

vile can be built for DOS, OS/2, Windows NT/2K/XP or Win9x/ME. 
additionally, precompiled binaries are available at vile's ftp sites
(refer to the README file for URLs).

the precompiled binaries have an obvious advantage:  you don't build vile,
which avoids the hassle of acquiring an "exotic" and/or expensive compiler.
on the flip side, some PC environments include multiple build options that
configure major editor features.  consequently, if you don't build vile,
you have no control of the resultant feature set.

General installation instructions
---------------------------------
installation of vile's PC components is the responsibility of the end user.
put another way, _none_ of the PC makefiles include install targets and
_none_ of the precompiled binaries include self-extracting setup programs.

Installing the precompiled binaries
-----------------------------------
1) unpack the appropriate compressed archive obtained from an ftp site.
2) copy all executables and the file vile.hlp to a directory in your PATH.

Installing after a build
------------------------
1) build the editor using the hints/information supplied below.
2) copy all resultant executables (except mktbls.exe) and the file vile.hlp
   to a directory in your PATH.

Creating a startup file
-----------------------
most users will configure the editor.  this is accomplished by creating a
startup file, called "vile.rc", and adding various settings and macros as
described in vile.hlp .  vile searches for the startup file in these
locations (and in the order listed):

	1 - current working directory
	2 - directory specified by $HOME
	3 - vile executable directory
	4 - each directory specified in $VILE_STARTUP_PATH.  If
	    this environment variable is not set, the following
	    defaults are internally assumed:

		/sys/public;/usr/bin;/bin;/

	5 - each directory specified in:

		$PATH
		$VILE_LIBDIR_PATH

Syntax coloring
---------------
syntax coloring works well on win32 hosts and everyone wants it :-) .
configuration of this feature is described step-by-step in these vile.hlp
topics:  "Color basics" and "Syntax coloring" .

the remainder of this file describes build requirements for various PC
environments.

DOS information
---------------
under DOS, you're best off using a DOS extender of some kind.  either
the Watcom or DJGPP compiler suites may be used -- DJGPP gives you a
faster executable, but the Watcom compiler is about 10 times faster.
you can use Turbo or Borland C as well, but neither of those support an
extender, so you end up only being able to edit files that fit in memory.
if you do this, be sure to '#define SMALLER 1' in estruct.h, to save as
much code space as possible.

if you build with Watcom, you'll need to have both vile.exe and dos4gw.exe
in your path to run vile.

if you build with DJGPP, you'll need to have both vile.exe and go32.exe
in your path to run vile.  newer versions of DJGPP may rely on DPMI, and
you might need cwsdpmi.exe instead of go32.  experiment.  have fun!

let me know about bugs/oddities when you use vile on a PC -- i probably don't
use it as much as you do.

(it's quite possible that the DOS makefiles are a little out of date --
refer to the UNIX makefile (makefile.in) for correct current list of source
and object files.)

oh -- there are three possible screen drivers in the source distribution
that should work, with varying degrees of success:

	borland.c (need #define BORLAND in estruct.h or makefile): this
		uses the "conio" routines that come with Turbo C or Borland
		C++.  Again, the trouble with this under DOS is that the
		Borland compilers don't produce a dos-extender 32 bit app,
		so you're _severely_ limited as to filesize.  but the DJGPP
		libraries emulate the borland screen i/o routines, so this
		screen driver is used there as well.

	ansi.c (need #define ANSI in estruct.h or makefile):  uses ANSI.SYS.
		it relies on the ansi driver for its cursor/scrolling/color
		services.  if you can change the resolution of your screen (to
		43 or 50 line mode) with your ansi driver, just use the
		"screen-rows" and/or "screen-columns" vile commands to make its
		idea of the size match your physical screen, and you'll be all
		set.  (i've only tested it with a free/public replacement
		program called NNANSI.  i got my copy from a simtel mirror.  i
		can probably find you a copy if you need it.)


OS/2 information
----------------
i believe vile can be built with the Borland compiler, or IBM CSET. be
aware that vile is NOT a PM program.  the two builds use the borland.c
or os2vio.c screen drivers, respectively.  with vile 7.3, an EMX port
is supported (for comparison, since OS/2 VIO performs much better).

we build the VIO version for the ftp downloads with IBM CSET, and the
associate nmake utility.

the makefile.emx (and associated config.emx file) are used for building
with a minimal EMX environment.  you need gcc for this.  however, for
best results in EMX, you should build with the autoconf version and
ncurses.  this requires a number of tools:

	+ you will have to regenerate the configure script, using
	  autoconf 2.13, with the patches from

	  http://invisible-island.net/autoconf/autoconf.html

	+ you'll need ksh (build or obtain a copy of pdksh 5.2.13 or
	  better).

	+ GNU m4 (needed for autoconf), and sed.

the termcap library distributed with EMX does not work well.  use ncurses:

	+ ncurses 4.2 or later, with patches through September 1998, from

	  http://invisible-island.net/ncurses/ncurses.faq.html
	  ftp://ftp.invisible-island.net/ncurses/

	+ use '$TERM=ansi', or start customizing from that.

WIN32 information (Windows NT/2K/XP and 9x/ME)
----------------------------------------------
either Visual C++ (4.x or later) or the Borland compiler can be used.  use
makefile.wnt with VC++ and makefile.blc with Borland's compiler.  with
respect to the console-mode port (vile.exe), the screen driver is
ntconio.c .  Both makefiles build vile.exe by default.

additionally, makefile.wnt builds a handful of C-based syntax coloring
filters.  many additional filters can be compiled and linked if lex or flex
are available, as described below.  refer to the help file topic "Syntax
coloring" for a description of these filters and their integration with the
editor.

as of vile 7.3, a gui called "winvile" is provided (screen driver is
ntwinio.c), which continues to improve with successive releases of the
editor.  currently, winvile may only be built with makefile.wnt (i.e.,
only with VC++).

as of vile 8.0, an embedded perl interpreter may be optionally included
with the console or gui versions of the editor.  again, this feature is
only accessible via makefile.wnt .  if perl has been installed on your
desktop, vile's perl API documentation can be extracted from the source
distribution with this nmake command:

    nmake -f makefile.wnt vile-perl-api.doc

as of vile 8.1, winvile may be built with optional OLE automation support,
which is described in the file doc/oleauto.doc .  additionally, a DLL called
visvile.dll can be built and installed as a Developer Studio add-in.  this
add-in substitutes winvile as the default Developer Studio editor for
many common editing tasks.  refer to the file doc/visvile.doc for further
information, including build instructions.

the following table summarizes the most significant makefile.wnt build
options:

component option(s)   required nmake command-line [1]
========= =========   ===============================
vile            nmake -f makefile.wnt
vile      perl    [2] nmake -f makefile.wnt CFG=vile-with-perl
winvile         nmake -f makefile.wnt CFG=winvile
winvile   perl        nmake -f makefile.wnt CFG=winvile-with-perl
winvile   ole         nmake -f makefile.wnt CFG=winvile OPT=ole-auto
winvile   perl,ole[2] nmake -f makefile.wnt CFG=winvile-with-perl OPT=ole-auto

[1] by default, all builds cd into the filters subdirectory and compile and
    link a handful of C-based syntax coloring filters.  to build _all_ of
    the editor's supported filters, acquire a copy of flex (or lex),
    install it in a directory located in your PATH and add the following
    command-line option:

        nmake -f makefile.wnt  FLT=1 LEX=flex  # or LEX=lex

    take note that flex is a component of cygwin's GNU emulation package
    and works quite well for this purpose.  cygwin can be obtained from
    Redhat at http://sources.redhat.com/cygwin.  the FLT option binds
    all syntax coloring filters into the resultant [win]vile executable.

[2] this option requires prior installation of perl.  refer to the section
    entitled "Perl preconditions" below.


More about makefile.wnt
-----------------------
this makefile builds the editor from the command-line, _not_ from Developer
Studio.  however, selected environment variables _must_ be set before
any VC++ tool can be used (this includes nmake, cl, link, etc.).
fortunately, microsoft supplies the file vcvars32.bat, in the Dev Studio
bin directory, to set these variables.  you'll probably want to examine and
edit this .bat file before using it for the first time because it usually
modifies the PATH to include the PC's CD-ROM drive (not nice at all!).
given all of this information, here's how to build the editor using the
MS developer tools:

a) open a dos box
b) cd to the vile source directory
c) run this command to initialize Dev Studio env vars:

   \bin\vcvars32

d) use one of the nmake command-lines shown above

Perl preconditions
------------------
before building vile with an embedded perl interpreter:

1) install a complete Win32 perl distribution[*] from this URL:

       http://www.perl.com/CPAN-local/ports/win32/Standard/x86/

   Included in this distribution, among many other items, is a required DLL
   (perl.dll) and the usual perl packages.

2) initialize the environment variable VILE_LIBDIR_PATH to point to a
   writable "root" directory where vile's perl scripts will be installed.

[*] Choose either a precompiled version of perl or build it yourself from
    source.  In this context, a "complete" distribution includes the perl
    interpreter and all "standard" packages, modules, and libraries.

note 1: one of CPAN's popular perl binary releases did not export an
important symbol.  this omission has been handled in vile's sources, but
there is a nontrivial performance impact associated with the workaround.
search for the symbol HAVE_BROKEN_PERL_RS in makefile.wnt to see if your
version of perl is affected.

note 2: the ActiveState port of perl is not compatible with vile's
internal perl API--older versions won't link/compile and newer versions
crash the editor.

--------------------------------------------------------
tom dickey, dickey@invisible-island.net

--------------------------------------------------------
paul fox, pgf@foxharp.boston.ma.us (home)

------------------------
$Id: README.PC,v 1.35 2017/08/09 08:48:59 tom Exp $
------------------------
vile-9.8v/README.VMS000066400000000000000000000054241415556424100140570ustar00rootroot00000000000000                          -------------------
                          Running vile on VMS
                          -------------------

vile can be built using either the VAXC or DECC compiler.  use vmsbuild.com
as the build script, which accepts this syntax:

          $ @vmsbuild [vile [ []]]      ! builds vile
          $ @vmsbuild xvile [ []]       ! builds xvile

where:
           :== { decc | vaxc }
             :== build target, generally used by developers

the default compiler on VAX hosts is vaxc, else decc (Alpha hosts).  

when choosing a compiler, carefully read the "warning" section below.  if
building _both_ vile and xvile from the _same_ directory, refer to the
"Configuration Note" at the top of vmsbuild.com.


Tested systems
--------------
    VMS system version 5.4-2
    VAX-C version 3.2
and
    VMS system version 6.1, 6.2
    DEC C version 5.0, 5.2
and
    VMS/VAX system version V7.1
    DEC C V5.6-003

                        +++++++++++++++++++++++++++
                        warning   warning   warning
                        +++++++++++++++++++++++++++

when selecting a target compiler, beware of this problem:

    on a VAX, the DEC-C compiler and/or its run-time library cause
    vile to change the "Revised time" of every file the editor _reads_.
    you won't like this when using mms or a make clone.  the VAXC
    compiler does not suffer from this problem.

    configuration where problem was observed:
                 DEC C V5.6-003 on OpenVMS VAX V7.1

General installation instructions
---------------------------------
installation of vile's components is the responsibility of the end user.

after the build, copy all resultant executables (except mktbls.exe) and the
file vile.hlp to a directory of your choice.  finally, create a foreign
symbol that invokes the editor from the installation directory.  ex:

      vile :== $install_disk:[install_dir]vile.exe

Creating a startup file
-----------------------
most users will configure the editor.  this is accomplished by creating a
startup file, called "vile.rc", and adding various settings and macros as
described in vile.hlp .  vile searches for the startup file in these
locations (and in the order listed):

    current working directory
    the directory specified by the symbol HOME
    the vile executable directory   [this often does not work]
    if the symbol VILE_STARTUP_PATH exists then
        search each comma-delimited directory specified in this symbol
    else search
        sys$login
        sys$device:[vmstools]
        sys$library
    end if
    sys$system
    sys$library

VMS-specific features
---------------------
vile includes several useful vms-specific modes, which are described in
vile.hlp in the section entitled "VMS specifics".
vile-9.8v/aclocal.m4000066400000000000000000006350371415556424100144040ustar00rootroot00000000000000dnl $Id: aclocal.m4,v 1.351 2021/11/25 22:10:54 tom Exp $
dnl ---------------------------------------------------------------------------
dnl
dnl Copyright 1996-2020,2021 by Thomas E. Dickey
dnl
dnl                         All Rights Reserved
dnl
dnl Permission is hereby granted, free of charge, to any person obtaining a
dnl copy of this software and associated documentation files (the
dnl "Software"), to deal in the Software without restriction, including
dnl without limitation the rights to use, copy, modify, merge, publish,
dnl distribute, sublicense, and/or sell copies of the Software, and to
dnl permit persons to whom the Software is furnished to do so, subject to
dnl the following conditions:
dnl
dnl The above copyright notice and this permission notice shall be included
dnl in all copies or substantial portions of the Software.
dnl
dnl THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
dnl OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
dnl MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
dnl IN NO EVENT SHALL THE ABOVE LISTED COPYRIGHT HOLDER(S) BE LIABLE FOR ANY
dnl CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
dnl TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
dnl SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
dnl
dnl Except as contained in this notice, the name(s) of the above copyright
dnl holders shall not be used in advertising or otherwise to promote the
dnl sale, use or other dealings in this Software without prior written
dnl authorization.
dnl
dnl ---------------------------------------------------------------------------
dnl vile's local definitions for autoconf.
dnl
dnl See
dnl		https://invisible-island.net/autoconf/autoconf.html
dnl		https://invisible-island.net/autoconf/my-autoconf.html
dnl ---------------------------------------------------------------------------
dnl ---------------------------------------------------------------------------
dnl AM_ICONV version: 12 updated: 2007/07/30 19:12:03
dnl --------
dnl Inserted as requested by gettext 0.10.40
dnl File from /usr/share/aclocal
dnl iconv.m4
dnl ====================
dnl serial AM2
dnl
dnl From Bruno Haible.
dnl
dnl ====================
dnl Modified to use CF_FIND_LINKAGE and CF_ADD_SEARCHPATH, to broaden the
dnl range of locations searched.  Retain the same cache-variable naming to
dnl allow reuse with the other gettext macros -Thomas E Dickey
AC_DEFUN([AM_ICONV],
[
  dnl Some systems have iconv in libc, some have it in libiconv (OSF/1 and
  dnl those with the standalone portable GNU libiconv installed).

  AC_ARG_WITH([libiconv-prefix],
[  --with-libiconv-prefix=DIR
                          search for libiconv in DIR/include and DIR/lib], [
    CF_ADD_OPTIONAL_PATH($withval, libiconv)
   ])

  AC_CACHE_CHECK(for iconv, am_cv_func_iconv, [
    CF_FIND_LINKAGE(CF__ICONV_HEAD,
      CF__ICONV_BODY,
      iconv,
      am_cv_func_iconv=yes,
      am_cv_func_iconv=["no, consider installing GNU libiconv"])])

  if test "$am_cv_func_iconv" = yes; then
    AC_DEFINE(HAVE_ICONV, 1, [Define if you have the iconv() function.])

    AC_CACHE_CHECK([if the declaration of iconv() needs const.],
		   am_cv_proto_iconv_const,[
      AC_TRY_COMPILE(CF__ICONV_HEAD [
extern
#ifdef __cplusplus
"C"
#endif
#if defined(__STDC__) || defined(__cplusplus)
size_t iconv (iconv_t cd, char * *inbuf, size_t *inbytesleft, char * *outbuf, size_t *outbytesleft);
#else
size_t iconv();
#endif
],[], am_cv_proto_iconv_const=no,
      am_cv_proto_iconv_const=yes)])

    if test "$am_cv_proto_iconv_const" = yes ; then
      am_cv_proto_iconv_arg1="const"
    else
      am_cv_proto_iconv_arg1=""
    fi

    AC_DEFINE_UNQUOTED(ICONV_CONST, $am_cv_proto_iconv_arg1,
      [Define as const if the declaration of iconv() needs const.])
  fi

  LIBICONV=
  if test "$cf_cv_find_linkage_iconv" = yes; then
    CF_ADD_INCDIR($cf_cv_header_path_iconv)
    if test -n "$cf_cv_library_file_iconv" ; then
      LIBICONV="-liconv"
      CF_ADD_LIBDIR($cf_cv_library_path_iconv)
    fi
  fi

  AC_SUBST(LIBICONV)
])dnl
dnl ---------------------------------------------------------------------------
dnl AM_LANGINFO_CODESET version: 6 updated: 2021/01/01 16:53:59
dnl -------------------
dnl Inserted as requested by gettext 0.10.40
dnl File from /usr/share/aclocal
dnl codeset.m4
dnl ====================
dnl serial AM1
dnl
dnl From Bruno Haible.
AC_DEFUN([AM_LANGINFO_CODESET],
[
AC_CACHE_CHECK([for nl_langinfo and CODESET], am_cv_langinfo_codeset,
	[AC_TRY_LINK([#include ],
	[char* cs = nl_langinfo(CODESET); (void)cs],
	am_cv_langinfo_codeset=yes,
	am_cv_langinfo_codeset=no)
	])
	if test "$am_cv_langinfo_codeset" = yes; then
		AC_DEFINE(HAVE_LANGINFO_CODESET, 1,
		[Define if you have  and nl_langinfo(CODESET).])
	fi
])dnl
dnl ---------------------------------------------------------------------------
dnl CF_ACVERSION_CHECK version: 5 updated: 2014/06/04 19:11:49
dnl ------------------
dnl Conditionally generate script according to whether we're using a given autoconf.
dnl
dnl $1 = version to compare against
dnl $2 = code to use if AC_ACVERSION is at least as high as $1.
dnl $3 = code to use if AC_ACVERSION is older than $1.
define([CF_ACVERSION_CHECK],
[
ifdef([AC_ACVERSION], ,[ifdef([AC_AUTOCONF_VERSION],[m4_copy([AC_AUTOCONF_VERSION],[AC_ACVERSION])],[m4_copy([m4_PACKAGE_VERSION],[AC_ACVERSION])])])dnl
ifdef([m4_version_compare],
[m4_if(m4_version_compare(m4_defn([AC_ACVERSION]), [$1]), -1, [$3], [$2])],
[CF_ACVERSION_COMPARE(
AC_PREREQ_CANON(AC_PREREQ_SPLIT([$1])),
AC_PREREQ_CANON(AC_PREREQ_SPLIT(AC_ACVERSION)), AC_ACVERSION, [$2], [$3])])])dnl
dnl ---------------------------------------------------------------------------
dnl CF_ACVERSION_COMPARE version: 3 updated: 2012/10/03 18:39:53
dnl --------------------
dnl CF_ACVERSION_COMPARE(MAJOR1, MINOR1, TERNARY1,
dnl                      MAJOR2, MINOR2, TERNARY2,
dnl                      PRINTABLE2, not FOUND, FOUND)
define([CF_ACVERSION_COMPARE],
[ifelse(builtin([eval], [$2 < $5]), 1,
[ifelse([$8], , ,[$8])],
[ifelse([$9], , ,[$9])])])dnl
dnl ---------------------------------------------------------------------------
dnl CF_ADD_CFLAGS version: 15 updated: 2020/12/31 10:54:15
dnl -------------
dnl Copy non-preprocessor flags to $CFLAGS, preprocessor flags to $CPPFLAGS
dnl $1 = flags to add
dnl $2 = if given makes this macro verbose.
dnl
dnl Put any preprocessor definitions that use quoted strings in $EXTRA_CPPFLAGS,
dnl to simplify use of $CPPFLAGS in compiler checks, etc., that are easily
dnl confused by the quotes (which require backslashes to keep them usable).
AC_DEFUN([CF_ADD_CFLAGS],
[
cf_fix_cppflags=no
cf_new_cflags=
cf_new_cppflags=
cf_new_extra_cppflags=

for cf_add_cflags in $1
do
case "$cf_fix_cppflags" in
(no)
	case "$cf_add_cflags" in
	(-undef|-nostdinc*|-I*|-D*|-U*|-E|-P|-C)
		case "$cf_add_cflags" in
		(-D*)
			cf_tst_cflags=`echo "${cf_add_cflags}" |sed -e 's/^-D[[^=]]*='\''\"[[^"]]*//'`

			test "x${cf_add_cflags}" != "x${cf_tst_cflags}" \
				&& test -z "${cf_tst_cflags}" \
				&& cf_fix_cppflags=yes

			if test "$cf_fix_cppflags" = yes ; then
				CF_APPEND_TEXT(cf_new_extra_cppflags,$cf_add_cflags)
				continue
			elif test "${cf_tst_cflags}" = "\"'" ; then
				CF_APPEND_TEXT(cf_new_extra_cppflags,$cf_add_cflags)
				continue
			fi
			;;
		esac
		case "$CPPFLAGS" in
		(*$cf_add_cflags)
			;;
		(*)
			case "$cf_add_cflags" in
			(-D*)
				cf_tst_cppflags=`echo "x$cf_add_cflags" | sed -e 's/^...//' -e 's/=.*//'`
				CF_REMOVE_DEFINE(CPPFLAGS,$CPPFLAGS,$cf_tst_cppflags)
				;;
			esac
			CF_APPEND_TEXT(cf_new_cppflags,$cf_add_cflags)
			;;
		esac
		;;
	(*)
		CF_APPEND_TEXT(cf_new_cflags,$cf_add_cflags)
		;;
	esac
	;;
(yes)
	CF_APPEND_TEXT(cf_new_extra_cppflags,$cf_add_cflags)

	cf_tst_cflags=`echo "${cf_add_cflags}" |sed -e 's/^[[^"]]*"'\''//'`

	test "x${cf_add_cflags}" != "x${cf_tst_cflags}" \
		&& test -z "${cf_tst_cflags}" \
		&& cf_fix_cppflags=no
	;;
esac
done

if test -n "$cf_new_cflags" ; then
	ifelse([$2],,,[CF_VERBOSE(add to \$CFLAGS $cf_new_cflags)])
	CF_APPEND_TEXT(CFLAGS,$cf_new_cflags)
fi

if test -n "$cf_new_cppflags" ; then
	ifelse([$2],,,[CF_VERBOSE(add to \$CPPFLAGS $cf_new_cppflags)])
	CF_APPEND_TEXT(CPPFLAGS,$cf_new_cppflags)
fi

if test -n "$cf_new_extra_cppflags" ; then
	ifelse([$2],,,[CF_VERBOSE(add to \$EXTRA_CPPFLAGS $cf_new_extra_cppflags)])
	CF_APPEND_TEXT(EXTRA_CPPFLAGS,$cf_new_extra_cppflags)
fi

AC_SUBST(EXTRA_CPPFLAGS)

])dnl
dnl ---------------------------------------------------------------------------
dnl CF_ADD_INCDIR version: 17 updated: 2021/09/04 06:35:04
dnl -------------
dnl Add an include-directory to $CPPFLAGS.  Don't add /usr/include, since it is
dnl redundant.  We don't normally need to add -I/usr/local/include for gcc,
dnl but old versions (and some misinstalled ones) need that.  To make things
dnl worse, gcc 3.x may give error messages if -I/usr/local/include is added to
dnl the include-path).
AC_DEFUN([CF_ADD_INCDIR],
[
if test -n "$1" ; then
  for cf_add_incdir in $1
  do
	while test "$cf_add_incdir" != /usr/include
	do
	  if test -d "$cf_add_incdir"
	  then
		cf_have_incdir=no
		if test -n "$CFLAGS$CPPFLAGS" ; then
		  # a loop is needed to ensure we can add subdirs of existing dirs
		  for cf_test_incdir in $CFLAGS $CPPFLAGS ; do
			if test ".$cf_test_incdir" = ".-I$cf_add_incdir" ; then
			  cf_have_incdir=yes; break
			fi
		  done
		fi

		if test "$cf_have_incdir" = no ; then
		  if test "$cf_add_incdir" = /usr/local/include ; then
			if test "$GCC" = yes
			then
			  cf_save_CPPFLAGS=$CPPFLAGS
			  CF_APPEND_TEXT(CPPFLAGS,-I$cf_add_incdir)
			  AC_TRY_COMPILE([#include ],
				  [printf("Hello")],
				  [],
				  [cf_have_incdir=yes])
			  CPPFLAGS=$cf_save_CPPFLAGS
			fi
		  fi
		fi

		if test "$cf_have_incdir" = no ; then
		  CF_VERBOSE(adding $cf_add_incdir to include-path)
		  ifelse([$2],,CPPFLAGS,[$2])="$ifelse([$2],,CPPFLAGS,[$2]) -I$cf_add_incdir"

		  cf_top_incdir=`echo "$cf_add_incdir" | sed -e 's%/include/.*$%/include%'`
		  test "$cf_top_incdir" = "$cf_add_incdir" && break
		  cf_add_incdir="$cf_top_incdir"
		else
		  break
		fi
	  else
		break
	  fi
	done
  done
fi
])dnl
dnl ---------------------------------------------------------------------------
dnl CF_ADD_LIB version: 2 updated: 2010/06/02 05:03:05
dnl ----------
dnl Add a library, used to enforce consistency.
dnl
dnl $1 = library to add, without the "-l"
dnl $2 = variable to update (default $LIBS)
AC_DEFUN([CF_ADD_LIB],[CF_ADD_LIBS(-l$1,ifelse($2,,LIBS,[$2]))])dnl
dnl ---------------------------------------------------------------------------
dnl CF_ADD_LIBDIR version: 11 updated: 2020/12/31 20:19:42
dnl -------------
dnl	Adds to the library-path
dnl
dnl	Some machines have trouble with multiple -L options.
dnl
dnl $1 is the (list of) directory(s) to add
dnl $2 is the optional name of the variable to update (default LDFLAGS)
dnl
AC_DEFUN([CF_ADD_LIBDIR],
[
if test -n "$1" ; then
	for cf_add_libdir in $1
	do
		if test "$cf_add_libdir" = /usr/lib ; then
			:
		elif test -d "$cf_add_libdir"
		then
			cf_have_libdir=no
			if test -n "$LDFLAGS$LIBS" ; then
				# a loop is needed to ensure we can add subdirs of existing dirs
				for cf_test_libdir in $LDFLAGS $LIBS ; do
					if test ".$cf_test_libdir" = ".-L$cf_add_libdir" ; then
						cf_have_libdir=yes; break
					fi
				done
			fi
			if test "$cf_have_libdir" = no ; then
				CF_VERBOSE(adding $cf_add_libdir to library-path)
				ifelse([$2],,LDFLAGS,[$2])="-L$cf_add_libdir $ifelse([$2],,LDFLAGS,[$2])"
			fi
		fi
	done
fi
])dnl
dnl ---------------------------------------------------------------------------
dnl CF_ADD_LIBS version: 3 updated: 2019/11/02 16:47:33
dnl -----------
dnl Add one or more libraries, used to enforce consistency.  Libraries are
dnl prepended to an existing list, since their dependencies are assumed to
dnl already exist in the list.
dnl
dnl $1 = libraries to add, with the "-l", etc.
dnl $2 = variable to update (default $LIBS)
AC_DEFUN([CF_ADD_LIBS],[
cf_add_libs="[$]ifelse($2,,LIBS,[$2])"
# reverse order
cf_add_0lib=
for cf_add_1lib in $1; do cf_add_0lib="$cf_add_1lib $cf_add_0lib"; done
# filter duplicates
for cf_add_1lib in $cf_add_0lib; do
	for cf_add_2lib in $cf_add_libs; do
		if test "x$cf_add_1lib" = "x$cf_add_2lib"; then
			cf_add_1lib=
			break
		fi
	done
	test -n "$cf_add_1lib" && cf_add_libs="$cf_add_1lib $cf_add_libs"
done
ifelse($2,,LIBS,[$2])="$cf_add_libs"
])dnl
dnl ---------------------------------------------------------------------------
dnl CF_ADD_LIB_AFTER version: 3 updated: 2013/07/09 21:27:22
dnl ----------------
dnl Add a given library after another, e.g., following the one it satisfies a
dnl dependency for.
dnl
dnl $1 = the first library
dnl $2 = its dependency
AC_DEFUN([CF_ADD_LIB_AFTER],[
CF_VERBOSE(...before $LIBS)
LIBS=`echo "$LIBS" | sed -e "s/[[ 	]][[ 	]]*/ /g" -e "s%$1 %$1 $2 %" -e 's%  % %g'`
CF_VERBOSE(...after  $LIBS)
])dnl
dnl ---------------------------------------------------------------------------
dnl CF_ADD_OPTIONAL_PATH version: 3 updated: 2015/05/10 19:52:14
dnl --------------------
dnl Add an optional search-path to the compile/link variables.
dnl See CF_WITH_PATH
dnl
dnl $1 = shell variable containing the result of --with-XXX=[DIR]
dnl $2 = module to look for.
AC_DEFUN([CF_ADD_OPTIONAL_PATH],[
case "$1" in
(no)
	;;
(yes)
	;;
(*)
	CF_ADD_SEARCHPATH([$1], [AC_MSG_ERROR(cannot find $2 under $1)])
	;;
esac
])dnl
dnl ---------------------------------------------------------------------------
dnl CF_ADD_SEARCHPATH version: 6 updated: 2020/12/31 20:19:42
dnl -----------------
dnl Set $CPPFLAGS and $LDFLAGS with the directories given via the parameter.
dnl They can be either the common root of include- and lib-directories, or the
dnl lib-directory (to allow for things like lib64 directories).
dnl See also CF_FIND_LINKAGE.
dnl
dnl $1 is the list of colon-separated directory names to search.
dnl $2 is the action to take if a parameter does not yield a directory.
AC_DEFUN([CF_ADD_SEARCHPATH],
[
AC_REQUIRE([CF_PATHSEP])
for cf_searchpath in `echo "$1" | tr $PATH_SEPARATOR ' '`; do
	if test -d "$cf_searchpath/include" ; then
		CF_ADD_INCDIR($cf_searchpath/include)
	elif test -d "$cf_searchpath/../include" ; then
		CF_ADD_INCDIR($cf_searchpath/../include)
	ifelse([$2],,,[else
$2])
	fi
	if test -d "$cf_searchpath/lib" ; then
		CF_ADD_LIBDIR($cf_searchpath/lib)
	elif test -d "$cf_searchpath" ; then
		CF_ADD_LIBDIR($cf_searchpath)
	ifelse([$2],,,[else
$2])
	fi
done
])
dnl ---------------------------------------------------------------------------
dnl CF_ADD_SUBDIR_PATH version: 5 updated: 2020/12/31 20:19:42
dnl ------------------
dnl Append to a search-list for a nonstandard header/lib-file
dnl	$1 = the variable to return as result
dnl	$2 = the package name
dnl	$3 = the subdirectory, e.g., bin, include or lib
dnl $4 = the directory under which we will test for subdirectories
dnl $5 = a directory that we do not want $4 to match
AC_DEFUN([CF_ADD_SUBDIR_PATH],
[
test "x$4" != "x$5" && \
test -d "$4" && \
ifelse([$5],NONE,,[{ test -z "$5" || test "x$5" = xNONE || test "x$4" != "x$5"; } &&]) {
	test -n "$verbose" && echo "	... testing for $3-directories under $4"
	test -d "$4/$3" &&          $1="[$]$1 $4/$3"
	test -d "$4/$3/$2" &&       $1="[$]$1 $4/$3/$2"
	test -d "$4/$3/$2/$3" &&    $1="[$]$1 $4/$3/$2/$3"
	test -d "$4/$2/$3" &&       $1="[$]$1 $4/$2/$3"
	test -d "$4/$2/$3/$2" &&    $1="[$]$1 $4/$2/$3/$2"
}
])dnl
dnl ---------------------------------------------------------------------------
dnl CF_APPEND_CFLAGS version: 3 updated: 2021/09/05 17:25:40
dnl ----------------
dnl Use CF_ADD_CFLAGS after first checking for potential redefinitions.
dnl $1 = flags to add
dnl $2 = if given makes this macro verbose.
define([CF_APPEND_CFLAGS],
[
for cf_add_cflags in $1
do
	case "x$cf_add_cflags" in
	(x-[[DU]]*)
		CF_REMOVE_CFLAGS($cf_add_cflags,CFLAGS,[$2])
		CF_REMOVE_CFLAGS($cf_add_cflags,CPPFLAGS,[$2])
		;;
	esac
	CF_ADD_CFLAGS([$cf_add_cflags],[$2])
done
])dnl
dnl ---------------------------------------------------------------------------
dnl CF_APPEND_TEXT version: 1 updated: 2017/02/25 18:58:55
dnl --------------
dnl use this macro for appending text without introducing an extra blank at
dnl the beginning
define([CF_APPEND_TEXT],
[
	test -n "[$]$1" && $1="[$]$1 "
	$1="[$]{$1}$2"
])dnl
dnl ---------------------------------------------------------------------------
dnl CF_ARG_DISABLE version: 3 updated: 1999/03/30 17:24:31
dnl --------------
dnl Allow user to disable a normally-on option.
AC_DEFUN([CF_ARG_DISABLE],
[CF_ARG_OPTION($1,[$2],[$3],[$4],yes)])dnl
dnl ---------------------------------------------------------------------------
dnl CF_ARG_ENABLE version: 3 updated: 1999/03/30 17:24:31
dnl -------------
dnl Allow user to enable a normally-off option.
AC_DEFUN([CF_ARG_ENABLE],
[CF_ARG_OPTION($1,[$2],[$3],[$4],no)])dnl
dnl ---------------------------------------------------------------------------
dnl CF_ARG_OPTION version: 5 updated: 2015/05/10 19:52:14
dnl -------------
dnl Restricted form of AC_ARG_ENABLE that ensures user doesn't give bogus
dnl values.
dnl
dnl Parameters:
dnl $1 = option name
dnl $2 = help-string
dnl $3 = action to perform if option is not default
dnl $4 = action if perform if option is default
dnl $5 = default option value (either 'yes' or 'no')
AC_DEFUN([CF_ARG_OPTION],
[AC_ARG_ENABLE([$1],[$2],[test "$enableval" != ifelse([$5],no,yes,no) && enableval=ifelse([$5],no,no,yes)
	if test "$enableval" != "$5" ; then
ifelse([$3],,[    :]dnl
,[    $3]) ifelse([$4],,,[
	else
		$4])
	fi],[enableval=$5 ifelse([$4],,,[
	$4
])dnl
])])dnl
dnl ---------------------------------------------------------------------------
dnl CF_AR_FLAGS version: 9 updated: 2021/01/01 13:31:04
dnl -----------
dnl Check for suitable "ar" (archiver) options for updating an archive.
dnl
dnl In particular, handle some obsolete cases where the "-" might be omitted,
dnl as well as a workaround for breakage of make's archive rules by the GNU
dnl binutils "ar" program.
AC_DEFUN([CF_AR_FLAGS],[
AC_REQUIRE([CF_PROG_AR])

AC_CACHE_CHECK(for options to update archives, cf_cv_ar_flags,[
	case "$cf_cv_system_name" in
	(*-msvc*)
		cf_cv_ar_flags=''
		cat >mk_static_lib.sh <<-EOF
		#!$SHELL
		MSVC_BIN="[$]AR"
		out="\[$]1"
		shift
		exec \[$]MSVC_BIN -out:"\[$]out" \[$]@
		EOF
		chmod +x mk_static_lib.sh
		AR=`pwd`/mk_static_lib.sh
		;;
	(*)
		cf_cv_ar_flags=unknown
		for cf_ar_flags in -curvU -curv curv -crv crv -cqv cqv -rv rv
		do

			# check if $ARFLAGS already contains this choice
			if test "x$ARFLAGS" != "x" ; then
				cf_check_ar_flags=`echo "x$ARFLAGS" | sed -e "s/$cf_ar_flags\$//" -e "s/$cf_ar_flags / /"`
				if test "x$ARFLAGS" != "$cf_check_ar_flags" ; then
					cf_cv_ar_flags=
					break
				fi
			fi

			rm -f "conftest.$ac_cv_objext"
			rm -f conftest.a

			cat >"conftest.$ac_ext" <&AC_FD_CC
				$AR $ARFLAGS "$cf_ar_flags" conftest.a "conftest.$ac_cv_objext" 2>&AC_FD_CC 1>/dev/null
				if test -f conftest.a ; then
					cf_cv_ar_flags="$cf_ar_flags"
					break
				fi
			else
				CF_VERBOSE(cannot compile test-program)
				break
			fi
		done
		rm -f conftest.a "conftest.$ac_ext" "conftest.$ac_cv_objext"
		;;
	esac
])

if test -n "$ARFLAGS" ; then
	if test -n "$cf_cv_ar_flags" ; then
		ARFLAGS="$ARFLAGS $cf_cv_ar_flags"
	fi
else
	ARFLAGS=$cf_cv_ar_flags
fi

AC_SUBST(ARFLAGS)
])
dnl ---------------------------------------------------------------------------
dnl CF_AUTO_SYMLINK version: 4 updated: 2020/12/31 20:19:42
dnl ---------------
dnl If CF_WITH_SYMLINK is set, but the program transformation is inactive,
dnl override it to provide a version-suffix to the result.  This assumes that
dnl a "version.sh" script is in the source directory.
dnl
dnl $1 = variable to substitute
AC_DEFUN([CF_AUTO_SYMLINK],[
AC_REQUIRE([CF_WITH_SYMLINK])dnl

if test "x$with_symlink" != xno ; then
	if test "[$]$1" = NONE ; then
		cf_version=`$SHELL "$srcdir/version.sh" 2>/dev/null`
		if test -n "$cf_version" ; then
			if test "$program_suffix" = NONE ; then
				program_suffix="-$cf_version"
			else
				program_suffix="$program_suffix-$cf_version"
			fi
			CF_TRANSFORM_PROGRAM
			$1="$with_symlink"
		else
			AC_MSG_ERROR(No version number found in sources)
		fi
	fi
fi
])
dnl ---------------------------------------------------------------------------
dnl CF_BUILD_CC version: 9 updated: 2021/01/02 09:31:20
dnl -----------
dnl If we're cross-compiling, allow the user to override the tools and their
dnl options.  The configure script is oriented toward identifying the host
dnl compiler, etc., but we need a build compiler to generate parts of the
dnl source.
dnl
dnl $1 = default for $CPPFLAGS
dnl $2 = default for $LIBS
AC_DEFUN([CF_BUILD_CC],[
CF_ACVERSION_CHECK(2.52,,
	[AC_REQUIRE([CF_PROG_EXT])])
if test "$cross_compiling" = yes ; then

	# defaults that we might want to override
	: ${BUILD_CFLAGS:=''}
	: ${BUILD_CPPFLAGS:='ifelse([$1],,,[$1])'}
	: ${BUILD_LDFLAGS:=''}
	: ${BUILD_LIBS:='ifelse([$2],,,[$2])'}
	: ${BUILD_EXEEXT:='$x'}
	: ${BUILD_OBJEXT:='o'}

	AC_ARG_WITH(build-cc,
		[  --with-build-cc=XXX     the build C compiler ($BUILD_CC)],
		[BUILD_CC="$withval"],
		[AC_CHECK_PROGS(BUILD_CC, [gcc clang c99 c89 cc cl],none)])
	AC_MSG_CHECKING(for native build C compiler)
	AC_MSG_RESULT($BUILD_CC)

	AC_MSG_CHECKING(for native build C preprocessor)
	AC_ARG_WITH(build-cpp,
		[  --with-build-cpp=XXX    the build C preprocessor ($BUILD_CPP)],
		[BUILD_CPP="$withval"],
		[BUILD_CPP='${BUILD_CC} -E'])
	AC_MSG_RESULT($BUILD_CPP)

	AC_MSG_CHECKING(for native build C flags)
	AC_ARG_WITH(build-cflags,
		[  --with-build-cflags=XXX the build C compiler-flags ($BUILD_CFLAGS)],
		[BUILD_CFLAGS="$withval"])
	AC_MSG_RESULT($BUILD_CFLAGS)

	AC_MSG_CHECKING(for native build C preprocessor-flags)
	AC_ARG_WITH(build-cppflags,
		[  --with-build-cppflags=XXX the build C preprocessor-flags ($BUILD_CPPFLAGS)],
		[BUILD_CPPFLAGS="$withval"])
	AC_MSG_RESULT($BUILD_CPPFLAGS)

	AC_MSG_CHECKING(for native build linker-flags)
	AC_ARG_WITH(build-ldflags,
		[  --with-build-ldflags=XXX the build linker-flags ($BUILD_LDFLAGS)],
		[BUILD_LDFLAGS="$withval"])
	AC_MSG_RESULT($BUILD_LDFLAGS)

	AC_MSG_CHECKING(for native build linker-libraries)
	AC_ARG_WITH(build-libs,
		[  --with-build-libs=XXX   the build libraries (${BUILD_LIBS})],
		[BUILD_LIBS="$withval"])
	AC_MSG_RESULT($BUILD_LIBS)

	# this assumes we're on Unix.
	BUILD_EXEEXT=
	BUILD_OBJEXT=o

	: ${BUILD_CC:='${CC}'}

	if { test "$BUILD_CC" = "$CC" || test "$BUILD_CC" = '${CC}'; } ; then
		AC_MSG_ERROR([Cross-build requires two compilers.
Use --with-build-cc to specify the native compiler.])
	fi

else
	: ${BUILD_CC:='${CC}'}
	: ${BUILD_CPP:='${CPP}'}
	: ${BUILD_CFLAGS:='${CFLAGS}'}
	: ${BUILD_CPPFLAGS:='${CPPFLAGS}'}
	: ${BUILD_LDFLAGS:='${LDFLAGS}'}
	: ${BUILD_LIBS:='${LIBS}'}
	: ${BUILD_EXEEXT:='$x'}
	: ${BUILD_OBJEXT:='o'}
fi

AC_SUBST(BUILD_CC)
AC_SUBST(BUILD_CPP)
AC_SUBST(BUILD_CFLAGS)
AC_SUBST(BUILD_CPPFLAGS)
AC_SUBST(BUILD_LDFLAGS)
AC_SUBST(BUILD_LIBS)
AC_SUBST(BUILD_EXEEXT)
AC_SUBST(BUILD_OBJEXT)
])dnl
dnl ---------------------------------------------------------------------------
dnl CF_C11_NORETURN version: 3 updated: 2021/03/28 11:36:23
dnl ---------------
AC_DEFUN([CF_C11_NORETURN],
[
AC_MSG_CHECKING(if you want to use C11 _Noreturn feature)
CF_ARG_ENABLE(stdnoreturn,
	[  --enable-stdnoreturn    enable C11 _Noreturn feature for diagnostics],
	[enable_stdnoreturn=yes],
	[enable_stdnoreturn=no])
AC_MSG_RESULT($enable_stdnoreturn)

if test $enable_stdnoreturn = yes; then
AC_CACHE_CHECK([for C11 _Noreturn feature], cf_cv_c11_noreturn,
	[AC_TRY_COMPILE([
#include 
#include 
#include 
static _Noreturn void giveup(void) { exit(0); }
	],
	[if (feof(stdin)) giveup()],
	cf_cv_c11_noreturn=yes,
	cf_cv_c11_noreturn=no)
	])
else
	cf_cv_c11_noreturn=no,
fi

if test "$cf_cv_c11_noreturn" = yes; then
	AC_DEFINE(HAVE_STDNORETURN_H, 1,[Define if  header is available and working])
	AC_DEFINE_UNQUOTED(STDC_NORETURN,_Noreturn,[Define if C11 _Noreturn keyword is supported])
	HAVE_STDNORETURN_H=1
else
	HAVE_STDNORETURN_H=0
fi

AC_SUBST(HAVE_STDNORETURN_H)
AC_SUBST(STDC_NORETURN)
])dnl
dnl ---------------------------------------------------------------------------
dnl CF_CC_ENV_FLAGS version: 10 updated: 2020/12/31 18:40:20
dnl ---------------
dnl Check for user's environment-breakage by stuffing CFLAGS/CPPFLAGS content
dnl into CC.  This will not help with broken scripts that wrap the compiler
dnl with options, but eliminates a more common category of user confusion.
dnl
dnl In particular, it addresses the problem of being able to run the C
dnl preprocessor in a consistent manner.
dnl
dnl Caveat: this also disallows blanks in the pathname for the compiler, but
dnl the nuisance of having inconsistent settings for compiler and preprocessor
dnl outweighs that limitation.
AC_DEFUN([CF_CC_ENV_FLAGS],
[
# This should have been defined by AC_PROG_CC
: "${CC:=cc}"

AC_MSG_CHECKING(\$CFLAGS variable)
case "x$CFLAGS" in
(*-[[IUD]]*)
	AC_MSG_RESULT(broken)
	AC_MSG_WARN(your environment uses the CFLAGS variable to hold CPPFLAGS options)
	cf_flags="$CFLAGS"
	CFLAGS=
	for cf_arg in $cf_flags
	do
		CF_ADD_CFLAGS($cf_arg)
	done
	;;
(*)
	AC_MSG_RESULT(ok)
	;;
esac

AC_MSG_CHECKING(\$CC variable)
case "$CC" in
(*[[\ \	]]-*)
	AC_MSG_RESULT(broken)
	AC_MSG_WARN(your environment uses the CC variable to hold CFLAGS/CPPFLAGS options)
	# humor him...
	cf_prog=`echo "$CC" | sed -e 's/	/ /g' -e 's/[[ ]]* / /g' -e 's/[[ ]]*[[ ]]-[[^ ]].*//'`
	cf_flags=`echo "$CC" | ${AWK:-awk} -v prog="$cf_prog" '{ printf("%s", [substr]([$]0,1+length(prog))); }'`
	CC="$cf_prog"
	for cf_arg in $cf_flags
	do
		case "x$cf_arg" in
		(x-[[IUDfgOW]]*)
			CF_ADD_CFLAGS($cf_arg)
			;;
		(*)
			CC="$CC $cf_arg"
			;;
		esac
	done
	CF_VERBOSE(resulting CC: '$CC')
	CF_VERBOSE(resulting CFLAGS: '$CFLAGS')
	CF_VERBOSE(resulting CPPFLAGS: '$CPPFLAGS')
	;;
(*)
	AC_MSG_RESULT(ok)
	;;
esac
])dnl
dnl ---------------------------------------------------------------------------
dnl CF_CC_INIT_UNIONS version: 3 updated: 2012/10/06 11:17:15
dnl -----------------
dnl Check if the C compiler supports initialization of unions.
AC_DEFUN([CF_CC_INIT_UNIONS],[
AC_CACHE_CHECK(if we can initialize unions,
cf_cv_init_unions,[
	AC_TRY_COMPILE([],
	[static struct foo {int x; union {double a; int b; } bar; } c = {0,{1.0}}],
	[cf_cv_init_unions=yes],
	[cf_cv_init_unions=no])
	])
test $cf_cv_init_unions = no && AC_DEFINE(CC_CANNOT_INIT_UNIONS,1,[Define to 1 if C compiler cannot initialize unions])
])dnl
dnl ---------------------------------------------------------------------------
dnl CF_CHAR_DEVICE version: 4 updated: 2020/12/31 20:19:42
dnl --------------
dnl Check for existence of the given character-device
AC_DEFUN([CF_CHAR_DEVICE],
[
AC_MSG_CHECKING(for /dev/tty)
if test -c $1 ; then
	cf_result=yes
else
	cf_result=no
fi
AC_MSG_RESULT($cf_result)
if test "$cf_result" = yes ; then
	cf_result="`echo "$1" | sed -e s%/%_%g`"
	CF_UPPER(cf_result,$cf_result)
	AC_DEFINE_UNQUOTED(HAVE$cf_result)
fi
])dnl
dnl ---------------------------------------------------------------------------
dnl CF_CHECK_CACHE version: 13 updated: 2020/12/31 10:54:15
dnl --------------
dnl Check if we're accidentally using a cache from a different machine.
dnl Derive the system name, as a check for reusing the autoconf cache.
dnl
dnl If we've packaged config.guess and config.sub, run that (since it does a
dnl better job than uname).  Normally we'll use AC_CANONICAL_HOST, but allow
dnl an extra parameter that we may override, e.g., for AC_CANONICAL_SYSTEM
dnl which is useful in cross-compiles.
dnl
dnl Note: we would use $ac_config_sub, but that is one of the places where
dnl autoconf 2.5x broke compatibility with autoconf 2.13
AC_DEFUN([CF_CHECK_CACHE],
[
if test -f "$srcdir/config.guess" || test -f "$ac_aux_dir/config.guess" ; then
	ifelse([$1],,[AC_CANONICAL_HOST],[$1])
	system_name="$host_os"
else
	system_name="`(uname -s -r) 2>/dev/null`"
	if test -z "$system_name" ; then
		system_name="`(hostname) 2>/dev/null`"
	fi
fi
test -n "$system_name" && AC_DEFINE_UNQUOTED(SYSTEM_NAME,"$system_name",[Define to the system name.])
AC_CACHE_VAL(cf_cv_system_name,[cf_cv_system_name="$system_name"])

test -z "$system_name" && system_name="$cf_cv_system_name"
test -n "$cf_cv_system_name" && AC_MSG_RESULT(Configuring for $cf_cv_system_name)

if test ".$system_name" != ".$cf_cv_system_name" ; then
	AC_MSG_RESULT(Cached system name ($system_name) does not agree with actual ($cf_cv_system_name))
	AC_MSG_ERROR("Please remove config.cache and try again.")
fi
])dnl
dnl ---------------------------------------------------------------------------
dnl CF_CHECK_CFLAGS version: 4 updated: 2021/01/02 19:22:58
dnl ---------------
dnl Conditionally add to $CFLAGS and $CPPFLAGS values which are derived from
dnl a build-configuration such as imake.  These have the pitfall that they
dnl often contain compiler-specific options which we cannot use, mixed with
dnl preprocessor options that we usually can.
AC_DEFUN([CF_CHECK_CFLAGS],
[
CF_VERBOSE(checking additions to CFLAGS)
cf_check_cflags="$CFLAGS"
cf_check_cppflags="$CPPFLAGS"
CF_ADD_CFLAGS($1,yes)
if test "x$cf_check_cflags" != "x$CFLAGS" ; then
AC_TRY_LINK([#include ],[printf("Hello world");],,
	[CF_VERBOSE(test-compile failed.  Undoing change to \$CFLAGS)
	 if test "x$cf_check_cppflags" != "x$CPPFLAGS" ; then
		 CF_VERBOSE(but keeping change to \$CPPFLAGS)
	 fi
	 CFLAGS="$cf_check_cflags"])
fi
])dnl
dnl ---------------------------------------------------------------------------
dnl CF_CHECK_ENVIRON version: 3 updated: 2010/05/26 16:44:57
dnl ----------------
dnl Check for data that is usually declared in , e.g., the 'environ'
dnl variable.  Define a DECL_xxx symbol if we must declare it ourselves.
dnl
dnl $1 = the name to check
dnl $2 = the assumed type
AC_DEFUN([CF_CHECK_ENVIRON],
[
AC_CACHE_CHECK(if external $1 is declared, cf_cv_dcl_$1,[
    AC_TRY_COMPILE([
#ifdef HAVE_STDLIB_H
#include 
#endif
#include  ],
    ifelse([$2],,int,[$2]) x = (ifelse([$2],,int,[$2])) $1,
    [cf_cv_dcl_$1=yes],
    [cf_cv_dcl_$1=no])
])

if test "$cf_cv_dcl_$1" = no ; then
    CF_UPPER(cf_result,decl_$1)
    AC_DEFINE_UNQUOTED($cf_result)
fi

# It's possible (for near-UNIX clones) that the data doesn't exist
CF_CHECK_EXTERN_DATA($1,ifelse([$2],,int,[$2]))
])dnl
dnl ---------------------------------------------------------------------------
dnl CF_CHECK_ERRNO version: 13 updated: 2020/03/10 18:53:47
dnl --------------
dnl Check for data that is usually declared in  or , e.g.,
dnl the 'errno' variable.  Define a DECL_xxx symbol if we must declare it
dnl ourselves.
dnl
dnl $1 = the name to check
dnl $2 = the assumed type
AC_DEFUN([CF_CHECK_ERRNO],
[
AC_CACHE_CHECK(if external $1 is declared, cf_cv_dcl_$1,[
	AC_TRY_COMPILE([
#ifdef HAVE_STDLIB_H
#include 
#endif
#include 
#include 
#include  ],
	ifelse([$2],,int,[$2]) x = (ifelse([$2],,int,[$2])) $1; (void)x,
	[cf_cv_dcl_$1=yes],
	[cf_cv_dcl_$1=no])
])

if test "$cf_cv_dcl_$1" = no ; then
	CF_UPPER(cf_result,decl_$1)
	AC_DEFINE_UNQUOTED($cf_result)
fi

# It's possible (for near-UNIX clones) that the data doesn't exist
CF_CHECK_EXTERN_DATA($1,ifelse([$2],,int,[$2]))
])dnl
dnl ---------------------------------------------------------------------------
dnl CF_CHECK_EXTERN_DATA version: 5 updated: 2021/09/04 06:35:04
dnl --------------------
dnl Check for existence of external data in the current set of libraries.  If
dnl we can modify it, it is real enough.
dnl $1 = the name to check
dnl $2 = its type
AC_DEFUN([CF_CHECK_EXTERN_DATA],
[
AC_CACHE_CHECK(if external $1 exists, cf_cv_have_$1,[
	AC_TRY_LINK([
#undef $1
extern $2 $1;
],
	[$1 = 2],
	[cf_cv_have_$1=yes],
	[cf_cv_have_$1=no])
])

if test "$cf_cv_have_$1" = yes ; then
	CF_UPPER(cf_result,have_$1)
	AC_DEFINE_UNQUOTED($cf_result)
fi

])dnl
dnl ---------------------------------------------------------------------------
dnl CF_CHECK_FD_SET version: 5 updated: 2012/10/06 11:17:15
dnl ---------------
dnl Check if the fd_set type and corresponding macros are defined.
AC_DEFUN([CF_CHECK_FD_SET],
[
AC_REQUIRE([CF_TYPE_FD_SET])
AC_CACHE_CHECK([for fd_set macros],cf_cv_macros_fd_set,[
AC_TRY_COMPILE([
#include 
#if USE_SYS_SELECT_H
# include 
#else
# ifdef HAVE_SYS_TIME_H
#  include 
#  ifdef TIME_WITH_SYS_TIME
#   include 
#  endif
# else
#  include 
# endif
#endif
],[
	fd_set read_bits;
	FD_ZERO(&read_bits);
	FD_SET(0, &read_bits);],
	[cf_cv_macros_fd_set=yes],
	[cf_cv_macros_fd_set=no])])
test $cf_cv_macros_fd_set = yes && AC_DEFINE(HAVE_TYPE_FD_SET,1,[Define to 1 if type fd_set is declared])
])dnl
dnl ---------------------------------------------------------------------------
dnl CF_CHECK_LIBSSP version: 1 updated: 2021/10/30 10:40:19
dnl ---------------
dnl Check if libssp is needed, e.g., to work around misconfigured libraries
dnl used in cross-compiling to MinGW.
AC_DEFUN([CF_CHECK_LIBSSP],[
AC_CACHE_CHECK(if ssp library is needed,cf_cv_need_libssp,[
AC_TRY_LINK([
#include 
#include 
],[
       DIR *dp = opendir(".");
],cf_cv_need_libssp=no,[
	cf_save_LIBS="$LIBS"
	LIBS="$LIBS -lssp"
	AC_TRY_LINK([
#include 
#include 
	],[
		   DIR *dp = opendir(".");
	],cf_cv_need_libssp=yes,
	  cf_cv_need_libssp=maybe)
	LIBS="$cf_save_LIBS"
])dnl
])

if test "x$cf_cv_need_libssp" = xyes
then
	CF_ADD_LIB(ssp)
fi
])dnl
dnl ---------------------------------------------------------------------------
dnl CF_CLANG_COMPILER version: 8 updated: 2021/01/01 13:31:04
dnl -----------------
dnl Check if the given compiler is really clang.  clang's C driver defines
dnl __GNUC__ (fooling the configure script into setting $GCC to yes) but does
dnl not ignore some gcc options.
dnl
dnl This macro should be run "soon" after AC_PROG_CC or AC_PROG_CPLUSPLUS, to
dnl ensure that it is not mistaken for gcc/g++.  It is normally invoked from
dnl the wrappers for gcc and g++ warnings.
dnl
dnl $1 = GCC (default) or GXX
dnl $2 = CLANG_COMPILER (default)
dnl $3 = CFLAGS (default) or CXXFLAGS
AC_DEFUN([CF_CLANG_COMPILER],[
ifelse([$2],,CLANG_COMPILER,[$2])=no

if test "$ifelse([$1],,[$1],GCC)" = yes ; then
	AC_MSG_CHECKING(if this is really Clang ifelse([$1],GXX,C++,C) compiler)
	cf_save_CFLAGS="$ifelse([$3],,CFLAGS,[$3])"
	AC_TRY_COMPILE([],[
#ifdef __clang__
#else
make an error
#endif
],[ifelse([$2],,CLANG_COMPILER,[$2])=yes
],[])
	ifelse([$3],,CFLAGS,[$3])="$cf_save_CFLAGS"
	AC_MSG_RESULT($ifelse([$2],,CLANG_COMPILER,[$2]))
fi

CLANG_VERSION=none

if test "x$ifelse([$2],,CLANG_COMPILER,[$2])" = "xyes" ; then
	case "$CC" in
	(c[[1-9]][[0-9]]|*/c[[1-9]][[0-9]])
		AC_MSG_WARN(replacing broken compiler alias $CC)
		CFLAGS="$CFLAGS -std=`echo "$CC" | sed -e 's%.*/%%'`"
		CC=clang
		;;
	esac

	AC_MSG_CHECKING(version of $CC)
	CLANG_VERSION="`$CC --version 2>/dev/null | sed -e '2,$d' -e 's/^.*(CLANG[[^)]]*) //' -e 's/^.*(Debian[[^)]]*) //' -e 's/^[[^0-9.]]*//' -e 's/[[^0-9.]].*//'`"
	test -z "$CLANG_VERSION" && CLANG_VERSION=unknown
	AC_MSG_RESULT($CLANG_VERSION)

	for cf_clang_opt in \
		-Qunused-arguments \
		-Wno-error=implicit-function-declaration
	do
		AC_MSG_CHECKING(if option $cf_clang_opt works)
		cf_save_CFLAGS="$CFLAGS"
		CFLAGS="$CFLAGS $cf_clang_opt"
		AC_TRY_LINK([
			#include ],[
			printf("hello!\\n");],[
			cf_clang_optok=yes],[
			cf_clang_optok=no])
		AC_MSG_RESULT($cf_clang_optok)
		CFLAGS="$cf_save_CFLAGS"
		if test "$cf_clang_optok" = yes; then
			CF_VERBOSE(adding option $cf_clang_opt)
			CF_APPEND_TEXT(CFLAGS,$cf_clang_opt)
		fi
	done
fi
])
dnl ---------------------------------------------------------------------------
dnl CF_CONST_X_STRING version: 7 updated: 2021/06/07 17:39:17
dnl -----------------
dnl The X11R4-X11R6 Xt specification uses an ambiguous String type for most
dnl character-strings.
dnl
dnl It is ambiguous because the specification accommodated the pre-ANSI
dnl compilers bundled by more than one vendor in lieu of providing a standard C
dnl compiler other than by costly add-ons.  Because of this, the specification
dnl did not take into account the use of const for telling the compiler that
dnl string literals would be in readonly memory.
dnl
dnl As a workaround, one could (starting with X11R5) define XTSTRINGDEFINES, to
dnl let the compiler decide how to represent Xt's strings which were #define'd.
dnl That does not solve the problem of using the block of Xt's strings which
dnl are compiled into the library (and is less efficient than one might want).
dnl
dnl Xt specification 7 introduces the _CONST_X_STRING symbol which is used both
dnl when compiling the library and compiling using the library, to tell the
dnl compiler that String is const.
AC_DEFUN([CF_CONST_X_STRING],
[
AC_REQUIRE([AC_PATH_XTRA])

CF_SAVE_XTRA_FLAGS([CF_CONST_X_STRING])

AC_TRY_COMPILE(
[
#include 
#include 
],
[String foo = malloc(1); free((void*)foo)],[

AC_CACHE_CHECK(for X11/Xt const-feature,cf_cv_const_x_string,[
	AC_TRY_COMPILE(
		[
#define _CONST_X_STRING	/* X11R7.8 (perhaps) */
#undef  XTSTRINGDEFINES	/* X11R5 and later */
#include 
#include 
		],[String foo = malloc(1); *foo = 0],[
			cf_cv_const_x_string=no
		],[
			cf_cv_const_x_string=yes
		])
])

CF_RESTORE_XTRA_FLAGS([CF_CONST_X_STRING])

case "$cf_cv_const_x_string" in
(no)
	CF_APPEND_TEXT(CPPFLAGS,-DXTSTRINGDEFINES)
	;;
(*)
	CF_APPEND_TEXT(CPPFLAGS,-D_CONST_X_STRING)
	;;
esac

])
])dnl
dnl ---------------------------------------------------------------------------
dnl CF_CRYPT_FUNC version: 6 updated: 2020/09/08 19:32:19
dnl -------------
dnl Check if we have a working crypt() function
AC_DEFUN([CF_CRYPT_FUNC],
[
AC_CACHE_CHECK(for crypt function,cf_cv_crypt_func,[
cf_cv_crypt_func=
AC_TRY_LINK([],[crypt()],[
	cf_cv_crypt_func=yes],[
	cf_save_LIBS="$LIBS"
	LIBS="-lcrypt $LIBS"
	AC_TRY_LINK([],[crypt()],[
		cf_cv_crypt_func="-lcrypt"],[
		cf_cv_crypt_func=no])
	LIBS="$cf_save_LIBS"
	])
])
if test "$cf_cv_crypt_func" != no ; then
	cf_save_LIBS="$LIBS"
	test "$cf_cv_crypt_func" != yes && LIBS="$cf_cv_crypt_func $LIBS"
AC_CACHE_CHECK(if crypt works,cf_cv_crypt_works,[
AC_TRY_RUN([
#include 
extern char *crypt();
int main(void) {
	char *s = crypt("vi-crypt", "vi");
	${cf_cv_main_return:-return}(strcmp("vi6r2tczBYLvM", s) != 0);
}
	],[
	cf_cv_crypt_works=yes],[
	cf_cv_crypt_works=no],[
	cf_cv_crypt_works=unknown])
	LIBS="$cf_save_LIBS"])
	if test "$cf_cv_crypt_works" != no ; then
		AC_DEFINE(HAVE_CRYPT)
		if test "$cf_cv_crypt_func" != yes ; then
			LIBS="$cf_cv_crypt_func $LIBS"
		fi
	fi
fi
])dnl
dnl ---------------------------------------------------------------------------
dnl CF_CURSES_CPPFLAGS version: 14 updated: 2021/01/02 09:31:20
dnl ------------------
dnl Look for the curses headers.
AC_DEFUN([CF_CURSES_CPPFLAGS],[

AC_CACHE_CHECK(for extra include directories,cf_cv_curses_incdir,[
cf_cv_curses_incdir=no
case "$host_os" in
(hpux10.*)
	if test "x$cf_cv_screen" = "xcurses_colr"
	then
		test -d /usr/include/curses_colr && \
		cf_cv_curses_incdir="-I/usr/include/curses_colr"
	fi
	;;
(sunos3*|sunos4*)
	if test "x$cf_cv_screen" = "xcurses_5lib"
	then
		test -d /usr/5lib && \
		test -d /usr/5include && \
		cf_cv_curses_incdir="-I/usr/5include"
	fi
	;;
esac
])
if test "$cf_cv_curses_incdir" != no
then
	CF_APPEND_TEXT(CPPFLAGS,$cf_cv_curses_incdir)
fi

CF_CURSES_HEADER
CF_TERM_HEADER
])dnl
dnl ---------------------------------------------------------------------------
dnl CF_CURSES_FUNCS version: 20 updated: 2020/12/31 20:19:42
dnl ---------------
dnl Curses-functions are a little complicated, since a lot of them are macros.
AC_DEFUN([CF_CURSES_FUNCS],
[
AC_REQUIRE([CF_CURSES_CPPFLAGS])dnl
AC_REQUIRE([CF_XOPEN_CURSES])
AC_REQUIRE([CF_CURSES_TERM_H])
AC_REQUIRE([CF_CURSES_UNCTRL_H])
for cf_func in $1
do
	CF_UPPER(cf_tr_func,$cf_func)
	AC_MSG_CHECKING(for ${cf_func})
	CF_MSG_LOG(${cf_func})
	AC_CACHE_VAL(cf_cv_func_$cf_func,[
		eval cf_result='$ac_cv_func_'$cf_func
		if test ".$cf_result" != ".no"; then
			AC_TRY_LINK(CF__CURSES_HEAD,
			[
#ifndef ${cf_func}
long foo = (long)(&${cf_func});
fprintf(stderr, "testing linkage of $cf_func:%p\\n", (void *)foo);
if (foo + 1234L > 5678L)
	${cf_cv_main_return:-return}(foo != 0);
#endif
			],
			[cf_result=yes],
			[cf_result=no])
		fi
		eval 'cf_cv_func_'$cf_func'="$cf_result"'
	])
	# use the computed/retrieved cache-value:
	eval 'cf_result=$cf_cv_func_'$cf_func
	AC_MSG_RESULT($cf_result)
	if test "$cf_result" != no; then
		AC_DEFINE_UNQUOTED(HAVE_${cf_tr_func})
	fi
done
])dnl
dnl ---------------------------------------------------------------------------
dnl CF_CURSES_HEADER version: 5 updated: 2015/04/23 20:35:30
dnl ----------------
dnl Find a "curses" header file, e.g,. "curses.h", or one of the more common
dnl variations of ncurses' installs.
dnl
dnl $1 = ncurses when looking for ncurses, or is empty
AC_DEFUN([CF_CURSES_HEADER],[
AC_CACHE_CHECK(if we have identified curses headers,cf_cv_ncurses_header,[
cf_cv_ncurses_header=none
for cf_header in \
	ncurses.h ifelse($1,,,[$1/ncurses.h]) \
	curses.h ifelse($1,,,[$1/curses.h]) ifelse($1,,[ncurses/ncurses.h ncurses/curses.h])
do
AC_TRY_COMPILE([#include <${cf_header}>],
	[initscr(); tgoto("?", 0,0)],
	[cf_cv_ncurses_header=$cf_header; break],[])
done
])

if test "$cf_cv_ncurses_header" = none ; then
	AC_MSG_ERROR(No curses header-files found)
fi

# cheat, to get the right #define's for HAVE_NCURSES_H, etc.
AC_CHECK_HEADERS($cf_cv_ncurses_header)
])dnl
dnl ---------------------------------------------------------------------------
dnl CF_CURSES_LIBS version: 44 updated: 2021/01/02 09:31:20
dnl --------------
dnl Look for the curses libraries.  Older curses implementations may require
dnl termcap/termlib to be linked as well.  Call CF_CURSES_CPPFLAGS first.
AC_DEFUN([CF_CURSES_LIBS],[

AC_REQUIRE([CF_CURSES_CPPFLAGS])dnl
AC_MSG_CHECKING(if we have identified curses libraries)
AC_TRY_LINK([#include <${cf_cv_ncurses_header:-curses.h}>],
	[initscr(); tgoto("?", 0,0)],
	cf_result=yes,
	cf_result=no)
AC_MSG_RESULT($cf_result)

if test "$cf_result" = no ; then
case "$host_os" in
(freebsd*)
	AC_CHECK_LIB(mytinfo,tgoto,[CF_ADD_LIBS(-lmytinfo)])
	;;
(hpux10.*)
	# Looking at HPUX 10.20, the Hcurses library is the oldest (1997), cur_colr
	# next (1998), and xcurses "newer" (2000).  There is no header file for
	# Hcurses; the subdirectory curses_colr has the headers (curses.h and
	# term.h) for cur_colr
	if test "x$cf_cv_screen" = "xcurses_colr"
	then
		AC_CHECK_LIB(cur_colr,initscr,[
			CF_ADD_LIBS(-lcur_colr)
			ac_cv_func_initscr=yes
			],[
		AC_CHECK_LIB(Hcurses,initscr,[
			# HP's header uses __HP_CURSES, but user claims _HP_CURSES.
			CF_ADD_LIBS(-lHcurses)
			CF_APPEND_TEXT(CPPFLAGS,-D__HP_CURSES -D_HP_CURSES)
			ac_cv_func_initscr=yes
			])])
	fi
	;;
(linux*)
	case `arch 2>/dev/null` in
	(x86_64)
		if test -d /lib64
		then
			CF_ADD_LIBDIR(/lib64)
		else
			CF_ADD_LIBDIR(/lib)
		fi
		;;
	(*)
		CF_ADD_LIBDIR(/lib)
		;;
	esac
	;;
(sunos3*|sunos4*)
	if test "x$cf_cv_screen" = "xcurses_5lib"
	then
		if test -d /usr/5lib ; then
			CF_ADD_LIBDIR(/usr/5lib)
			CF_ADD_LIBS(-lcurses -ltermcap)
		fi
	fi
	ac_cv_func_initscr=yes
	;;
esac

if test ".$ac_cv_func_initscr" != .yes ; then
	cf_save_LIBS="$LIBS"

	if test ".${cf_cv_ncurses_version:-no}" != .no
	then
		cf_check_list="ncurses curses cursesX"
	else
		cf_check_list="cursesX curses ncurses"
	fi

	# Check for library containing tgoto.  Do this before curses library
	# because it may be needed to link the test-case for initscr.
	if test "x$cf_term_lib" = x
	then
		AC_CHECK_FUNC(tgoto,[cf_term_lib=predefined],[
			for cf_term_lib in $cf_check_list otermcap termcap tinfo termlib unknown
			do
				AC_CHECK_LIB($cf_term_lib,tgoto,[
					: "${cf_nculib_root:=$cf_term_lib}"
					break
				])
			done
		])
	fi

	# Check for library containing initscr
	test "$cf_term_lib" != predefined && test "$cf_term_lib" != unknown && LIBS="-l$cf_term_lib $cf_save_LIBS"
	if test "x$cf_curs_lib" = x
	then
		for cf_curs_lib in $cf_check_list xcurses jcurses pdcurses unknown
		do
			LIBS="-l$cf_curs_lib $cf_save_LIBS"
			if test "$cf_term_lib" = unknown || test "$cf_term_lib" = "$cf_curs_lib" ; then
				AC_MSG_CHECKING(if we can link with $cf_curs_lib library)
				AC_TRY_LINK([#include <${cf_cv_ncurses_header:-curses.h}>],
					[initscr()],
					[cf_result=yes],
					[cf_result=no])
				AC_MSG_RESULT($cf_result)
				test "$cf_result" = yes && break
			elif test "$cf_curs_lib" = "$cf_term_lib" ; then
				cf_result=no
			elif test "$cf_term_lib" != predefined ; then
				AC_MSG_CHECKING(if we need both $cf_curs_lib and $cf_term_lib libraries)
				AC_TRY_LINK([#include <${cf_cv_ncurses_header:-curses.h}>],
					[initscr(); tgoto((char *)0, 0, 0);],
					[cf_result=no],
					[
					LIBS="-l$cf_curs_lib -l$cf_term_lib $cf_save_LIBS"
					AC_TRY_LINK([#include <${cf_cv_ncurses_header:-curses.h}>],
						[initscr()],
						[cf_result=yes],
						[cf_result=error])
					])
				AC_MSG_RESULT($cf_result)
				test "$cf_result" != error && break
			fi
		done
	fi
	test "$cf_curs_lib" = unknown && AC_MSG_ERROR(no curses library found)
fi
fi

])dnl
dnl ---------------------------------------------------------------------------
dnl CF_CURSES_TERMCAP version: 12 updated: 2015/05/15 19:42:24
dnl -----------------
dnl Check if we should include  to pick up prototypes for termcap
dnl functions.  On terminfo systems, these are normally declared in ,
dnl but may be in .  We check for termcap.h as an alternate, but it
dnl isn't standard (usually associated with GNU termcap).
dnl
dnl The 'tgoto()' function is declared in both terminfo and termcap.
dnl
dnl See CF_TYPE_OUTCHAR for more details.
AC_DEFUN([CF_CURSES_TERMCAP],
[
AC_REQUIRE([CF_CURSES_TERM_H])
AC_CACHE_CHECK(if we should include curses.h or termcap.h, cf_cv_need_curses_h,[
cf_save_CPPFLAGS="$CPPFLAGS"
cf_cv_need_curses_h=no

for cf_t_opts in "" "NEED_TERMCAP_H"
do
for cf_c_opts in "" "NEED_CURSES_H"
do

    CPPFLAGS="$cf_save_CPPFLAGS $CHECK_DECL_FLAG"
    test -n "$cf_c_opts" && CPPFLAGS="$CPPFLAGS -D$cf_c_opts"
    test -n "$cf_t_opts" && CPPFLAGS="$CPPFLAGS -D$cf_t_opts"

    AC_TRY_LINK([/* $cf_c_opts $cf_t_opts */
$CHECK_DECL_HDRS],
	[char *x = (char *)tgoto("")],
	[test "$cf_cv_need_curses_h" = no && {
	     cf_cv_need_curses_h=maybe
	     cf_ok_c_opts=$cf_c_opts
	     cf_ok_t_opts=$cf_t_opts
	}],
	[echo "Recompiling with corrected call (C:$cf_c_opts, T:$cf_t_opts)" >&AC_FD_CC
	AC_TRY_LINK([
$CHECK_DECL_HDRS],
	[char *x = (char *)tgoto("",0,0)],
	[cf_cv_need_curses_h=yes
	 cf_ok_c_opts=$cf_c_opts
	 cf_ok_t_opts=$cf_t_opts])])

	CPPFLAGS="$cf_save_CPPFLAGS"
	test "$cf_cv_need_curses_h" = yes && break
done
	test "$cf_cv_need_curses_h" = yes && break
done

if test "$cf_cv_need_curses_h" != no ; then
	echo "Curses/termcap test = $cf_cv_need_curses_h (C:$cf_ok_c_opts, T:$cf_ok_t_opts)" >&AC_FD_CC
	if test -n "$cf_ok_c_opts" ; then
		if test -n "$cf_ok_t_opts" ; then
			cf_cv_need_curses_h=both
		else
			cf_cv_need_curses_h=curses.h
		fi
	elif test -n "$cf_ok_t_opts" ; then
		cf_cv_need_curses_h=termcap.h
	elif test "$cf_cv_term_header" != no ; then
		cf_cv_need_curses_h=term.h
	else
		cf_cv_need_curses_h=no
	fi
fi
])

case $cf_cv_need_curses_h in
(both)
	AC_DEFINE_UNQUOTED(NEED_CURSES_H,1,[Define to 1 if we must include curses.h])
	AC_DEFINE_UNQUOTED(NEED_TERMCAP_H,1,[Define to 1 if we must include termcap.h])
	;;
(curses.h)
	AC_DEFINE_UNQUOTED(NEED_CURSES_H,1,[Define to 1 if we must include curses.h])
	;;
(term.h)
	AC_DEFINE_UNQUOTED(NEED_TERM_H,1,[Define to 1 if we must include term.h])
	;;
(termcap.h)
	AC_DEFINE_UNQUOTED(NEED_TERMCAP_H,1,[Define to 1 if we must include termcap.h])
	;;
esac

])dnl
dnl ---------------------------------------------------------------------------
dnl CF_CURSES_TERM_H version: 15 updated: 2021/01/02 09:31:20
dnl ----------------
dnl SVr4 curses should have term.h as well (where it puts the definitions of
dnl the low-level interface).  This may not be true in old/broken implementations,
dnl as well as in misconfigured systems (e.g., gcc configured for Solaris 2.4
dnl running with Solaris 2.5.1).
AC_DEFUN([CF_CURSES_TERM_H],
[
AC_REQUIRE([CF_CURSES_CPPFLAGS])dnl

AC_CACHE_CHECK(for term.h, cf_cv_term_header,[

# If we found , look for , but always look
# for  if we do not find the variant.

cf_header_list="term.h ncurses/term.h ncursesw/term.h"

case "${cf_cv_ncurses_header:-curses.h}" in
(*/*)
	cf_header_item=`echo "${cf_cv_ncurses_header:-curses.h}" | sed -e 's%\..*%%' -e 's%/.*%/%'`term.h
	cf_header_list="$cf_header_item $cf_header_list"
	;;
esac

for cf_header in $cf_header_list
do
	AC_TRY_COMPILE([
#include <${cf_cv_ncurses_header:-curses.h}>
#include <${cf_header}>],
	[WINDOW *x; (void)x],
	[cf_cv_term_header=$cf_header
	 break],
	[cf_cv_term_header=no])
done

case "$cf_cv_term_header" in
(no)
	# If curses is ncurses, some packagers still mess it up by trying to make
	# us use GNU termcap.  This handles the most common case.
	for cf_header in ncurses/term.h ncursesw/term.h
	do
		AC_TRY_COMPILE([
#include <${cf_cv_ncurses_header:-curses.h}>
#ifdef NCURSES_VERSION
#include <${cf_header}>
#else
make an error
#endif],
			[WINDOW *x; (void)x],
			[cf_cv_term_header=$cf_header
			 break],
			[cf_cv_term_header=no])
	done
	;;
esac
])

case "$cf_cv_term_header" in
(term.h)
	AC_DEFINE(HAVE_TERM_H,1,[Define to 1 if we have term.h])
	;;
(ncurses/term.h)
	AC_DEFINE(HAVE_NCURSES_TERM_H,1,[Define to 1 if we have ncurses/term.h])
	;;
(ncursesw/term.h)
	AC_DEFINE(HAVE_NCURSESW_TERM_H,1,[Define to 1 if we have ncursesw/term.h])
	;;
esac
])dnl
dnl ---------------------------------------------------------------------------
dnl CF_CURSES_UNCTRL_H version: 8 updated: 2021/01/02 09:31:20
dnl ------------------
dnl Any X/Open curses implementation must have unctrl.h, but ncurses packages
dnl may put it in a subdirectory (along with ncurses' other headers, of
dnl course).  Packages which put the headers in inconsistent locations are
dnl broken).
AC_DEFUN([CF_CURSES_UNCTRL_H],
[
AC_REQUIRE([CF_CURSES_CPPFLAGS])dnl

AC_CACHE_CHECK(for unctrl.h, cf_cv_unctrl_header,[

# If we found , look for , but always look
# for  if we do not find the variant.

cf_header_list="unctrl.h ncurses/unctrl.h ncursesw/unctrl.h"

case "${cf_cv_ncurses_header:-curses.h}" in
(*/*)
	cf_header_item=`echo "${cf_cv_ncurses_header:-curses.h}" | sed -e 's%\..*%%' -e 's%/.*%/%'`unctrl.h
	cf_header_list="$cf_header_item $cf_header_list"
	;;
esac

for cf_header in $cf_header_list
do
	AC_TRY_COMPILE([
#include <${cf_cv_ncurses_header:-curses.h}>
#include <${cf_header}>],
	[WINDOW *x; (void)x],
	[cf_cv_unctrl_header=$cf_header
	 break],
	[cf_cv_unctrl_header=no])
done
])

case "$cf_cv_unctrl_header" in
(no)
	AC_MSG_WARN(unctrl.h header not found)
	;;
esac

case "$cf_cv_unctrl_header" in
(unctrl.h)
	AC_DEFINE(HAVE_UNCTRL_H,1,[Define to 1 if we have unctrl.h])
	;;
(ncurses/unctrl.h)
	AC_DEFINE(HAVE_NCURSES_UNCTRL_H,1,[Define to 1 if we have ncurses/unctrl.h])
	;;
(ncursesw/unctrl.h)
	AC_DEFINE(HAVE_NCURSESW_UNCTRL_H,1,[Define to 1 if we have ncursesw/unctrl.h])
	;;
esac
])dnl
dnl ---------------------------------------------------------------------------
dnl CF_DIRNAME version: 5 updated: 2020/12/31 20:19:42
dnl ----------
dnl "dirname" is not portable, so we fake it with a shell script.
AC_DEFUN([CF_DIRNAME],[$1=`echo "$2" | sed -e 's%/[[^/]]*$%%'`])dnl
dnl ---------------------------------------------------------------------------
dnl CF_DISABLE_ECHO version: 14 updated: 2021/09/04 06:35:04
dnl ---------------
dnl You can always use "make -n" to see the actual options, but it is hard to
dnl pick out/analyze warning messages when the compile-line is long.
dnl
dnl Sets:
dnl	ECHO_LT - symbol to control if libtool is verbose
dnl	ECHO_LD - symbol to prefix "cc -o" lines
dnl	RULE_CC - symbol to put before implicit "cc -c" lines (e.g., .c.o)
dnl	SHOW_CC - symbol to put before explicit "cc -c" lines
dnl	ECHO_CC - symbol to put before any "cc" line
dnl
AC_DEFUN([CF_DISABLE_ECHO],[
AC_MSG_CHECKING(if you want to see long compiling messages)
CF_ARG_DISABLE(echo,
	[  --disable-echo          do not display "compiling" commands],
	[
	ECHO_LT='--silent'
	ECHO_LD='@echo linking [$]@;'
	RULE_CC='@echo compiling [$]<'
	SHOW_CC='@echo compiling [$]@'
	ECHO_CC='@'
],[
	ECHO_LT=''
	ECHO_LD=''
	RULE_CC=''
	SHOW_CC=''
	ECHO_CC=''
])
AC_MSG_RESULT($enableval)
AC_SUBST(ECHO_LT)
AC_SUBST(ECHO_LD)
AC_SUBST(RULE_CC)
AC_SUBST(SHOW_CC)
AC_SUBST(ECHO_CC)
])dnl
dnl ---------------------------------------------------------------------------
dnl CF_DISABLE_RPATH_HACK version: 3 updated: 2021/01/05 20:14:44
dnl ---------------------
dnl The rpath-hack makes it simpler to build programs, particularly with the
dnl *BSD ports which may have essential libraries in unusual places.  But it
dnl can interfere with building an executable for the base system.  Use this
dnl option in that case.
AC_DEFUN([CF_DISABLE_RPATH_HACK],
[
AC_MSG_CHECKING(if rpath-hack should be disabled)
CF_ARG_DISABLE(rpath-hack,
	[  --disable-rpath-hack    don't add rpath options for additional libraries],
	[enable_rpath_hack=no],
	[enable_rpath_hack=yes])
dnl TODO - drop cf_disable_rpath_hack
if test "x$enable_rpath_hack" = xno; then cf_disable_rpath_hack=yes; else cf_disable_rpath_hack=no; fi
AC_MSG_RESULT($cf_disable_rpath_hack)

if test "$enable_rpath_hack" = yes ; then
	CF_RPATH_HACK
fi
])
dnl ---------------------------------------------------------------------------
dnl CF_ENABLE_NARROWPROTO version: 6 updated: 2020/12/31 18:40:20
dnl ---------------------
dnl If this is not set properly, Xaw's scrollbars will not work.
dnl The so-called "modular" configuration for X.org omits most of the
dnl configure checks that would be needed to provide compatibility with
dnl older X builds.  This one breaks things noticeably.
AC_DEFUN([CF_ENABLE_NARROWPROTO],
[
AC_MSG_CHECKING(if you want narrow prototypes for X libraries)

case `$ac_config_guess` in
(*freebsd*|*gnu*|*irix5*|*irix6*|*netbsd*|*openbsd*|*qnx*|*sco*|*sgi*)
	cf_default_narrowproto=yes
	;;
(*)
	cf_default_narrowproto=no
	;;
esac

CF_ARG_OPTION(narrowproto,
	[  --enable-narrowproto    enable narrow prototypes for X libraries],
	[enable_narrowproto=$enableval],
	[enable_narrowproto=$cf_default_narrowproto],
	[$cf_default_narrowproto])
AC_MSG_RESULT($enable_narrowproto)
])
dnl ---------------------------------------------------------------------------
dnl CF_ENABLE_WARNINGS version: 9 updated: 2021/01/05 19:40:50
dnl ------------------
dnl Configure-option to enable gcc warnings
dnl
dnl $1 = extra options to add, if supported
dnl $2 = option for checking attributes.  By default, this is done when
dnl      warnings are enabled.  For other values:
dnl      yes: always do this, e.g., to use in generated library-headers
dnl      no: never do this
AC_DEFUN([CF_ENABLE_WARNINGS],[
if test "$GCC" = yes || test "$GXX" = yes
then
CF_FIX_WARNINGS(CFLAGS)
CF_FIX_WARNINGS(CPPFLAGS)
CF_FIX_WARNINGS(LDFLAGS)
AC_MSG_CHECKING(if you want to turn on gcc warnings)
CF_ARG_ENABLE(warnings,
	[  --enable-warnings       test: turn on gcc compiler warnings],
	[enable_warnings=yes],
	[enable_warnings=no])
AC_MSG_RESULT($enable_warnings)
if test "$enable_warnings" = "yes"
then
	ifelse($2,,[CF_GCC_ATTRIBUTES])
	CF_GCC_WARNINGS($1)
fi
ifelse($2,yes,[CF_GCC_ATTRIBUTES])
fi
])dnl
dnl ---------------------------------------------------------------------------
dnl CF_ERRNO version: 5 updated: 1997/11/30 12:44:39
dnl --------
dnl Check if 'errno' is declared in 
AC_DEFUN([CF_ERRNO],
[
CF_CHECK_ERRNO(errno)
])dnl
dnl ---------------------------------------------------------------------------
dnl CF_FIND_LIBRARY version: 11 updated: 2021/01/02 09:31:20
dnl ---------------
dnl Look for a non-standard library, given parameters for AC_TRY_LINK.  We
dnl prefer a standard location, and use -L options only if we do not find the
dnl library in the standard library location(s).
dnl	$1 = library name
dnl	$2 = library class, usually the same as library name
dnl	$3 = includes
dnl	$4 = code fragment to compile/link
dnl	$5 = corresponding function-name
dnl	$6 = flag, nonnull if failure should not cause an error-exit
dnl
dnl Sets the variable "$cf_libdir" as a side-effect, so we can see if we had
dnl to use a -L option.
AC_DEFUN([CF_FIND_LIBRARY],
[
	eval 'cf_cv_have_lib_'"$1"'=no'
	cf_libdir=""
	AC_CHECK_FUNC($5,
		eval 'cf_cv_have_lib_'"$1"'=yes',[
		cf_save_LIBS="$LIBS"
		AC_MSG_CHECKING(for $5 in -l$1)
		LIBS="-l$1 $LIBS"
		AC_TRY_LINK([$3],[$4],
			[AC_MSG_RESULT(yes)
			 eval 'cf_cv_have_lib_'"$1"'=yes'
			],
			[AC_MSG_RESULT(no)
			CF_LIBRARY_PATH(cf_search,$2)
			for cf_libdir in $cf_search
			do
				AC_MSG_CHECKING(for -l$1 in $cf_libdir)
				LIBS="-L$cf_libdir -l$1 $cf_save_LIBS"
				AC_TRY_LINK([$3],[$4],
					[AC_MSG_RESULT(yes)
			 		 eval 'cf_cv_have_lib_'"$1"'=yes'
					 break],
					[AC_MSG_RESULT(no)
					 LIBS="$cf_save_LIBS"])
			done
			])
		])
eval 'cf_found_library="[$]cf_cv_have_lib_'"$1"\"
ifelse($6,,[
if test "$cf_found_library" = no ; then
	AC_MSG_ERROR(Cannot link $1 library)
fi
])
])dnl
dnl ---------------------------------------------------------------------------
dnl CF_FIND_LINKAGE version: 22 updated: 2020/12/31 20:19:42
dnl ---------------
dnl Find a library (specifically the linkage used in the code fragment),
dnl searching for it if it is not already in the library path.
dnl See also CF_ADD_SEARCHPATH.
dnl
dnl Parameters (4-on are optional):
dnl     $1 = headers for library entrypoint
dnl     $2 = code fragment for library entrypoint
dnl     $3 = the library name without the "-l" option or ".so" suffix.
dnl     $4 = action to perform if successful (default: update CPPFLAGS, etc)
dnl     $5 = action to perform if not successful
dnl     $6 = module name, if not the same as the library name
dnl     $7 = extra libraries
dnl
dnl Sets these variables:
dnl     $cf_cv_find_linkage_$3 - yes/no according to whether linkage is found
dnl     $cf_cv_header_path_$3 - include-directory if needed
dnl     $cf_cv_library_path_$3 - library-directory if needed
dnl     $cf_cv_library_file_$3 - library-file if needed, e.g., -l$3
AC_DEFUN([CF_FIND_LINKAGE],[

# If the linkage is not already in the $CPPFLAGS/$LDFLAGS configuration, these
# will be set on completion of the AC_TRY_LINK below.
cf_cv_header_path_$3=
cf_cv_library_path_$3=

CF_MSG_LOG([Starting [FIND_LINKAGE]($3,$6)])

cf_save_LIBS="$LIBS"

AC_TRY_LINK([$1],[$2],[
	cf_cv_find_linkage_$3=yes
	cf_cv_header_path_$3=/usr/include
	cf_cv_library_path_$3=/usr/lib
],[

LIBS="-l$3 $7 $cf_save_LIBS"

AC_TRY_LINK([$1],[$2],[
	cf_cv_find_linkage_$3=yes
	cf_cv_header_path_$3=/usr/include
	cf_cv_library_path_$3=/usr/lib
	cf_cv_library_file_$3="-l$3"
],[
	cf_cv_find_linkage_$3=no
	LIBS="$cf_save_LIBS"

	CF_VERBOSE(find linkage for $3 library)
	CF_MSG_LOG([Searching for headers in [FIND_LINKAGE]($3,$6)])

	cf_save_CPPFLAGS="$CPPFLAGS"
	cf_test_CPPFLAGS="$CPPFLAGS"

	CF_HEADER_PATH(cf_search,ifelse([$6],,[$3],[$6]))
	for cf_cv_header_path_$3 in $cf_search
	do
		if test -d "$cf_cv_header_path_$3" ; then
			CF_VERBOSE(... testing $cf_cv_header_path_$3)
			CPPFLAGS="$cf_save_CPPFLAGS"
			CF_APPEND_TEXT(CPPFLAGS,-I$cf_cv_header_path_$3)
			AC_TRY_COMPILE([$1],[$2],[
				CF_VERBOSE(... found $3 headers in $cf_cv_header_path_$3)
				cf_cv_find_linkage_$3=maybe
				cf_test_CPPFLAGS="$CPPFLAGS"
				break],[
				CPPFLAGS="$cf_save_CPPFLAGS"
				])
		fi
	done

	if test "$cf_cv_find_linkage_$3" = maybe ; then

		CF_MSG_LOG([Searching for $3 library in [FIND_LINKAGE]($3,$6)])

		cf_save_LIBS="$LIBS"
		cf_save_LDFLAGS="$LDFLAGS"

		ifelse([$6],,,[
		CPPFLAGS="$cf_test_CPPFLAGS"
		LIBS="-l$3 $7 $cf_save_LIBS"
		AC_TRY_LINK([$1],[$2],[
			CF_VERBOSE(... found $3 library in system)
			cf_cv_find_linkage_$3=yes])
			CPPFLAGS="$cf_save_CPPFLAGS"
			LIBS="$cf_save_LIBS"
			])

		if test "$cf_cv_find_linkage_$3" != yes ; then
			CF_LIBRARY_PATH(cf_search,$3)
			for cf_cv_library_path_$3 in $cf_search
			do
				if test -d "$cf_cv_library_path_$3" ; then
					CF_VERBOSE(... testing $cf_cv_library_path_$3)
					CPPFLAGS="$cf_test_CPPFLAGS"
					LIBS="-l$3 $7 $cf_save_LIBS"
					LDFLAGS="$cf_save_LDFLAGS -L$cf_cv_library_path_$3"
					AC_TRY_LINK([$1],[$2],[
					CF_VERBOSE(... found $3 library in $cf_cv_library_path_$3)
					cf_cv_find_linkage_$3=yes
					cf_cv_library_file_$3="-l$3"
					break],[
					CPPFLAGS="$cf_save_CPPFLAGS"
					LIBS="$cf_save_LIBS"
					LDFLAGS="$cf_save_LDFLAGS"
					])
				fi
			done
			CPPFLAGS="$cf_save_CPPFLAGS"
			LDFLAGS="$cf_save_LDFLAGS"
		fi

	else
		cf_cv_find_linkage_$3=no
	fi
	],$7)
])

LIBS="$cf_save_LIBS"

if test "$cf_cv_find_linkage_$3" = yes ; then
ifelse([$4],,[
	CF_ADD_INCDIR($cf_cv_header_path_$3)
	CF_ADD_LIBDIR($cf_cv_library_path_$3)
	CF_ADD_LIB($3)
],[$4])
else
ifelse([$5],,AC_MSG_WARN(Cannot find $3 library),[$5])
fi
])dnl
dnl ---------------------------------------------------------------------------
dnl CF_FIX_WARNINGS version: 3 updated: 2020/12/31 18:40:20
dnl ---------------
dnl Warning flags do not belong in CFLAGS, CPPFLAGS, etc.  Any of gcc's
dnl "-Werror" flags can interfere with configure-checks.  Those go into
dnl EXTRA_CFLAGS.
dnl
dnl $1 = variable name to repair
define([CF_FIX_WARNINGS],[
if test "$GCC" = yes || test "$GXX" = yes
then
	case [$]$1 in
	(*-Werror=*)
		CF_VERBOSE(repairing $1: [$]$1)
		cf_temp_flags=
		for cf_temp_scan in [$]$1
		do
			case "x$cf_temp_scan" in
			(x-Werror=*)
				CF_APPEND_TEXT(EXTRA_CFLAGS,$cf_temp_scan)
				;;
			(*)
				CF_APPEND_TEXT(cf_temp_flags,$cf_temp_scan)
				;;
			esac
		done
		$1="$cf_temp_flags"
		CF_VERBOSE(... fixed [$]$1)
		CF_VERBOSE(... extra $EXTRA_CFLAGS)
		;;
	esac
fi
AC_SUBST(EXTRA_CFLAGS)
])dnl
dnl ---------------------------------------------------------------------------
dnl CF_FP_ISREADY version: 4 updated: 2020/12/31 20:19:42
dnl -------------
dnl Test for the common variations of stdio structures that we can use to
dnl test if a character is available for reading.
AC_DEFUN([CF_FP_ISREADY],
[
AC_CACHE_CHECK(for file-pointer ready definition,
cf_cv_fp_isready,[
cf_cv_fp_isready=none
while true
do
	read definition
	test -z "$definition" && break
	echo "test-compile $definition" 1>&AC_FD_CC

	AC_TRY_COMPILE([
#include 
#define isready_c(p) $definition
],[int x = isready_c(stdin)],
	[echo "$definition" >conftest.env
	 break])

done <<'CF_EOF'
( (p)->_IO_read_ptr < (p)->_IO_read_end)
( (p)->__cnt > 0)
( (p)->__rptr < (p)->__rend)
( (p)->_cnt > 0)
( (p)->_gptr < (p)->_egptr)
( (p)->_r > 0)
( (p)->_rcount > 0)
( (p)->endr < (p)->endb)
CF_EOF

test -f conftest.env && cf_cv_fp_isready="`cat conftest.env`"

])

test "$cf_cv_fp_isready" != none && AC_DEFINE_UNQUOTED(isready_c(p),$cf_cv_fp_isready,[Define to 1 if stdio structures permit checking if character is ready])

])dnl
dnl ---------------------------------------------------------------------------
dnl CF_FUNC_DLSYM version: 4 updated: 2015/09/12 14:46:44
dnl -------------
dnl Test for dlsym() and related functions, as well as libdl.
dnl
dnl Sets
dnl	$cf_have_dlsym
dnl	$cf_have_libdl
AC_DEFUN([CF_FUNC_DLSYM],[
cf_have_dlsym=no
AC_CHECK_FUNC(dlsym,cf_have_dlsym=yes,[

cf_have_libdl=no
AC_CHECK_LIB(dl,dlsym,[
	cf_have_dlsym=yes
	cf_have_libdl=yes])])

if test "$cf_have_dlsym" = yes ; then
	test "$cf_have_libdl" = yes && { CF_ADD_LIB(dl) }

	AC_MSG_CHECKING(whether able to link to dl*() functions)
	AC_TRY_LINK([#include ],[
		void *obj;
		if ((obj = dlopen("filename", 0)) != 0) {
			if (dlsym(obj, "symbolname") == 0) {
			dlclose(obj);
			}
		}],[
		AC_DEFINE(HAVE_LIBDL,1,[Define to 1 if we have dl library])],[
		AC_MSG_ERROR(Cannot link test program for libdl)])
	AC_MSG_RESULT(ok)
else
	AC_MSG_ERROR(Cannot find dlsym function)
fi
])
dnl ---------------------------------------------------------------------------
dnl CF_GCC_ATTRIBUTES version: 24 updated: 2021/03/20 12:00:25
dnl -----------------
dnl Test for availability of useful gcc __attribute__ directives to quiet
dnl compiler warnings.  Though useful, not all are supported -- and contrary
dnl to documentation, unrecognized directives cause older compilers to barf.
AC_DEFUN([CF_GCC_ATTRIBUTES],
[AC_REQUIRE([AC_PROG_FGREP])dnl
AC_REQUIRE([CF_C11_NORETURN])dnl

if test "$GCC" = yes || test "$GXX" = yes
then
cat > conftest.i < "conftest.$ac_ext" <&AC_FD_CC

		case "$cf_attribute" in
		(printf)
			cf_printf_attribute=yes
			cat >conftest.h <conftest.h <conftest.h <>confdefs.h
			case "$cf_attribute" in
			(noreturn)
				AC_DEFINE_UNQUOTED(GCC_NORETURN,$cf_directive,[Define to noreturn-attribute for gcc])
				;;
			(printf)
				cf_value='/* nothing */'
				if test "$cf_printf_attribute" != no ; then
					cf_value='__attribute__((format(printf,fmt,var)))'
					AC_DEFINE(GCC_PRINTF,1,[Define to 1 if the compiler supports gcc-like printf attribute.])
				fi
				AC_DEFINE_UNQUOTED(GCC_PRINTFLIKE(fmt,var),$cf_value,[Define to printf-attribute for gcc])
				;;
			(scanf)
				cf_value='/* nothing */'
				if test "$cf_scanf_attribute" != no ; then
					cf_value='__attribute__((format(scanf,fmt,var)))'
					AC_DEFINE(GCC_SCANF,1,[Define to 1 if the compiler supports gcc-like scanf attribute.])
				fi
				AC_DEFINE_UNQUOTED(GCC_SCANFLIKE(fmt,var),$cf_value,[Define to sscanf-attribute for gcc])
				;;
			(unused)
				AC_DEFINE_UNQUOTED(GCC_UNUSED,$cf_directive,[Define to unused-attribute for gcc])
				;;
			esac
		fi
	done
else
	${FGREP-fgrep} define conftest.i >>confdefs.h
fi
rm -rf ./conftest*
fi
])dnl
dnl ---------------------------------------------------------------------------
dnl CF_GCC_OPT_RDYNAMIC version: 6 updated: 2020/12/31 20:19:42
dnl -------------------
dnl "Newer" versions of gcc support the -rdynamic option:
dnl		Pass the flag -export-dynamic to the ELF linker, on targets that
dnl		support it. This instructs the linker to add all symbols, not only
dnl		used ones, to the dynamic symbol table. This option is needed for
dnl		some uses of "dlopen" or to allow obtaining backtraces from within
dnl		a program.
dnl Check for the option, and add it to $CFLAGS if available.
AC_DEFUN([CF_GCC_OPT_RDYNAMIC],[

if test "x$CLANG_COMPILER" = "xyes"
then
	AC_MSG_WARN(clang may only pretend to honor gcc -rdynamic option)
else

AC_CACHE_CHECK([if $CC has -rdynamic option],cf_cv_gcc_opt_rdynamic,[

cf_save_CFLAGS="$CFLAGS"
CFLAGS="-Wall -rdynamic $CFLAGS"

# gcc usually does not return an error for unrecognized options.
AC_TRY_LINK([#include ],
	[printf("Hello");],
	[
	# refine check...
	case testing`eval "$ac_link" 2>&1` in
	(*unexpect*|*unrecog*)
		cf_cv_gcc_opt_rdynamic=no
		;;
	(*)
		cf_cv_gcc_opt_rdynamic=yes
		;;
	esac
	],
	[cf_cv_gcc_opt_rdynamic=no])

CFLAGS="$cf_save_CFLAGS"
])
fi

if test "$cf_cv_gcc_opt_rdynamic" = yes ; then
	CF_ADD_CFLAGS([-rdynamic])
fi
])dnl
dnl ---------------------------------------------------------------------------
dnl CF_GCC_VERSION version: 8 updated: 2019/09/07 13:38:36
dnl --------------
dnl Find version of gcc, and (because icc/clang pretend to be gcc without being
dnl compatible), attempt to determine if icc/clang is actually used.
AC_DEFUN([CF_GCC_VERSION],[
AC_REQUIRE([AC_PROG_CC])
GCC_VERSION=none
if test "$GCC" = yes ; then
	AC_MSG_CHECKING(version of $CC)
	GCC_VERSION="`${CC} --version 2>/dev/null | sed -e '2,$d' -e 's/^.*(GCC[[^)]]*) //' -e 's/^.*(Debian[[^)]]*) //' -e 's/^[[^0-9.]]*//' -e 's/[[^0-9.]].*//'`"
	test -z "$GCC_VERSION" && GCC_VERSION=unknown
	AC_MSG_RESULT($GCC_VERSION)
fi
CF_INTEL_COMPILER(GCC,INTEL_COMPILER,CFLAGS)
CF_CLANG_COMPILER(GCC,CLANG_COMPILER,CFLAGS)
])dnl
dnl ---------------------------------------------------------------------------
dnl CF_GCC_WARNINGS version: 41 updated: 2021/01/01 16:53:59
dnl ---------------
dnl Check if the compiler supports useful warning options.  There's a few that
dnl we don't use, simply because they're too noisy:
dnl
dnl	-Wconversion (useful in older versions of gcc, but not in gcc 2.7.x)
dnl	-Winline (usually not worthwhile)
dnl	-Wredundant-decls (system headers make this too noisy)
dnl	-Wtraditional (combines too many unrelated messages, only a few useful)
dnl	-Wwrite-strings (too noisy, but should review occasionally).  This
dnl		is enabled for ncurses using "--enable-const".
dnl	-pedantic
dnl
dnl Parameter:
dnl	$1 is an optional list of gcc warning flags that a particular
dnl		application might want to use, e.g., "no-unused" for
dnl		-Wno-unused
dnl Special:
dnl	If $with_ext_const is "yes", add a check for -Wwrite-strings
dnl
AC_DEFUN([CF_GCC_WARNINGS],
[
AC_REQUIRE([CF_GCC_VERSION])
if test "x$have_x" = xyes; then CF_CONST_X_STRING fi
cat > "conftest.$ac_ext" <],[
	#if __GLIBC__ > 0 && __GLIBC_MINOR__ >= 0
		return 0;
	#elif __NEWLIB__ > 0 && __NEWLIB_MINOR__ >= 0
		return 0;
	#else
	#	error not GNU C library
	#endif],
	[cf_cv_gnu_library=yes],
	[cf_cv_gnu_library=no])
])

if test x$cf_cv_gnu_library = xyes; then

	# With glibc 2.19 (13 years after this check was begun), _DEFAULT_SOURCE
	# was changed to help a little.  newlib incorporated the change about 4
	# years later.
	AC_CACHE_CHECK(if _DEFAULT_SOURCE can be used as a basis,cf_cv_gnu_library_219,[
		cf_save="$CPPFLAGS"
		CF_APPEND_TEXT(CPPFLAGS,-D_DEFAULT_SOURCE)
		AC_TRY_COMPILE([#include ],[
			#if (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 19) || (__GLIBC__ > 2)
				return 0;
			#elif (__NEWLIB__ == 2 && __NEWLIB_MINOR__ >= 4) || (__GLIBC__ > 3)
				return 0;
			#else
			#	error GNU C library __GLIBC__.__GLIBC_MINOR__ is too old
			#endif],
			[cf_cv_gnu_library_219=yes],
			[cf_cv_gnu_library_219=no])
		CPPFLAGS="$cf_save"
	])

	if test "x$cf_cv_gnu_library_219" = xyes; then
		cf_save="$CPPFLAGS"
		AC_CACHE_CHECK(if _XOPEN_SOURCE=$cf_gnu_xopen_source works with _DEFAULT_SOURCE,cf_cv_gnu_dftsrc_219,[
			CF_ADD_CFLAGS(-D_DEFAULT_SOURCE -D_XOPEN_SOURCE=$cf_gnu_xopen_source)
			AC_TRY_COMPILE([
				#include 
				#include 
				],[
				#if (_XOPEN_SOURCE >= $cf_gnu_xopen_source) && (MB_LEN_MAX > 1)
					return 0;
				#else
				#	error GNU C library is too old
				#endif],
				[cf_cv_gnu_dftsrc_219=yes],
				[cf_cv_gnu_dftsrc_219=no])
			])
		test "x$cf_cv_gnu_dftsrc_219" = "xyes" || CPPFLAGS="$cf_save"
	else
		cf_cv_gnu_dftsrc_219=maybe
	fi

	if test "x$cf_cv_gnu_dftsrc_219" != xyes; then

		AC_CACHE_CHECK(if we must define _GNU_SOURCE,cf_cv_gnu_source,[
		AC_TRY_COMPILE([#include ],[
			#ifndef _XOPEN_SOURCE
			#error	expected _XOPEN_SOURCE to be defined
			#endif],
			[cf_cv_gnu_source=no],
			[cf_save="$CPPFLAGS"
			 CF_ADD_CFLAGS(-D_GNU_SOURCE)
			 AC_TRY_COMPILE([#include ],[
				#ifdef _XOPEN_SOURCE
				#error	expected _XOPEN_SOURCE to be undefined
				#endif],
				[cf_cv_gnu_source=no],
				[cf_cv_gnu_source=yes])
			CPPFLAGS="$cf_save"
			])
		])

		if test "$cf_cv_gnu_source" = yes
		then
		AC_CACHE_CHECK(if we should also define _DEFAULT_SOURCE,cf_cv_default_source,[
			CF_APPEND_TEXT(CPPFLAGS,-D_GNU_SOURCE)
			AC_TRY_COMPILE([#include ],[
				#ifdef _DEFAULT_SOURCE
				#error	expected _DEFAULT_SOURCE to be undefined
				#endif],
				[cf_cv_default_source=no],
				[cf_cv_default_source=yes])
			])
			if test "$cf_cv_default_source" = yes
			then
				CF_APPEND_TEXT(CPPFLAGS,-D_DEFAULT_SOURCE)
			fi
		fi
	fi

fi
])dnl
dnl ---------------------------------------------------------------------------
dnl CF_HEADER_PATH version: 15 updated: 2021/01/01 13:31:04
dnl --------------
dnl Construct a search-list of directories for a nonstandard header-file
dnl
dnl Parameters
dnl	$1 = the variable to return as result
dnl	$2 = the package name
AC_DEFUN([CF_HEADER_PATH],
[
$1=

# collect the current set of include-directories from compiler flags
cf_header_path_list=""
if test -n "${CFLAGS}${CPPFLAGS}" ; then
	for cf_header_path in $CPPFLAGS $CFLAGS
	do
		case "$cf_header_path" in
		(-I*)
			cf_header_path=`echo ".$cf_header_path" |sed -e 's/^...//' -e 's,/include$,,'`
			CF_ADD_SUBDIR_PATH($1,$2,include,$cf_header_path,NONE)
			cf_header_path_list="$cf_header_path_list [$]$1"
			;;
		esac
	done
fi

# add the variations for the package we are looking for
CF_SUBDIR_PATH($1,$2,include)

test "$includedir" != NONE && \
test "$includedir" != "/usr/include" && \
test -d "$includedir" && {
	test -d "$includedir" &&    $1="[$]$1 $includedir"
	test -d "$includedir/$2" && $1="[$]$1 $includedir/$2"
}

test "$oldincludedir" != NONE && \
test "$oldincludedir" != "/usr/include" && \
test -d "$oldincludedir" && {
	test -d "$oldincludedir"    && $1="[$]$1 $oldincludedir"
	test -d "$oldincludedir/$2" && $1="[$]$1 $oldincludedir/$2"
}

$1="[$]$1 $cf_header_path_list"
])dnl
dnl ---------------------------------------------------------------------------
dnl CF_HEADER_RESOURCE version: 5 updated: 2012/10/06 11:17:15
dnl ------------------
dnl On SunOS, struct rusage is referred to in .  struct rusage is
dnl defined in .  On SCO v4, resource.h needs time.h, which we
dnl may have excluded.
AC_DEFUN([CF_HEADER_RESOURCE],[
AC_REQUIRE([CF_HEADER_SELECT])
AC_CACHE_CHECK(if we may include sys/resource.h with sys/wait.h,
cf_cv_resource_with_wait,[
AC_TRY_COMPILE([
#if defined(HAVE_SYS_TIME_H) && (defined(SELECT_WITH_TIME) || !(defined(HAVE_SELECT_H || defined(HAVE_SYS_SELECT_H))))
#include 
#ifdef TIME_WITH_SYS_TIME
# include 
#endif
#else
#include 
#endif
#include 
#include 
#include 
],[],[cf_cv_resource_with_wait=yes],[cf_cv_resource_with_wait=no])
])
test $cf_cv_resource_with_wait = yes && AC_DEFINE(RESOURCE_WITH_WAIT,1,[Define to 1 if we may include sys/resource.h with sys/wait.h])
])dnl
dnl ---------------------------------------------------------------------------
dnl CF_HEADER_SELECT version: 5 updated: 2012/10/06 11:17:15
dnl ----------------
dnl like AC_HEADER_TIME, check for conflicts:
dnl on SCO v4, sys/time.h conflicts with select.h
AC_DEFUN([CF_HEADER_SELECT],[
AC_REQUIRE([AC_HEADER_TIME])
AC_CACHE_CHECK(if we can include select.h with time.h,
cf_cv_select_with_time,[
AC_TRY_COMPILE([
#include 
#ifdef HAVE_SYS_TIME_H
#include 
#ifdef TIME_WITH_SYS_TIME
# include 
#endif
#else
#include 
#endif
#ifdef HAVE_SELECT
# ifdef HAVE_SELECT_H
# include 
# endif
# ifdef HAVE_SYS_SELECT_H
# include 
# endif
#endif
],[],[cf_cv_select_with_time=yes],[cf_cv_select_with_time=no])
])
test $cf_cv_select_with_time = yes && AC_DEFINE(SELECT_WITH_TIME,1,[Define to 1 if we can include select.h with time.h])
])dnl
dnl ---------------------------------------------------------------------------
dnl CF_HELP_MESSAGE version: 4 updated: 2019/12/31 08:53:54
dnl ---------------
dnl Insert text into the help-message, for readability, from AC_ARG_WITH.
AC_DEFUN([CF_HELP_MESSAGE],
[CF_ACVERSION_CHECK(2.53,[],[
AC_DIVERT_HELP($1)])dnl
])dnl
dnl ---------------------------------------------------------------------------
dnl CF_IMAKE_CFLAGS version: 34 updated: 2020/12/31 18:40:20
dnl ---------------
dnl Use imake to obtain compiler flags.  We could, in principle, write tests to
dnl get these, but if imake is properly configured there is no point in doing
dnl this.
dnl
dnl Parameters (used in constructing a sample Imakefile):
dnl	$1 = optional value to append to $IMAKE_CFLAGS
dnl	$2 = optional value to append to $IMAKE_LOADFLAGS
AC_DEFUN([CF_IMAKE_CFLAGS],
[
AC_PATH_PROGS(IMAKE,xmkmf imake)

if test -n "$IMAKE" ; then

case $IMAKE in
(*/imake)
	cf_imake_opts="-DUseInstalled=YES"
	;;
(*/util/xmkmf)
	# A single parameter tells xmkmf where the config-files are:
	cf_imake_opts="`echo "$IMAKE"|sed -e s,/config/util/xmkmf,,`"
	;;
(*)
	cf_imake_opts=
	;;
esac

# If it's installed properly, imake (or its wrapper, xmkmf) will point to the
# config directory.
if mkdir conftestdir; then
	CDPATH=; export CDPATH
	cf_makefile=`cd "$srcdir" || exit;pwd`/Imakefile
	cd conftestdir

	cat >fix_cflags.sed <<'CF_EOF'
s/\\//g
s/[[ 	]][[ 	]]*/ /g
s/"//g
:pack
s/\(=[[^ ]][[^ ]]*\) \([[^-]]\)/\1	\2/g
t pack
s/\(-D[[a-zA-Z0-9_]][[a-zA-Z0-9_]]*\)=\([[^\'0-9 ]][[^ ]]*\)/\1='\\"\2\\"'/g
s/^IMAKE[[ ]]/IMAKE_CFLAGS="/
s/	/ /g
s/$/"/
CF_EOF

	cat >fix_lflags.sed <<'CF_EOF'
s/^IMAKE[[ 	]]*/IMAKE_LOADFLAGS="/
s/$/"/
CF_EOF

	echo >./Imakefile
	test -f "$cf_makefile" && cat "$cf_makefile" >>./Imakefile

	cat >> ./Imakefile <<'CF_EOF'
findstddefs:
	@echo IMAKE ${ALLDEFINES}ifelse([$1],,,[ $1])       | sed -f fix_cflags.sed
	@echo IMAKE ${EXTRA_LOAD_FLAGS}ifelse([$2],,,[ $2]) | sed -f fix_lflags.sed
CF_EOF

	if ( $IMAKE "$cf_imake_opts" 1>/dev/null 2>&AC_FD_CC && test -f Makefile)
	then
		CF_VERBOSE(Using $IMAKE $cf_imake_opts)
	else
		# sometimes imake doesn't have the config path compiled in.  Find it.
		cf_config=
		for cf_libpath in $X_LIBS $LIBS ; do
			case "$cf_libpath" in
			(-L*)
				cf_libpath=`echo ".$cf_libpath" | sed -e 's/^...//'`
				cf_libpath="$cf_libpath/X11/config"
				if test -d "$cf_libpath" ; then
					cf_config="$cf_libpath"
					break
				fi
				;;
			esac
		done
		if test -z "$cf_config" ; then
			AC_MSG_WARN(Could not find imake config-directory)
		else
			cf_imake_opts="$cf_imake_opts -I$cf_config"
			if ( "$IMAKE" -v "$cf_imake_opts" 2>&AC_FD_CC)
			then
				CF_VERBOSE(Using $IMAKE $cf_config)
			else
				AC_MSG_WARN(Cannot run $IMAKE)
			fi
		fi
	fi

	# GNU make sometimes prints "make[1]: Entering...", which
	# would confuse us.
	eval "`make findstddefs 2>/dev/null | grep -v make`"

	cd ..
	rm -rf conftestdir

	# We use ${ALLDEFINES} rather than ${STD_DEFINES} because the former
	# declares XTFUNCPROTO there.  However, some vendors (e.g., SGI) have
	# modified it to support site.cf, adding a kludge for the /usr/include
	# directory.  Try to filter that out, otherwise gcc won't find its
	# headers.
	if test -n "$GCC" ; then
	    if test -n "$IMAKE_CFLAGS" ; then
		cf_nostdinc=""
		cf_std_incl=""
		cf_cpp_opts=""
		for cf_opt in $IMAKE_CFLAGS
		do
		    case "$cf_opt" in
		    (-nostdinc)
			cf_nostdinc="$cf_opt"
			;;
		    (-I/usr/include)
			cf_std_incl="$cf_opt"
			;;
		    (*)
			cf_cpp_opts="$cf_cpp_opts $cf_opt"
			;;
		    esac
		done
		if test -z "$cf_nostdinc" ; then
		    IMAKE_CFLAGS="$cf_cpp_opts $cf_std_incl"
		elif test -z "$cf_std_incl" ; then
		    IMAKE_CFLAGS="$cf_cpp_opts $cf_nostdinc"
		else
		    CF_VERBOSE(suppressed \"$cf_nostdinc\" and \"$cf_std_incl\")
		    IMAKE_CFLAGS="$cf_cpp_opts"
		fi
	    fi
	fi
fi

# Some imake configurations define PROJECTROOT with an empty value.  Remove
# the empty definition.
case $IMAKE_CFLAGS in
(*-DPROJECTROOT=/*)
	;;
(*)
	IMAKE_CFLAGS=`echo "$IMAKE_CFLAGS" |sed -e "s,-DPROJECTROOT=[[ 	]], ,"`
	;;
esac

fi

CF_VERBOSE(IMAKE_CFLAGS $IMAKE_CFLAGS)
CF_VERBOSE(IMAKE_LOADFLAGS $IMAKE_LOADFLAGS)

AC_SUBST(IMAKE_CFLAGS)
AC_SUBST(IMAKE_LOADFLAGS)
])dnl
dnl ---------------------------------------------------------------------------
dnl CF_INSTALL_OPTS version: 2 updated: 2018/08/18 12:19:21
dnl ---------------
dnl prompt for/fill-in useful install-program options
AC_DEFUN([CF_INSTALL_OPTS],
[
CF_INSTALL_OPT_S
CF_INSTALL_OPT_P
CF_INSTALL_OPT_O
])dnl
dnl ---------------------------------------------------------------------------
dnl CF_INSTALL_OPT_O version: 3 updated: 2020/12/31 20:19:42
dnl ----------------
dnl Almost all "install" programs default to the current user's ownership.
dnl Almost - MINIX is an exception.
AC_DEFUN([CF_INSTALL_OPT_O],
[
AC_MSG_CHECKING(if install needs to be told about ownership)
case `$ac_config_guess` in
(*minix)
	with_install_o=yes
	;;
(*)
	with_install_o=no
	;;
esac

AC_MSG_RESULT($with_install_o)
if test "x$with_install_o" = xyes
then
	INSTALL_OPT_O="`id root|sed -e 's/uid=[[0-9]]*(/ -o /' -e 's/gid=[[0-9]]*(/ -g /' -e 's/ [[^=[:space:]]][[^=[:space:]]]*=.*/ /' -e 's/)//g'`"
else
	INSTALL_OPT_O=
fi

AC_SUBST(INSTALL_OPT_O)
])dnl
dnl ---------------------------------------------------------------------------
dnl CF_INSTALL_OPT_P version: 3 updated: 2021/01/01 13:31:04
dnl ----------------
dnl Some install-programs accept a "-p" option to preserve file modification
dnl timestamps.  That can be useful as an install option, as well as a way to
dnl avoid the need for ranlib after copying a static archive.
AC_DEFUN([CF_INSTALL_OPT_P],
[
: "${INSTALL:=install}"
AC_CACHE_CHECK(if install accepts -p option, cf_cv_install_p,[
	rm -rf ./conftest*
	date >conftest.in
	mkdir conftest.out
	sleep 3
	if $INSTALL -p conftest.in conftest.out 2>/dev/null
	then
		if test -f conftest.out/conftest.in
		then
			test conftest.in -nt conftest.out/conftest.in 2>conftest.err && \
			test conftest.out/conftest.in -nt conftest.in 2>conftest.err
			if test -s conftest.err
			then
				cf_cv_install_p=no
			else
				cf_cv_install_p=yes
			fi
		else
			cf_cv_install_p=no
		fi
	else
		cf_cv_install_p=no
	fi
	rm -rf ./conftest*
])
])dnl
dnl ---------------------------------------------------------------------------
dnl CF_INSTALL_OPT_S version: 3 updated: 2021/01/05 19:23:48
dnl ----------------
dnl By default, we should strip executables which are installed, but leave the
dnl ability to suppress that for unit-testing.
AC_DEFUN([CF_INSTALL_OPT_S],
[
AC_MSG_CHECKING(if you want to install stripped executables)
CF_ARG_DISABLE(stripping,
	[  --disable-stripping     do not strip (debug info) installed executables],
	[enable_stripping=no],
	[enable_stripping=yes])
AC_MSG_RESULT($enable_stripping)

if test "$enable_stripping" = yes
then
	INSTALL_OPT_S="-s"
else
	INSTALL_OPT_S=
fi
AC_SUBST(INSTALL_OPT_S)
])dnl
dnl ---------------------------------------------------------------------------
dnl CF_INTEL_COMPILER version: 8 updated: 2021/01/01 16:53:59
dnl -----------------
dnl Check if the given compiler is really the Intel compiler for Linux.  It
dnl tries to imitate gcc, but does not return an error when it finds a mismatch
dnl between prototypes, e.g., as exercised by CF_MISSING_CHECK.
dnl
dnl This macro should be run "soon" after AC_PROG_CC or AC_PROG_CPLUSPLUS, to
dnl ensure that it is not mistaken for gcc/g++.  It is normally invoked from
dnl the wrappers for gcc and g++ warnings.
dnl
dnl $1 = GCC (default) or GXX
dnl $2 = INTEL_COMPILER (default) or INTEL_CPLUSPLUS
dnl $3 = CFLAGS (default) or CXXFLAGS
AC_DEFUN([CF_INTEL_COMPILER],[
AC_REQUIRE([AC_CANONICAL_HOST])
ifelse([$2],,INTEL_COMPILER,[$2])=no

if test "$ifelse([$1],,[$1],GCC)" = yes ; then
	case "$host_os" in
	(linux*|gnu*)
		AC_MSG_CHECKING(if this is really Intel ifelse([$1],GXX,C++,C) compiler)
		cf_save_CFLAGS="$ifelse([$3],,CFLAGS,[$3])"
		ifelse([$3],,CFLAGS,[$3])="$ifelse([$3],,CFLAGS,[$3]) -no-gcc"
		AC_TRY_COMPILE([],[
#ifdef __INTEL_COMPILER
#else
make an error
#endif
],[ifelse([$2],,INTEL_COMPILER,[$2])=yes
cf_save_CFLAGS="$cf_save_CFLAGS -we147"
],[])
		ifelse([$3],,CFLAGS,[$3])="$cf_save_CFLAGS"
		AC_MSG_RESULT($ifelse([$2],,INTEL_COMPILER,[$2]))
		;;
	esac
fi
])dnl
dnl ---------------------------------------------------------------------------
dnl CF_KILLPG version: 7 updated: 2020/09/08 19:32:19
dnl ---------
dnl Note: relies upon AC_FUNC_SETPGRP, but cannot use AC_REQUIRE, since that
dnl messes up the messages...
define([CF_KILLPG],
[
if test "$cross_compiling" = yes ; then
	AC_CHECK_FUNC(setpgrp,[
	AC_TRY_COMPILE([
#ifdef HAVE_UNISTD_H
#include 
#endif
#include 
#include 
],[
    (void) setpgrp();
],
	[AC_DEFINE(SETPGRP_VOID)])])
else
	AC_FUNC_SETPGRP
fi

if test "$cross_compiling" = yes ; then
	AC_CHECK_FUNC(getpgrp,[
	AC_TRY_COMPILE([
#include 
#include 
],[
    (void) getpgrp();
],
	[AC_DEFINE(GETPGRP_VOID)])])
else
	AC_FUNC_GETPGRP
fi

AC_CACHE_CHECK(if killpg is needed, cf_cv_need_killpg,[
AC_TRY_RUN([
#ifdef HAVE_STDLIB_H
#include 
#endif
#ifdef HAVE_UNISTD_H
#include 
#endif
#include 
#include 
RETSIGTYPE
handler(s)
    int s;
{
    exit(0);
}

int main(void)
{
#ifdef SETPGRP_VOID
    (void) setpgrp();
#else
    (void) setpgrp(0,0);
#endif
    (void) signal(SIGINT, handler);
    (void) kill(-getpid(), SIGINT);
    ${cf_cv_main_return:-return}(1);
}],
	[cf_cv_need_killpg=no],
	[cf_cv_need_killpg=yes],
	[cf_cv_need_killpg=unknown])
])

test $cf_cv_need_killpg = yes && AC_DEFINE(HAVE_KILLPG)
])dnl
dnl ---------------------------------------------------------------------------
dnl CF_LARGEFILE version: 12 updated: 2020/03/19 20:23:48
dnl ------------
dnl Add checks for large file support.
AC_DEFUN([CF_LARGEFILE],[
ifdef([AC_FUNC_FSEEKO],[
	AC_SYS_LARGEFILE
	if test "$enable_largefile" != no ; then
	AC_FUNC_FSEEKO

	# Normally we would collect these definitions in the config.h,
	# but (like _XOPEN_SOURCE), some environments rely on having these
	# defined before any of the system headers are included.  Another
	# case comes up with C++, e.g., on AIX the compiler compiles the
	# header files by themselves before looking at the body files it is
	# told to compile.  For ncurses, those header files do not include
	# the config.h
	if test "$ac_cv_sys_large_files" != no
	then
		CF_APPEND_TEXT(CPPFLAGS,-D_LARGE_FILES)
	fi
	if test "$ac_cv_sys_largefile_source" != no
	then
		CF_APPEND_TEXT(CPPFLAGS,-D_LARGEFILE_SOURCE)
	fi
	if test "$ac_cv_sys_file_offset_bits" != no
	then
		CF_APPEND_TEXT(CPPFLAGS,-D_FILE_OFFSET_BITS=$ac_cv_sys_file_offset_bits)
	fi

	AC_CACHE_CHECK(whether to use struct dirent64, cf_cv_struct_dirent64,[
		AC_TRY_COMPILE([
#pragma GCC diagnostic error "-Wincompatible-pointer-types"
#include 
#include 
		],[
		/* if transitional largefile support is setup, this is true */
		extern struct dirent64 * readdir(DIR *);
		struct dirent64 *x = readdir((DIR *)0);
		struct dirent *y = readdir((DIR *)0);
		int z = x - y;
		(void)z;
		],
		[cf_cv_struct_dirent64=yes],
		[cf_cv_struct_dirent64=no])
	])
	test "$cf_cv_struct_dirent64" = yes && AC_DEFINE(HAVE_STRUCT_DIRENT64,1,[Define to 1 if we have struct dirent64])
	fi
])
])
dnl ---------------------------------------------------------------------------
dnl CF_LD_RPATH_OPT version: 9 updated: 2021/01/01 13:31:04
dnl ---------------
dnl For the given system and compiler, find the compiler flags to pass to the
dnl loader to use the "rpath" feature.
AC_DEFUN([CF_LD_RPATH_OPT],
[
AC_REQUIRE([CF_CHECK_CACHE])

LD_RPATH_OPT=
if test "x$cf_cv_enable_rpath" != xno
then
	AC_MSG_CHECKING(for an rpath option)
	case "$cf_cv_system_name" in
	(irix*)
		if test "$GCC" = yes; then
			LD_RPATH_OPT="-Wl,-rpath,"
		else
			LD_RPATH_OPT="-rpath "
		fi
		;;
	(linux*|gnu*|k*bsd*-gnu|freebsd*)
		LD_RPATH_OPT="-Wl,-rpath,"
		;;
	(openbsd[[2-9]].*|mirbsd*)
		LD_RPATH_OPT="-Wl,-rpath,"
		;;
	(dragonfly*)
		LD_RPATH_OPT="-rpath "
		;;
	(netbsd*)
		LD_RPATH_OPT="-Wl,-rpath,"
		;;
	(osf*|mls+*)
		LD_RPATH_OPT="-rpath "
		;;
	(solaris2*)
		LD_RPATH_OPT="-R"
		;;
	(*)
		;;
	esac
	AC_MSG_RESULT($LD_RPATH_OPT)

	case "x$LD_RPATH_OPT" in
	(x-R*)
		AC_MSG_CHECKING(if we need a space after rpath option)
		cf_save_LIBS="$LIBS"
		CF_ADD_LIBS(${LD_RPATH_OPT}$libdir)
		AC_TRY_LINK(, , cf_rpath_space=no, cf_rpath_space=yes)
		LIBS="$cf_save_LIBS"
		AC_MSG_RESULT($cf_rpath_space)
		test "$cf_rpath_space" = yes && LD_RPATH_OPT="$LD_RPATH_OPT "
		;;
	esac
fi
])dnl
dnl ---------------------------------------------------------------------------
dnl CF_LEX_CHAR_CLASSES version: 7 updated: 2020/01/05 20:03:16
dnl -------------------
dnl Check if the lex/flex program accepts character-classes, i.e., [:alpha:],
dnl which are a POSIX feature.
AC_DEFUN([CF_LEX_CHAR_CLASSES],[
AC_MSG_CHECKING(if $LEX supports character classes)
cat >conftest.l <conftest.l <conftest.l <conftest.l <&1 |${FGREP-fgrep} flex >/dev/null )
then
	AC_MSG_RESULT(yes)
	AC_MSG_CHECKING(version of $LEX)
	LEX_VERSION="`$LEX --version &1 | sed -e 's/^.* \([[0-9]]\)/\1/;s/ .*$//;s/^[[^0-9]]*//'`"
	AC_MSG_RESULT($LEX_VERSION)
else
	AC_MSG_RESULT(no)
fi

])dnl
dnl ---------------------------------------------------------------------------
dnl CF_LIBRARY_PATH version: 11 updated: 2021/01/01 13:31:04
dnl ---------------
dnl Construct a search-list of directories for a nonstandard library-file
dnl
dnl Parameters
dnl	$1 = the variable to return as result
dnl	$2 = the package name
AC_DEFUN([CF_LIBRARY_PATH],
[
$1=
cf_library_path_list=""
if test -n "${LDFLAGS}${LIBS}" ; then
	for cf_library_path in $LDFLAGS $LIBS
	do
		case "$cf_library_path" in
		(-L*)
			cf_library_path=`echo ".$cf_library_path" |sed -e 's/^...//' -e 's,/lib$,,'`
			CF_ADD_SUBDIR_PATH($1,$2,lib,$cf_library_path,NONE)
			cf_library_path_list="$cf_library_path_list [$]$1"
			;;
		esac
	done
fi

CF_SUBDIR_PATH($1,$2,lib)

$1="$cf_library_path_list [$]$1"
])dnl
dnl ---------------------------------------------------------------------------
dnl CF_LIB_PREFIX version: 14 updated: 2021/01/01 13:31:04
dnl -------------
dnl Compute the library-prefix for the given host system
dnl $1 = variable to set
define([CF_LIB_PREFIX],
[
	case "$cf_cv_system_name" in
	(OS/2*|os2*)
		if test "$DFT_LWR_MODEL" = libtool; then
			LIB_PREFIX='lib'
		else
			LIB_PREFIX=''
		fi
		;;
	(*-msvc*)
		LIB_PREFIX=''
		;;
	(*)	LIB_PREFIX='lib'
		;;
	esac
ifelse($1,,,[$1=$LIB_PREFIX])
	AC_SUBST(LIB_PREFIX)
])dnl
dnl ---------------------------------------------------------------------------
dnl CF_LINK_PREFIX version: 2 updated: 2021/01/06 16:19:35
dnl --------------
dnl Use xterm's plink.sh script as a link-prefix, to trim unneeded libraries.
dnl This is optional since in some obscure cases of weak-linkage it may be
dnl possible to trim too much.
AC_DEFUN([CF_LINK_PREFIX],
[
AC_MSG_CHECKING(if you want to trim unneeded libraries)
CF_ARG_DISABLE(link-prefix,
	[  --disable-link-prefix   do not trim unneeded libraries from link command],
	[enable_link_prefix=no],
	[enable_link_prefix=yes])
AC_MSG_RESULT($enable_link_prefix)
if test $enable_link_prefix = yes
then
	LINK_PREFIX='$(SHELL) $(top_srcdir)/plink.sh'
else
	LINK_PREFIX=
fi
AC_SUBST(LINK_PREFIX)
])dnl
dnl ---------------------------------------------------------------------------
dnl CF_LOCALE version: 6 updated: 2021/01/02 09:31:20
dnl ---------
dnl Check if we have setlocale() and its header, 
dnl The optional parameter $1 tells what to do if we do have locale support.
AC_DEFUN([CF_LOCALE],
[
AC_MSG_CHECKING(for setlocale())
AC_CACHE_VAL(cf_cv_locale,[
AC_TRY_LINK([#include ],
	[setlocale(LC_ALL, "")],
	[cf_cv_locale=yes],
	[cf_cv_locale=no])
	])
AC_MSG_RESULT($cf_cv_locale)
test "$cf_cv_locale" = yes && { ifelse($1,,AC_DEFINE(LOCALE,1,[Define to 1 if we have locale support]),[$1]) }
])dnl
dnl ---------------------------------------------------------------------------
dnl CF_MAKEFLAGS version: 21 updated: 2021/09/04 06:47:34
dnl ------------
dnl Some 'make' programs support ${MAKEFLAGS}, some ${MFLAGS}, to pass 'make'
dnl options to lower-levels.  It is very useful for "make -n" -- if we have it.
dnl (GNU 'make' does both, something POSIX 'make', which happens to make the
dnl ${MAKEFLAGS} variable incompatible because it adds the assignments :-)
AC_DEFUN([CF_MAKEFLAGS],
[AC_REQUIRE([AC_PROG_FGREP])dnl

AC_CACHE_CHECK(for makeflags variable, cf_cv_makeflags,[
	cf_cv_makeflags=''
	for cf_option in '-${MAKEFLAGS}' '${MFLAGS}'
	do
		cat >cf_makeflags.tmp </dev/null | ${FGREP-fgrep} -v "ing directory" | sed -e 's,[[ 	]]*$,,'`
		case "$cf_result" in
		(.*k|.*kw)
			cf_result="`${MAKE:-make} -k -f cf_makeflags.tmp CC=cc 2>/dev/null`"
			case "$cf_result" in
			(.*CC=*)	cf_cv_makeflags=
				;;
			(*)	cf_cv_makeflags=$cf_option
				;;
			esac
			break
			;;
		(.-)
			;;
		(*)
			CF_MSG_LOG(given option \"$cf_option\", no match \"$cf_result\")
			;;
		esac
	done
	rm -f cf_makeflags.tmp
])

AC_SUBST(cf_cv_makeflags)
])dnl
dnl ---------------------------------------------------------------------------
dnl CF_MAKE_PHONY version: 3 updated: 2021/01/08 16:08:21
dnl -------------
dnl Check if the make-program handles a ".PHONY" target, e.g,. a target which
dnl acts as a placeholder.
dnl
dnl The ".PHONY" feature was proposed in 2011 here
dnl     https://www.austingroupbugs.net/view.php?id=523
dnl and is scheduled for release in P1003.1 Issue 8 (late 2022).
dnl
dnl This is not supported by SVr4 make (or SunOS 4, 4.3SD, etc), but works with
dnl a few others (i.e., GNU make and the non-POSIX "BSD" make):
dnl
dnl + This is a GNU make feature (since April 1988, but in turn from binutils,
dnl   date unspecified).
dnl
dnl + It was adopted in NetBSD make in June 1995.
dnl
dnl + The other BSD make programs are derived from the NetBSD make (and for
dnl   that reason are not actually different "implementations").
dnl
dnl + Some features of NetBSD make were actually adapted from pmake, which
dnl   began as a modified GNU make starting in 1993.
dnl
dnl + Version 3.8 of the dmake program in January 1992 also implemented this
dnl   GNU make extension, but is less well known than the BSD make.
AC_DEFUN([CF_MAKE_PHONY],[
AC_CACHE_CHECK(for \".PHONY\" make-support, cf_cv_make_PHONY,[
	rm -rf conftest*
	(
		mkdir conftest || exit 1
		cd conftest
		cat >makefile <<'CF_EOF'
.PHONY: always
DATA=0
always:	always.out
	@echo "** making [$]@ [$](DATA)"
once: once.out
	@echo "** making [$]@ [$](DATA)"
always.out:
	@echo "** making [$]@ [$](DATA)"
	echo [$](DATA) > [$]@
once.out:
	@echo "** making [$]@ [$](DATA)"
	echo [$](DATA) > [$]@
CF_EOF
		for cf_data in 1 2 3
		do
			${MAKE:-make} always DATA=$cf_data
			${MAKE:-make} once   DATA=$cf_data
			${MAKE:-make} -t always once
			if test -f always ; then
				echo "no (case 1)" > ../conftest.tmp
			elif test ! -f always.out ; then
				echo "no (case 2)" > ../conftest.tmp
			elif test ! -f once.out ; then
				echo "no (case 3)" > ../conftest.tmp
			elif ! cmp -s always.out once.out ; then
				echo "no (case 4)" > ../conftest.tmp
				diff always.out once.out
			else
				cf_check="`cat always.out`"
				if test "x$cf_check" != "x$cf_data" ; then
					echo "no (case 5)" > ../conftest.tmp
				else
					echo yes > ../conftest.tmp
					rm -f ./*.out
					continue
				fi
			fi
			break
		done
	) >&AC_FD_CC 2>&1
	cf_cv_make_PHONY="`cat conftest.tmp`"
	rm -rf conftest*
])
MAKE_NO_PHONY="#"
MAKE_PHONY="#"
test "x$cf_cv_make_PHONY" = xyes && MAKE_PHONY=
test "x$cf_cv_make_PHONY" != xyes && MAKE_NO_PHONY=
AC_SUBST(MAKE_NO_PHONY)
AC_SUBST(MAKE_PHONY)
])dnl
dnl ---------------------------------------------------------------------------
dnl CF_MAKE_TAGS version: 6 updated: 2010/10/23 15:52:32
dnl ------------
dnl Generate tags/TAGS targets for makefiles.  Do not generate TAGS if we have
dnl a monocase filesystem.
AC_DEFUN([CF_MAKE_TAGS],[
AC_REQUIRE([CF_MIXEDCASE_FILENAMES])

AC_CHECK_PROGS(CTAGS, exctags ctags)
AC_CHECK_PROGS(ETAGS, exetags etags)

AC_CHECK_PROG(MAKE_LOWER_TAGS, ${CTAGS:-ctags}, yes, no)

if test "$cf_cv_mixedcase" = yes ; then
	AC_CHECK_PROG(MAKE_UPPER_TAGS, ${ETAGS:-etags}, yes, no)
else
	MAKE_UPPER_TAGS=no
fi

if test "$MAKE_UPPER_TAGS" = yes ; then
	MAKE_UPPER_TAGS=
else
	MAKE_UPPER_TAGS="#"
fi

if test "$MAKE_LOWER_TAGS" = yes ; then
	MAKE_LOWER_TAGS=
else
	MAKE_LOWER_TAGS="#"
fi

AC_SUBST(CTAGS)
AC_SUBST(ETAGS)

AC_SUBST(MAKE_UPPER_TAGS)
AC_SUBST(MAKE_LOWER_TAGS)
])dnl
dnl ---------------------------------------------------------------------------
dnl CF_MERGE_EXTRA_CFLAGS version: 2 updated: 2021/01/02 09:31:20
dnl ---------------------
dnl CF_FIX_WARNINGS moves problematic flags into EXTRA_CFLAGS, but some scripts
dnl may depend on being able to override that variable at build-time.  Move it
dnl all back.
define([CF_MERGE_EXTRA_CFLAGS],[
if test "$GCC" = yes || test "$GXX" = yes
then
	CF_APPEND_TEXT(CFLAGS,$EXTRA_CFLAGS)
	EXTRA_CFLAGS=
fi
])
dnl ---------------------------------------------------------------------------
dnl CF_MISSING_CHECK version: 7 updated: 2020/12/31 20:19:42
dnl ----------------
dnl
AC_DEFUN([CF_MISSING_CHECK],
[
AC_MSG_CHECKING([for missing \"$1\" extern])
AC_CACHE_VAL([cf_cv_func_$1],[
cf_save_CPPFLAGS="$CPPFLAGS"
CPPFLAGS="$CPPFLAGS $CHECK_DECL_FLAG"
AC_TRY_LINK([
$CHECK_DECL_HDRS

#undef $1
struct zowie { int a; double b; struct zowie *c; char d; };
extern struct zowie *$1();
],
[
#ifdef HAVE_LIBXT		/* needed for SunOS 4.0.3 or 4.1 */
XtToolkitInitialize();
#endif
],
[eval 'cf_cv_func_'"$1"'=yes'],
[eval 'cf_cv_func_'"$1"'=no'])
CPPFLAGS="$cf_save_CPPFLAGS"
])
eval 'cf_result="$cf_cv_func_'"$1"\"
AC_MSG_RESULT($cf_result)
test "$cf_result" = yes && AC_DEFINE_UNQUOTED(MISSING_EXTERN_$2)
])dnl
dnl ---------------------------------------------------------------------------
dnl CF_MISSING_EXTERN version: 3 updated: 1997/09/06 15:25:32
dnl -----------------
dnl
AC_DEFUN([CF_MISSING_EXTERN],
[for ac_func in $1
do
CF_UPPER(ac_tr_func,$ac_func)
CF_MISSING_CHECK(${ac_func}, ${ac_tr_func})dnl
done
])dnl
dnl ---------------------------------------------------------------------------
dnl CF_MIXEDCASE_FILENAMES version: 9 updated: 2021/01/01 16:53:59
dnl ----------------------
dnl Check if the file-system supports mixed-case filenames.  If we're able to
dnl create a lowercase name and see it as uppercase, it doesn't support that.
AC_DEFUN([CF_MIXEDCASE_FILENAMES],
[
AC_CACHE_CHECK(if filesystem supports mixed-case filenames,cf_cv_mixedcase,[
if test "$cross_compiling" = yes ; then
	case "$target_alias" in
	(*-os2-emx*|*-msdosdjgpp*|*-cygwin*|*-msys*|*-mingw*|*-uwin*|darwin*)
		cf_cv_mixedcase=no
		;;
	(*)
		cf_cv_mixedcase=yes
		;;
	esac
else
	rm -f conftest CONFTEST
	echo test >conftest
	if test -f CONFTEST ; then
		cf_cv_mixedcase=no
	else
		cf_cv_mixedcase=yes
	fi
	rm -f conftest CONFTEST
fi
])
test "$cf_cv_mixedcase" = yes && AC_DEFINE(MIXEDCASE_FILENAMES,1,[Define to 1 if filesystem supports mixed-case filenames.])
])dnl
dnl ---------------------------------------------------------------------------
dnl CF_MKSTEMP version: 11 updated: 2021/01/01 13:31:04
dnl ----------
dnl Check for a working mkstemp.  This creates two files, checks that they are
dnl successfully created and distinct (AmigaOS apparently fails on the last).
AC_DEFUN([CF_MKSTEMP],[
AC_CHECK_HEADERS( \
unistd.h \
)
AC_CACHE_CHECK(for working mkstemp, cf_cv_func_mkstemp,[
rm -rf ./conftest*
AC_TRY_RUN([
#include 
#ifdef HAVE_UNISTD_H
#include 
#endif
#include 
#include 
#include 
#include 
int main(void)
{
	char *tmpl = "conftestXXXXXX";
	char name[2][80];
	int n;
	int result = 0;
	int fd;
	struct stat sb;

	umask(077);
	for (n = 0; n < 2; ++n) {
		strcpy(name[n], tmpl);
		if ((fd = mkstemp(name[n])) >= 0) {
			if (!strcmp(name[n], tmpl)
			 || stat(name[n], &sb) != 0
			 || (sb.st_mode & S_IFMT) != S_IFREG
			 || (sb.st_mode & 077) != 0) {
				result = 1;
			}
			close(fd);
		}
	}
	if (result == 0
	 && !strcmp(name[0], name[1]))
		result = 1;
	${cf_cv_main_return:-return}(result);
}
],[cf_cv_func_mkstemp=yes
],[cf_cv_func_mkstemp=no
],[cf_cv_func_mkstemp=maybe])
])
if test "x$cf_cv_func_mkstemp" = xmaybe ; then
	AC_CHECK_FUNC(mkstemp)
fi
if test "x$cf_cv_func_mkstemp" = xyes || test "x$ac_cv_func_mkstemp" = xyes ; then
	AC_DEFINE(HAVE_MKSTEMP,1,[Define to 1 if mkstemp() is available and working.])
fi
])dnl
dnl ---------------------------------------------------------------------------
dnl CF_MSG_LOG version: 5 updated: 2010/10/23 15:52:32
dnl ----------
dnl Write a debug message to config.log, along with the line number in the
dnl configure script.
AC_DEFUN([CF_MSG_LOG],[
echo "${as_me:-configure}:__oline__: testing $* ..." 1>&AC_FD_CC
])dnl
dnl ---------------------------------------------------------------------------
dnl CF_NCURSES_CC_CHECK version: 5 updated: 2020/12/31 20:19:42
dnl -------------------
dnl Check if we can compile with ncurses' header file
dnl $1 is the cache variable to set
dnl $2 is the header-file to include
dnl $3 is the root name (ncurses or ncursesw)
AC_DEFUN([CF_NCURSES_CC_CHECK],[
	AC_TRY_COMPILE([
]ifelse($3,ncursesw,[
#define _XOPEN_SOURCE_EXTENDED
#undef  HAVE_LIBUTF8_H	/* in case we used CF_UTF8_LIB */
#define HAVE_LIBUTF8_H	/* to force ncurses' header file to use cchar_t */
])[
#include <$2>],[
#ifdef NCURSES_VERSION
]ifelse($3,ncursesw,[
#ifndef WACS_BSSB
	make an error
#endif
])[
printf("%s\\n", NCURSES_VERSION);
#else
#ifdef __NCURSES_H
printf("old\\n");
#else
	make an error
#endif
#endif
	]
	,[$1=$2]
	,[$1=no])
])dnl
dnl ---------------------------------------------------------------------------
dnl CF_NCURSES_CONFIG version: 28 updated: 2021/08/28 15:20:37
dnl -----------------
dnl Tie together the configure-script macros for ncurses, preferring these in
dnl order:
dnl a) ".pc" files for pkg-config, using $NCURSES_CONFIG_PKG
dnl b) the "-config" script from ncurses, using $NCURSES_CONFIG
dnl c) just plain libraries
dnl
dnl $1 is the root library name (default: "ncurses")
AC_DEFUN([CF_NCURSES_CONFIG],[
AC_REQUIRE([CF_PKG_CONFIG])
cf_ncuconfig_root=ifelse($1,,ncurses,$1)
cf_have_ncuconfig=no

if test "x${PKG_CONFIG:=none}" != xnone; then
	AC_MSG_CHECKING(pkg-config for $cf_ncuconfig_root)
	if "$PKG_CONFIG" --exists $cf_ncuconfig_root ; then
		AC_MSG_RESULT(yes)

		AC_MSG_CHECKING(if the $cf_ncuconfig_root package files work)
		cf_have_ncuconfig=unknown

		cf_save_CFLAGS="$CFLAGS"
		cf_save_CPPFLAGS="$CPPFLAGS"
		cf_save_LIBS="$LIBS"

		cf_pkg_cflags="`$PKG_CONFIG --cflags $cf_ncuconfig_root`"
		cf_pkg_libs="`$PKG_CONFIG --libs $cf_ncuconfig_root`"

		# while -W for passing linker flags is prevalent, it is not "standard".
		# At least one wrapper for c89/c99 (in Apple's xcode) has its own
		# incompatible _and_ non-standard -W option which gives an error.  Work
		# around that pitfall.
		case "x${CC}@@${cf_pkg_libs}@${cf_pkg_cflags}" in
		(x*c[[89]]9@@*-W*)
			CF_ADD_CFLAGS($cf_pkg_cflags)
			CF_ADD_LIBS($cf_pkg_libs)

			AC_TRY_LINK([#include <${cf_cv_ncurses_header:-curses.h}>],
				[initscr(); mousemask(0,0); tigetstr((char *)0);],
				[AC_TRY_RUN([#include <${cf_cv_ncurses_header:-curses.h}>
					int main(void)
					{ const char *xx = curses_version(); return (xx == 0); }],
					[cf_test_ncuconfig=yes],
					[cf_test_ncuconfig=no],
					[cf_test_ncuconfig=maybe])],
				[cf_test_ncuconfig=no])

			CFLAGS="$cf_save_CFLAGS"
			CPPFLAGS="$cf_save_CPPFLAGS"
			LIBS="$cf_save_LIBS"

			if test "x$cf_test_ncuconfig" != xyes; then
				cf_temp=`echo "x$cf_pkg_cflags" | sed -e s/^x// -e 's/-W[[^ 	]]*//g'`
				cf_pkg_cflags="$cf_temp"
				cf_temp=`echo "x$cf_pkg_libs" | sed -e s/^x// -e 's/-W[[^ 	]]*//g'`
				cf_pkg_libs="$cf_temp"
			fi
			;;
		esac

		CF_APPEND_CFLAGS($cf_pkg_cflags)
		CF_ADD_LIBS($cf_pkg_libs)

		AC_TRY_LINK([#include <${cf_cv_ncurses_header:-curses.h}>],
			[initscr(); mousemask(0,0); tigetstr((char *)0);],
			[AC_TRY_RUN([#include <${cf_cv_ncurses_header:-curses.h}>
				int main(void)
				{ const char *xx = curses_version(); return (xx == 0); }],
				[cf_have_ncuconfig=yes],
				[cf_have_ncuconfig=no],
				[cf_have_ncuconfig=maybe])],
			[cf_have_ncuconfig=no])
		AC_MSG_RESULT($cf_have_ncuconfig)
		test "$cf_have_ncuconfig" = maybe && cf_have_ncuconfig=yes
		if test "$cf_have_ncuconfig" != "yes"
		then
			CPPFLAGS="$cf_save_CPPFLAGS"
			LIBS="$cf_save_LIBS"
			NCURSES_CONFIG_PKG=none
		else
			AC_DEFINE(NCURSES,1,[Define to 1 if we are using ncurses headers/libraries])
			NCURSES_CONFIG_PKG=$cf_ncuconfig_root
			CF_TERM_HEADER
		fi

	else
		AC_MSG_RESULT(no)
		NCURSES_CONFIG_PKG=none
	fi
else
	NCURSES_CONFIG_PKG=none
fi

if test "x$cf_have_ncuconfig" = "xno"; then
	cf_ncurses_config="${cf_ncuconfig_root}${NCURSES_CONFIG_SUFFIX}-config"; echo "Looking for ${cf_ncurses_config}"

	CF_ACVERSION_CHECK(2.52,
		[AC_CHECK_TOOLS(NCURSES_CONFIG, ${cf_ncurses_config} ${cf_ncuconfig_root}6-config ${cf_ncuconfig_root}6-config ${cf_ncuconfig_root}5-config, none)],
		[AC_PATH_PROGS(NCURSES_CONFIG,  ${cf_ncurses_config} ${cf_ncuconfig_root}6-config ${cf_ncuconfig_root}6-config ${cf_ncuconfig_root}5-config, none)])

	if test "$NCURSES_CONFIG" != none ; then

		CF_APPEND_CFLAGS(`$NCURSES_CONFIG --cflags`)
		CF_ADD_LIBS(`$NCURSES_CONFIG --libs`)

		# even with config script, some packages use no-override for curses.h
		CF_CURSES_HEADER(ifelse($1,,ncurses,$1))

		dnl like CF_NCURSES_CPPFLAGS
		AC_DEFINE(NCURSES,1,[Define to 1 if we are using ncurses headers/libraries])

		dnl like CF_NCURSES_LIBS
		CF_UPPER(cf_nculib_ROOT,HAVE_LIB$cf_ncuconfig_root)
		AC_DEFINE_UNQUOTED($cf_nculib_ROOT)

		dnl like CF_NCURSES_VERSION
		cf_cv_ncurses_version="`$NCURSES_CONFIG --version`"

	else

		CF_NCURSES_CPPFLAGS(ifelse($1,,ncurses,$1))
		CF_NCURSES_LIBS(ifelse($1,,ncurses,$1))

	fi
else
	NCURSES_CONFIG=none
fi
])dnl
dnl ---------------------------------------------------------------------------
dnl CF_NCURSES_CPPFLAGS version: 22 updated: 2021/01/02 09:31:20
dnl -------------------
dnl Look for the SVr4 curses clone 'ncurses' in the standard places, adjusting
dnl the CPPFLAGS variable so we can include its header.
dnl
dnl The header files may be installed as either curses.h, or ncurses.h (would
dnl be obsolete, except that some packagers prefer this name to distinguish it
dnl from a "native" curses implementation).  If not installed for overwrite,
dnl the curses.h file would be in an ncurses subdirectory (e.g.,
dnl /usr/include/ncurses), but someone may have installed overwriting the
dnl vendor's curses.  Only very old versions (pre-1.9.2d, the first autoconf'd
dnl version) of ncurses don't define either __NCURSES_H or NCURSES_VERSION in
dnl the header.
dnl
dnl If the installer has set $CFLAGS or $CPPFLAGS so that the ncurses header
dnl is already in the include-path, don't even bother with this, since we cannot
dnl easily determine which file it is.  In this case, it has to be .
dnl
dnl The optional parameter gives the root name of the library, in case it is
dnl not installed as the default curses library.  That is how the
dnl wide-character version of ncurses is installed.
AC_DEFUN([CF_NCURSES_CPPFLAGS],
[AC_REQUIRE([CF_WITH_CURSES_DIR])

AC_PROVIDE([CF_CURSES_CPPFLAGS])dnl
cf_ncuhdr_root=ifelse($1,,ncurses,$1)

test -n "$cf_cv_curses_dir" && \
test "$cf_cv_curses_dir" != "no" && { \
  CF_ADD_INCDIR($cf_cv_curses_dir/include/$cf_ncuhdr_root)
}

AC_CACHE_CHECK(for $cf_ncuhdr_root header in include-path, cf_cv_ncurses_h,[
	cf_header_list="$cf_ncuhdr_root/curses.h $cf_ncuhdr_root/ncurses.h"
	{ test "$cf_ncuhdr_root" = ncurses || test "$cf_ncuhdr_root" = ncursesw; } && cf_header_list="$cf_header_list curses.h ncurses.h"
	for cf_header in $cf_header_list
	do
		CF_NCURSES_CC_CHECK(cf_cv_ncurses_h,$cf_header,$1)
		test "$cf_cv_ncurses_h" != no && break
	done
])

CF_NCURSES_HEADER
CF_TERM_HEADER

# some applications need this, but should check for NCURSES_VERSION
AC_DEFINE(NCURSES,1,[Define to 1 if we are using ncurses headers/libraries])

CF_NCURSES_VERSION
])dnl
dnl ---------------------------------------------------------------------------
dnl CF_NCURSES_HEADER version: 7 updated: 2021/01/04 19:33:05
dnl -----------------
dnl Find a "curses" header file, e.g,. "curses.h", or one of the more common
dnl variations of ncurses' installs.
dnl
dnl See also CF_CURSES_HEADER, which sets the same cache variable.
AC_DEFUN([CF_NCURSES_HEADER],[

if test "$cf_cv_ncurses_h" != no ; then
	cf_cv_ncurses_header=$cf_cv_ncurses_h
else

AC_CACHE_CHECK(for $cf_ncuhdr_root include-path, cf_cv_ncurses_h2,[
	test -n "$verbose" && echo
	CF_HEADER_PATH(cf_search,$cf_ncuhdr_root)
	test -n "$verbose" && echo "search path $cf_search"
	cf_save2_CPPFLAGS="$CPPFLAGS"
	for cf_incdir in $cf_search
	do
		CF_ADD_INCDIR($cf_incdir)
		for cf_header in \
			ncurses.h \
			curses.h
		do
			CF_NCURSES_CC_CHECK(cf_cv_ncurses_h2,$cf_header,$1)
			if test "$cf_cv_ncurses_h2" != no ; then
				cf_cv_ncurses_h2=$cf_incdir/$cf_header
				test -n "$verbose" && echo $ECHO_N "	... found $ECHO_C" 1>&AC_FD_MSG
				break
			fi
			test -n "$verbose" && echo "	... tested $cf_incdir/$cf_header" 1>&AC_FD_MSG
		done
		CPPFLAGS="$cf_save2_CPPFLAGS"
		test "$cf_cv_ncurses_h2" != no && break
	done
	test "$cf_cv_ncurses_h2" = no && AC_MSG_ERROR(not found)
	])

	CF_DIRNAME(cf_1st_incdir,$cf_cv_ncurses_h2)
	cf_cv_ncurses_header="`basename "$cf_cv_ncurses_h2"`"
	if test "`basename "$cf_1st_incdir"`" = "$cf_ncuhdr_root" ; then
		cf_cv_ncurses_header="$cf_ncuhdr_root/$cf_cv_ncurses_header"
	fi
	CF_ADD_INCDIR($cf_1st_incdir)

fi

# Set definitions to allow ifdef'ing for ncurses.h

case "$cf_cv_ncurses_header" in
(*ncurses.h)
	AC_DEFINE(HAVE_NCURSES_H,1,[Define to 1 if we have ncurses.h])
	;;
esac

case "$cf_cv_ncurses_header" in
(ncurses/curses.h|ncurses/ncurses.h)
	AC_DEFINE(HAVE_NCURSES_NCURSES_H,1,[Define to 1 if we have ncurses/ncurses.h])
	;;
(ncursesw/curses.h|ncursesw/ncurses.h)
	AC_DEFINE(HAVE_NCURSESW_NCURSES_H,1,[Define to 1 if we have ncursesw/ncurses.h])
	;;
esac

])dnl
dnl ---------------------------------------------------------------------------
dnl CF_NCURSES_LIBS version: 21 updated: 2021/09/04 06:37:12
dnl ---------------
dnl Look for the ncurses library.  This is a little complicated on Linux,
dnl because it may be linked with the gpm (general purpose mouse) library.
dnl Some distributions have gpm linked with (bsd) curses, which makes it
dnl unusable with ncurses.  However, we don't want to link with gpm unless
dnl ncurses has a dependency, since gpm is normally set up as a shared library,
dnl and the linker will record a dependency.
dnl
dnl The optional parameter gives the root name of the library, in case it is
dnl not installed as the default curses library.  That is how the
dnl wide-character version of ncurses is installed.
AC_DEFUN([CF_NCURSES_LIBS],
[AC_REQUIRE([CF_NCURSES_CPPFLAGS])

cf_nculib_root=ifelse($1,,ncurses,$1)
	# This works, except for the special case where we find gpm, but
	# ncurses is in a nonstandard location via $LIBS, and we really want
	# to link gpm.
cf_ncurses_LIBS=""
cf_ncurses_SAVE="$LIBS"
AC_CHECK_LIB(gpm,Gpm_Open,
	[AC_CHECK_LIB(gpm,initscr,
		[LIBS="$cf_ncurses_SAVE"],
		[cf_ncurses_LIBS="-lgpm"])])

case "$host_os" in
(freebsd*)
	# This is only necessary if you are linking against an obsolete
	# version of ncurses (but it should do no harm, since it is static).
	if test "$cf_nculib_root" = ncurses ; then
		AC_CHECK_LIB(mytinfo,tgoto,[cf_ncurses_LIBS="-lmytinfo $cf_ncurses_LIBS"])
	fi
	;;
esac

CF_ADD_LIBS($cf_ncurses_LIBS)

if test -n "$cf_cv_curses_dir" && test "$cf_cv_curses_dir" != "no"
then
	CF_ADD_LIBS(-l$cf_nculib_root)
else
	CF_FIND_LIBRARY($cf_nculib_root,$cf_nculib_root,
		[#include <${cf_cv_ncurses_header:-curses.h}>],
		[initscr()],
		initscr)
fi

if test -n "$cf_ncurses_LIBS" ; then
	AC_MSG_CHECKING(if we can link $cf_nculib_root without $cf_ncurses_LIBS)
	cf_ncurses_SAVE="$LIBS"
	for p in $cf_ncurses_LIBS ; do
		q=`echo "$LIBS" | sed -e "s%$p %%" -e "s%$p$%%"`
		if test "$q" != "$LIBS" ; then
			LIBS="$q"
		fi
	done
	AC_TRY_LINK([#include <${cf_cv_ncurses_header:-curses.h}>],
		[initscr(); mousemask(0,0); tigetstr((char *)0);],
		[AC_MSG_RESULT(yes)],
		[AC_MSG_RESULT(no)
		 LIBS="$cf_ncurses_SAVE"])
fi

CF_UPPER(cf_nculib_ROOT,HAVE_LIB$cf_nculib_root)
AC_DEFINE_UNQUOTED($cf_nculib_ROOT)
])dnl
dnl ---------------------------------------------------------------------------
dnl CF_NCURSES_VERSION version: 16 updated: 2020/12/31 20:19:42
dnl ------------------
dnl Check for the version of ncurses, to aid in reporting bugs, etc.
dnl Call CF_CURSES_CPPFLAGS first, or CF_NCURSES_CPPFLAGS.  We don't use
dnl AC_REQUIRE since that does not work with the shell's if/then/else/fi.
AC_DEFUN([CF_NCURSES_VERSION],
[
AC_REQUIRE([CF_CURSES_CPPFLAGS])dnl
AC_CACHE_CHECK(for ncurses version, cf_cv_ncurses_version,[
	cf_cv_ncurses_version=no
	cf_tempfile=out$$
	rm -f "$cf_tempfile"
	AC_TRY_RUN([
#include <${cf_cv_ncurses_header:-curses.h}>
#include 
int main(void)
{
	FILE *fp = fopen("$cf_tempfile", "w");
#ifdef NCURSES_VERSION
# ifdef NCURSES_VERSION_PATCH
	fprintf(fp, "%s.%d\\n", NCURSES_VERSION, NCURSES_VERSION_PATCH);
# else
	fprintf(fp, "%s\\n", NCURSES_VERSION);
# endif
#else
# ifdef __NCURSES_H
	fprintf(fp, "old\\n");
# else
	make an error
# endif
#endif
	${cf_cv_main_return:-return}(0);
}],[
	cf_cv_ncurses_version=`cat $cf_tempfile`],,[

	# This will not work if the preprocessor splits the line after the
	# Autoconf token.  The 'unproto' program does that.
	cat > "conftest.$ac_ext" <
#undef Autoconf
#ifdef NCURSES_VERSION
Autoconf NCURSES_VERSION
#else
#ifdef __NCURSES_H
Autoconf "old"
#endif
;
#endif
EOF
	cf_try="$ac_cpp conftest.$ac_ext 2>&AC_FD_CC | grep '^Autoconf ' >conftest.out"
	AC_TRY_EVAL(cf_try)
	if test -f conftest.out ; then
		cf_out=`sed -e 's%^Autoconf %%' -e 's%^[[^"]]*"%%' -e 's%".*%%' conftest.out`
		test -n "$cf_out" && cf_cv_ncurses_version="$cf_out"
		rm -f conftest.out
	fi
])
	rm -f "$cf_tempfile"
])
test "$cf_cv_ncurses_version" = no || AC_DEFINE(NCURSES,1,[Define to 1 if we are using ncurses headers/libraries])
])dnl
dnl ---------------------------------------------------------------------------
dnl CF_NO_LEAKS_OPTION version: 9 updated: 2021/06/13 19:45:41
dnl ------------------
dnl see CF_WITH_NO_LEAKS
dnl
dnl $1 = option/name
dnl $2 = help-text
dnl $3 = symbol to define if the option is set
dnl $4 = additional actions to take if the option is set
AC_DEFUN([CF_NO_LEAKS_OPTION],[
AC_MSG_CHECKING(if you want to use $1 for testing)
AC_ARG_WITH($1,
	[$2],
	[case "x$withval" in
	(x|xno) ;;
	(*)
		: "${with_cflags:=-g}"
		: "${enable_leaks:=no}"
		with_$1=yes
		AC_DEFINE_UNQUOTED($3,1,"Define to 1 if you want to use $1 for testing.")ifelse([$4],,[
	 $4
])
		;;
	esac],
	[with_$1=])
AC_MSG_RESULT(${with_$1:-no})

case ".$with_cflags" in
(.*-g*)
	case .$CFLAGS in
	(.*-g*)
		;;
	(*)
		CF_ADD_CFLAGS([-g])
		;;
	esac
	;;
esac
])dnl
dnl ---------------------------------------------------------------------------
dnl CF_PATHSEP version: 8 updated: 2021/01/01 13:31:04
dnl ----------
dnl Provide a value for the $PATH and similar separator (or amend the value
dnl as provided in autoconf 2.5x).
AC_DEFUN([CF_PATHSEP],
[
	AC_MSG_CHECKING(for PATH separator)
	case "$cf_cv_system_name" in
	(os2*)	PATH_SEPARATOR=';'  ;;
	(*)	${PATH_SEPARATOR:=':'}  ;;
	esac
ifelse([$1],,,[$1=$PATH_SEPARATOR])
	AC_SUBST(PATH_SEPARATOR)
	AC_MSG_RESULT($PATH_SEPARATOR)
])dnl
dnl ---------------------------------------------------------------------------
dnl CF_PATH_SYNTAX version: 18 updated: 2020/12/31 18:40:20
dnl --------------
dnl Check the argument to see that it looks like a pathname.  Rewrite it if it
dnl begins with one of the prefix/exec_prefix variables, and then again if the
dnl result begins with 'NONE'.  This is necessary to work around autoconf's
dnl delayed evaluation of those symbols.
AC_DEFUN([CF_PATH_SYNTAX],[
if test "x$prefix" != xNONE; then
	cf_path_syntax="$prefix"
else
	cf_path_syntax="$ac_default_prefix"
fi

case ".[$]$1" in
(.\[$]\(*\)*|.\'*\'*)
	;;
(..|./*|.\\*)
	;;
(.[[a-zA-Z]]:[[\\/]]*) # OS/2 EMX
	;;
(.\[$]\{*prefix\}*|.\[$]\{*dir\}*)
	eval $1="[$]$1"
	case ".[$]$1" in
	(.NONE/*)
		$1=`echo "[$]$1" | sed -e s%NONE%$cf_path_syntax%`
		;;
	esac
	;;
(.no|.NONE/*)
	$1=`echo "[$]$1" | sed -e s%NONE%$cf_path_syntax%`
	;;
(*)
	ifelse([$2],,[AC_MSG_ERROR([expected a pathname, not \"[$]$1\"])],$2)
	;;
esac
])dnl
dnl ---------------------------------------------------------------------------
dnl CF_PKG_CONFIG version: 12 updated: 2021/10/10 20:18:09
dnl -------------
dnl Check for the package-config program, unless disabled by command-line.
dnl
dnl Sets $PKG_CONFIG to the pathname of the pkg-config program.
AC_DEFUN([CF_PKG_CONFIG],
[
AC_MSG_CHECKING(if you want to use pkg-config)
AC_ARG_WITH(pkg-config,
	[  --with-pkg-config{=path} enable/disable use of pkg-config],
	[cf_pkg_config=$withval],
	[cf_pkg_config=yes])
AC_MSG_RESULT($cf_pkg_config)

case "$cf_pkg_config" in
(no)
	PKG_CONFIG=none
	;;
(yes)
	CF_ACVERSION_CHECK(2.52,
		[AC_PATH_TOOL(PKG_CONFIG, pkg-config, none)],
		[AC_PATH_PROG(PKG_CONFIG, pkg-config, none)])
	;;
(*)
	PKG_CONFIG=$withval
	;;
esac

test -z "$PKG_CONFIG" && PKG_CONFIG=none
if test "$PKG_CONFIG" != none ; then
	CF_PATH_SYNTAX(PKG_CONFIG)
elif test "x$cf_pkg_config" != xno ; then
	AC_MSG_WARN(pkg-config is not installed)
fi

AC_SUBST(PKG_CONFIG)
])dnl
dnl ---------------------------------------------------------------------------
dnl CF_POSIX_C_SOURCE version: 11 updated: 2018/12/31 20:46:17
dnl -----------------
dnl Define _POSIX_C_SOURCE to the given level, and _POSIX_SOURCE if needed.
dnl
dnl	POSIX.1-1990				_POSIX_SOURCE
dnl	POSIX.1-1990 and			_POSIX_SOURCE and
dnl		POSIX.2-1992 C-Language			_POSIX_C_SOURCE=2
dnl		Bindings Option
dnl	POSIX.1b-1993				_POSIX_C_SOURCE=199309L
dnl	POSIX.1c-1996				_POSIX_C_SOURCE=199506L
dnl	X/Open 2000				_POSIX_C_SOURCE=200112L
dnl
dnl Parameters:
dnl	$1 is the nominal value for _POSIX_C_SOURCE
AC_DEFUN([CF_POSIX_C_SOURCE],
[AC_REQUIRE([CF_POSIX_VISIBLE])dnl

if test "$cf_cv_posix_visible" = no; then

cf_POSIX_C_SOURCE=ifelse([$1],,199506L,[$1])

cf_save_CFLAGS="$CFLAGS"
cf_save_CPPFLAGS="$CPPFLAGS"

CF_REMOVE_DEFINE(cf_trim_CFLAGS,$cf_save_CFLAGS,_POSIX_C_SOURCE)
CF_REMOVE_DEFINE(cf_trim_CPPFLAGS,$cf_save_CPPFLAGS,_POSIX_C_SOURCE)

AC_CACHE_CHECK(if we should define _POSIX_C_SOURCE,cf_cv_posix_c_source,[
	CF_MSG_LOG(if the symbol is already defined go no further)
	AC_TRY_COMPILE([#include ],[
#ifndef _POSIX_C_SOURCE
make an error
#endif],
	[cf_cv_posix_c_source=no],
	[cf_want_posix_source=no
	 case .$cf_POSIX_C_SOURCE in
	 (.[[12]]??*)
		cf_cv_posix_c_source="-D_POSIX_C_SOURCE=$cf_POSIX_C_SOURCE"
		;;
	 (.2)
		cf_cv_posix_c_source="-D_POSIX_C_SOURCE=$cf_POSIX_C_SOURCE"
		cf_want_posix_source=yes
		;;
	 (.*)
		cf_want_posix_source=yes
		;;
	 esac
	 if test "$cf_want_posix_source" = yes ; then
		AC_TRY_COMPILE([#include ],[
#ifdef _POSIX_SOURCE
make an error
#endif],[],
		cf_cv_posix_c_source="$cf_cv_posix_c_source -D_POSIX_SOURCE")
	 fi
	 CF_MSG_LOG(ifdef from value $cf_POSIX_C_SOURCE)
	 CFLAGS="$cf_trim_CFLAGS"
	 CPPFLAGS="$cf_trim_CPPFLAGS"
	 CF_APPEND_TEXT(CPPFLAGS,$cf_cv_posix_c_source)
	 CF_MSG_LOG(if the second compile does not leave our definition intact error)
	 AC_TRY_COMPILE([#include ],[
#ifndef _POSIX_C_SOURCE
make an error
#endif],,
	 [cf_cv_posix_c_source=no])
	 CFLAGS="$cf_save_CFLAGS"
	 CPPFLAGS="$cf_save_CPPFLAGS"
	])
])

if test "$cf_cv_posix_c_source" != no ; then
	CFLAGS="$cf_trim_CFLAGS"
	CPPFLAGS="$cf_trim_CPPFLAGS"
	CF_ADD_CFLAGS($cf_cv_posix_c_source)
fi

fi # cf_cv_posix_visible

])dnl
dnl ---------------------------------------------------------------------------
dnl CF_POSIX_VISIBLE version: 1 updated: 2018/12/31 20:46:17
dnl ----------------
dnl POSIX documents test-macros which an application may set before any system
dnl headers are included to make features available.
dnl
dnl Some BSD platforms (originally FreeBSD, but copied by a few others)
dnl diverged from POSIX in 2002 by setting symbols which make all of the most
dnl recent features visible in the system header files unless the application
dnl overrides the corresponding test-macros.  Doing that introduces portability
dnl problems.
dnl
dnl This macro makes a special check for the symbols used for this, to avoid a
dnl conflicting definition.
AC_DEFUN([CF_POSIX_VISIBLE],
[
AC_CACHE_CHECK(if the POSIX test-macros are already defined,cf_cv_posix_visible,[
AC_TRY_COMPILE([#include ],[
#if defined(__POSIX_VISIBLE) && ((__POSIX_VISIBLE - 0L) > 0) \
	&& defined(__XSI_VISIBLE) && ((__XSI_VISIBLE - 0L) > 0) \
	&& defined(__BSD_VISIBLE) && ((__BSD_VISIBLE - 0L) > 0) \
	&& defined(__ISO_C_VISIBLE) && ((__ISO_C_VISIBLE - 0L) > 0)
#error conflicting symbols found
#endif
],[cf_cv_posix_visible=no],[cf_cv_posix_visible=yes])
])
])dnl
dnl ---------------------------------------------------------------------------
dnl CF_PROG_AR version: 1 updated: 2009/01/01 20:15:22
dnl ----------
dnl Check for archiver "ar".
AC_DEFUN([CF_PROG_AR],[
AC_CHECK_TOOL(AR, ar, ar)
])
dnl ---------------------------------------------------------------------------
dnl CF_PROG_CC version: 5 updated: 2019/12/31 08:53:54
dnl ----------
dnl standard check for CC, plus followup sanity checks
dnl $1 = optional parameter to pass to AC_PROG_CC to specify compiler name
AC_DEFUN([CF_PROG_CC],[
CF_ACVERSION_CHECK(2.53,
	[AC_MSG_WARN(this will incorrectly handle gnatgcc choice)
	 AC_REQUIRE([AC_PROG_CC])],
	[])
ifelse($1,,[AC_PROG_CC],[AC_PROG_CC($1)])
CF_GCC_VERSION
CF_ACVERSION_CHECK(2.52,
	[AC_PROG_CC_STDC],
	[CF_ANSI_CC_REQD])
CF_CC_ENV_FLAGS
])dnl
dnl ---------------------------------------------------------------------------
dnl CF_PROG_EXT version: 15 updated: 2021/01/02 09:31:20
dnl -----------
dnl Compute $PROG_EXT, used for non-Unix ports, such as OS/2 EMX.
AC_DEFUN([CF_PROG_EXT],
[
AC_REQUIRE([CF_CHECK_CACHE])
case "$cf_cv_system_name" in
(os2*)
	CFLAGS="$CFLAGS -Zmt"
	CF_APPEND_TEXT(CPPFLAGS,-D__ST_MT_ERRNO__)
	CXXFLAGS="$CXXFLAGS -Zmt"
	# autoconf's macro sets -Zexe and suffix both, which conflict:w
	LDFLAGS="$LDFLAGS -Zmt -Zcrtdll"
	ac_cv_exeext=.exe
	;;
esac

AC_EXEEXT
AC_OBJEXT

PROG_EXT="$EXEEXT"
AC_SUBST(PROG_EXT)
test -n "$PROG_EXT" && AC_DEFINE_UNQUOTED(PROG_EXT,"$PROG_EXT",[Define to the program extension (normally blank)])
])dnl
dnl ---------------------------------------------------------------------------
dnl CF_PROG_GROFF version: 3 updated: 2018/01/07 13:16:19
dnl -------------
dnl Check if groff is available, for cases (such as html output) where nroff
dnl is not enough.
AC_DEFUN([CF_PROG_GROFF],[
AC_PATH_PROG(GROFF_PATH,groff,no)
AC_PATH_PROGS(NROFF_PATH,nroff mandoc,no)
AC_PATH_PROG(TBL_PATH,tbl,cat)
if test "x$GROFF_PATH" = xno
then
	NROFF_NOTE=
	GROFF_NOTE="#"
else
	NROFF_NOTE="#"
	GROFF_NOTE=
fi
AC_SUBST(GROFF_NOTE)
AC_SUBST(NROFF_NOTE)
])dnl
dnl ---------------------------------------------------------------------------
dnl CF_PROG_LINT version: 4 updated: 2019/11/20 18:55:37
dnl ------------
AC_DEFUN([CF_PROG_LINT],
[
AC_CHECK_PROGS(LINT, lint cppcheck splint)
case "x$LINT" in
(xcppcheck|x*/cppcheck)
	test -z "$LINT_OPTS" && LINT_OPTS="--enable=all"
	;;
esac
AC_SUBST(LINT_OPTS)
])dnl
dnl ---------------------------------------------------------------------------
dnl CF_PROG_PERL version: 6 updated: 2020/12/31 20:19:42
dnl ------------
dnl Check for Perl, given the minimum version, to ensure that required features
dnl are present.
dnl $1 = the minimum version
AC_DEFUN([CF_PROG_PERL],
[# find perl binary
AC_MSG_CHECKING([for ifelse([$1],,perl,[perl-$1])])
AC_CACHE_VAL(cf_cv_prog_PERL,
[ifelse([$1],,,[echo "configure:__oline__: ...version $1 required" >&AC_FD_CC
  ])# allow user to override
  if test -n "$PERL"; then
    cf_try="$PERL"
  else
    cf_try="perl perl5"
  fi

  cf_version="`echo '[[]]'|sed -e 's/^./$/'`"
  for cf_prog in $cf_try; do
    echo "configure:__oline__: trying $cf_prog" >&AC_FD_CC
    if ($cf_prog -e 'printf "found version %g\n",'"$cf_version"'][dnl
ifelse([$1],,,[;exit('"$cf_version"'<$1)])') 1>&AC_FD_CC 2>&1; then
      cf_cv_prog_PERL=$cf_prog
      break
    fi
  done])dnl
PERL="$cf_cv_prog_PERL"
if test -n "$PERL"; then
  AC_MSG_RESULT($PERL)
else
  AC_MSG_RESULT(no)
fi
AC_SUBST(PERL)dnl
])dnl
dnl ---------------------------------------------------------------------------
dnl CF_REMOVE_CFLAGS version: 3 updated: 2021/09/05 17:25:40
dnl ----------------
dnl Remove a given option from CFLAGS/CPPFLAGS
dnl $1 = option to remove
dnl $2 = variable to update
dnl $3 = nonempty to allow verbose message
define([CF_REMOVE_CFLAGS],
[
cf_tmp_cflag=`echo "x$1" | sed -e 's/^.//' -e 's/=.*//'`
while true
do
	cf_old_cflag=`echo "x[$]$2" | sed -e 's/^.//' -e 's/[[ 	]][[ 	]]*-/ -/g' -e "s%$cf_tmp_cflag\\(=[[^ 	]][[^ 	]]*\\)\?%%" -e 's/^[[ 	]]*//' -e 's%[[ ]][[ ]]*-D% -D%g' -e 's%[[ ]][[ ]]*-I% -I%g'`
	test "[$]$2" != "$cf_old_cflag" || break
	ifelse([$3],,,[CF_VERBOSE(removing old option $1 from $2)])
	$2="$cf_old_cflag"
done
])dnl
dnl ---------------------------------------------------------------------------
dnl CF_REMOVE_DEFINE version: 3 updated: 2010/01/09 11:05:50
dnl ----------------
dnl Remove all -U and -D options that refer to the given symbol from a list
dnl of C compiler options.  This works around the problem that not all
dnl compilers process -U and -D options from left-to-right, so a -U option
dnl cannot be used to cancel the effect of a preceding -D option.
dnl
dnl $1 = target (which could be the same as the source variable)
dnl $2 = source (including '$')
dnl $3 = symbol to remove
define([CF_REMOVE_DEFINE],
[
$1=`echo "$2" | \
	sed	-e 's/-[[UD]]'"$3"'\(=[[^ 	]]*\)\?[[ 	]]/ /g' \
		-e 's/-[[UD]]'"$3"'\(=[[^ 	]]*\)\?[$]//g'`
])dnl
dnl ---------------------------------------------------------------------------
dnl CF_RESTARTABLE_PIPEREAD version: 9 updated: 2020/09/08 19:32:19
dnl -----------------------
dnl CF_RESTARTABLE_PIPEREAD is a modified version of AC_RESTARTABLE_SYSCALLS
dnl from acspecific.m4, which uses a read on a pipe (surprise!) rather than a
dnl wait() as the test code.  apparently there is a POSIX change, which OSF/1
dnl at least has adapted to, which says reads (or writes) on pipes for which no
dnl data has been transferred are interruptible _regardless_ of the SA_RESTART
dnl bit.  yuck.
AC_DEFUN([CF_RESTARTABLE_PIPEREAD],
[
AC_REQUIRE([AC_TYPE_SIGNAL])
AC_CACHE_CHECK(for restartable reads on pipes, cf_cv_can_restart_read,[
AC_TRY_RUN(
[/* Exit 0 (true) if wait returns something other than -1,
   i.e. the pid of the child, which means that wait was restarted
   after getting the signal.  */
#ifdef HAVE_STDLIB_H
#include 
#endif
#ifdef HAVE_UNISTD_H
#include 
#endif
#include 
#include 
#ifdef SA_RESTART
static void sigwrapper(int sig, RETSIGTYPE (*disp)(int))
{
    struct sigaction act, oact;

    act.sa_handler = disp;
    sigemptyset(&act.sa_mask);
    act.sa_flags = SA_RESTART;

    (void)sigaction(sig, &act, &oact);

}
#else
# define sigwrapper signal
#endif
RETSIGTYPE ucatch (int isig) { }
int main (void) {
  int i, status;
  int fd[2];
  char buff[2];
  pipe(fd);
  i = fork();
  if (i == 0) {
      sleep (2);
      kill (getppid (), SIGINT);
      sleep (2);
      write(fd[1],"done",4);
      close(fd[1]);
      ${cf_cv_main_return:-return} (0);
  }
  sigwrapper (SIGINT, ucatch);
  status = read(fd[0], buff, sizeof(buff));
  wait (&i);
  ${cf_cv_main_return:-return} (status == -1);
}
],
[cf_cv_can_restart_read=yes],
[cf_cv_can_restart_read=no],
[cf_cv_can_restart_read=unknown])
])

test $cf_cv_can_restart_read = yes && AC_DEFINE(HAVE_RESTARTABLE_PIPEREAD,1,[Define to 1 if we can make restartable reads on pipes])
])dnl
dnl ---------------------------------------------------------------------------
dnl CF_RESTORE_XTRA_FLAGS version: 1 updated: 2020/01/11 16:47:45
dnl ---------------------
dnl Restore flags saved in CF_SAVE_XTRA_FLAGS
dnl $1 = name of current macro
define([CF_RESTORE_XTRA_FLAGS],
[
LIBS="$cf_save_LIBS_$1"
CFLAGS="$cf_save_CFLAGS_$1"
CPPFLAGS="$cf_save_CPPFLAGS_$1"
])dnl
dnl ---------------------------------------------------------------------------
dnl CF_RPATH_HACK version: 13 updated: 2021/01/03 18:30:50
dnl -------------
AC_DEFUN([CF_RPATH_HACK],
[AC_REQUIRE([AC_PROG_FGREP])dnl
AC_REQUIRE([CF_LD_RPATH_OPT])dnl

AC_MSG_CHECKING(for updated LDFLAGS)
if test -n "$LD_RPATH_OPT" ; then
	AC_MSG_RESULT(maybe)

	AC_CHECK_PROGS(cf_ldd_prog,ldd,no)
	cf_rpath_list="/usr/lib /lib"
	if test "$cf_ldd_prog" != no
	then
		cf_rpath_oops=

AC_TRY_LINK([#include ],
		[printf("Hello");],
		[cf_rpath_oops=`"$cf_ldd_prog" "conftest$ac_exeext" | ${FGREP-fgrep} ' not found' | sed -e 's% =>.*$%%' |sort | uniq`
		 cf_rpath_list=`"$cf_ldd_prog" "conftest$ac_exeext" | ${FGREP-fgrep} / | sed -e 's%^.*[[ 	]]/%/%' -e 's%/[[^/]][[^/]]*$%%' |sort | uniq`])

		# If we passed the link-test, but get a "not found" on a given library,
		# this could be due to inept reconfiguration of gcc to make it only
		# partly honor /usr/local/lib (or whatever).  Sometimes this behavior
		# is intentional, e.g., installing gcc in /usr/bin and suppressing the
		# /usr/local libraries.
		if test -n "$cf_rpath_oops"
		then
			for cf_rpath_src in $cf_rpath_oops
			do
				for cf_rpath_dir in \
					/usr/local \
					/usr/pkg \
					/opt/sfw
				do
					if test -f "$cf_rpath_dir/lib/$cf_rpath_src"
					then
						CF_VERBOSE(...adding -L$cf_rpath_dir/lib to LDFLAGS for $cf_rpath_src)
						LDFLAGS="$LDFLAGS -L$cf_rpath_dir/lib"
						break
					fi
				done
			done
		fi
	fi

	CF_VERBOSE(...checking EXTRA_LDFLAGS $EXTRA_LDFLAGS)

	CF_RPATH_HACK_2(LDFLAGS)
	CF_RPATH_HACK_2(LIBS)

	CF_VERBOSE(...checked EXTRA_LDFLAGS $EXTRA_LDFLAGS)
else
	AC_MSG_RESULT(no)
fi
AC_SUBST(EXTRA_LDFLAGS)
])dnl
dnl ---------------------------------------------------------------------------
dnl CF_RPATH_HACK_2 version: 8 updated: 2021/01/01 13:31:04
dnl ---------------
dnl Do one set of substitutions for CF_RPATH_HACK, adding an rpath option to
dnl EXTRA_LDFLAGS for each -L option found.
dnl
dnl $cf_rpath_list contains a list of directories to ignore.
dnl
dnl $1 = variable name to update.  The LDFLAGS variable should be the only one,
dnl      but LIBS often has misplaced -L options.
AC_DEFUN([CF_RPATH_HACK_2],
[
CF_VERBOSE(...checking $1 [$]$1)

cf_rpath_dst=
for cf_rpath_src in [$]$1
do
	case "$cf_rpath_src" in
	(-L*)

		# check if this refers to a directory which we will ignore
		cf_rpath_skip=no
		if test -n "$cf_rpath_list"
		then
			for cf_rpath_item in $cf_rpath_list
			do
				if test "x$cf_rpath_src" = "x-L$cf_rpath_item"
				then
					cf_rpath_skip=yes
					break
				fi
			done
		fi

		if test "$cf_rpath_skip" = no
		then
			# transform the option
			if test "$LD_RPATH_OPT" = "-R " ; then
				cf_rpath_tmp=`echo "$cf_rpath_src" |sed -e "s%-L%-R %"`
			else
				cf_rpath_tmp=`echo "$cf_rpath_src" |sed -e "s%-L%$LD_RPATH_OPT%"`
			fi

			# if we have not already added this, add it now
			cf_rpath_tst=`echo "$EXTRA_LDFLAGS" | sed -e "s%$cf_rpath_tmp %%"`
			if test "x$cf_rpath_tst" = "x$EXTRA_LDFLAGS"
			then
				CF_VERBOSE(...Filter $cf_rpath_src ->$cf_rpath_tmp)
				EXTRA_LDFLAGS="$cf_rpath_tmp $EXTRA_LDFLAGS"
			fi
		fi
		;;
	esac
	cf_rpath_dst="$cf_rpath_dst $cf_rpath_src"
done
$1=$cf_rpath_dst

CF_VERBOSE(...checked $1 [$]$1)
AC_SUBST(EXTRA_LDFLAGS)
])dnl
dnl ---------------------------------------------------------------------------
dnl CF_SAVE_XTRA_FLAGS version: 1 updated: 2020/01/11 16:46:44
dnl ------------------
dnl Use this macro to save CFLAGS/CPPFLAGS/LIBS before checks against X headers
dnl and libraries which do not update those variables.
dnl
dnl $1 = name of current macro
define([CF_SAVE_XTRA_FLAGS],
[
cf_save_LIBS_$1="$LIBS"
cf_save_CFLAGS_$1="$CFLAGS"
cf_save_CPPFLAGS_$1="$CPPFLAGS"
LIBS="$LIBS ${X_PRE_LIBS} ${X_LIBS} ${X_EXTRA_LIBS}"
for cf_X_CFLAGS in $X_CFLAGS
do
	case "x$cf_X_CFLAGS" in
	x-[[IUD]]*)
		CPPFLAGS="$CPPFLAGS $cf_X_CFLAGS"
		;;
	*)
		CFLAGS="$CFLAGS $cf_X_CFLAGS"
		;;
	esac
done
])dnl
dnl ---------------------------------------------------------------------------
dnl CF_SIGWINCH version: 6 updated: 2021/01/01 13:31:04
dnl -----------
dnl Use this macro after CF_XOPEN_SOURCE, but do not require it (not all
dnl programs need this test).
dnl
dnl This is really a Mac OS X 10.4.3 workaround.  Defining _POSIX_C_SOURCE
dnl forces SIGWINCH to be undefined (breaks xterm, ncurses).  Oddly, the struct
dnl winsize declaration is left alone - we may revisit this if Apple choose to
dnl break that part of the interface as well.
AC_DEFUN([CF_SIGWINCH],
[
AC_CACHE_CHECK(if SIGWINCH is defined,cf_cv_define_sigwinch,[
	AC_TRY_COMPILE([
#include 
#include 
],[int x = SIGWINCH; (void)x],
	[cf_cv_define_sigwinch=yes],
	[AC_TRY_COMPILE([
#undef _XOPEN_SOURCE
#undef _POSIX_SOURCE
#undef _POSIX_C_SOURCE
#include 
#include 
],[int x = SIGWINCH; (void)x],
	[cf_cv_define_sigwinch=maybe],
	[cf_cv_define_sigwinch=no])
])
])

if test "$cf_cv_define_sigwinch" = maybe ; then
AC_CACHE_CHECK(for actual SIGWINCH definition,cf_cv_fixup_sigwinch,[
cf_cv_fixup_sigwinch=unknown
cf_sigwinch=32
while test "$cf_sigwinch" != 1
do
	AC_TRY_COMPILE([
#undef _XOPEN_SOURCE
#undef _POSIX_SOURCE
#undef _POSIX_C_SOURCE
#include 
#include 
],[
#if SIGWINCH != $cf_sigwinch
make an error
#endif
int x = SIGWINCH; (void)x],
	[cf_cv_fixup_sigwinch=$cf_sigwinch
	 break])

cf_sigwinch="`expr "$cf_sigwinch" - 1`"
done
])

	if test "$cf_cv_fixup_sigwinch" != unknown ; then
		CPPFLAGS="$CPPFLAGS -DSIGWINCH=$cf_cv_fixup_sigwinch"
	fi
fi
])dnl
dnl ---------------------------------------------------------------------------
dnl CF_SIZECHANGE version: 18 updated: 2021/09/04 06:35:04
dnl -------------
dnl Check for definitions & structures needed for window size-changing
dnl
dnl https://stackoverflow.com/questions/18878141/difference-between-structures-ttysize-and-winsize/50769952#50769952
AC_DEFUN([CF_SIZECHANGE],
[
AC_REQUIRE([CF_STRUCT_TERMIOS])
AC_CACHE_CHECK(declaration of size-change, cf_cv_sizechange,[
	cf_cv_sizechange=unknown
	cf_save_CPPFLAGS="$CPPFLAGS"

for cf_opts in "" "NEED_PTEM_H"
do

	CPPFLAGS="$cf_save_CPPFLAGS"
	if test -n "$cf_opts"
	then
		CF_APPEND_TEXT(CPPFLAGS,-D$cf_opts)
	fi
	AC_TRY_COMPILE([#include 
#ifdef HAVE_TERMIOS_H
#include 
#else
#ifdef HAVE_TERMIO_H
#include 
#endif
#endif

#ifdef NEED_PTEM_H
/* This is a workaround for SCO:  they neglected to define struct winsize in
 * termios.h -- it is only in termio.h and ptem.h
 */
#include 
#include 
#endif

#ifdef HAVE_SYS_IOCTL_H
#include 
#endif
],[
#ifdef TIOCGSIZE
	struct ttysize win;	/* SunOS 3.0... */
	int y = win.ts_lines = 2;
	int x = win.ts_cols = 1;
	(void)y;
	(void)x;
#else
#ifdef TIOCGWINSZ
	struct winsize win;	/* everything else */
	int y = win.ws_row = 2;
	int x = win.ws_col = 1;
	(void)y;
	(void)x;
#else
	no TIOCGSIZE or TIOCGWINSZ
#endif /* TIOCGWINSZ */
#endif /* TIOCGSIZE */
	],
	[cf_cv_sizechange=yes],
	[cf_cv_sizechange=no])

	CPPFLAGS="$cf_save_CPPFLAGS"
	if test "$cf_cv_sizechange" = yes ; then
		echo "size-change succeeded ($cf_opts)" >&AC_FD_CC
		test -n "$cf_opts" && cf_cv_sizechange="$cf_opts"
		break
	fi
done
])
if test "$cf_cv_sizechange" != no ; then
	AC_DEFINE(HAVE_SIZECHANGE,1,[Define to 1 if sizechange declarations are provided])
	case "$cf_cv_sizechange" in
	(NEED*)
		AC_DEFINE_UNQUOTED($cf_cv_sizechange )
		;;
	esac
fi
])dnl
dnl ---------------------------------------------------------------------------
dnl CF_STDIO_UNLOCKED version: 6 updated: 2020/12/31 20:19:42
dnl -----------------
dnl The four functions getc_unlocked(), getchar_unlocked(), putc_unlocked(),
dnl putchar_unlocked() are in POSIX.1-2001.
dnl
dnl Test for one or more of the "unlocked" stdio getc/putc functions, and (if
dnl the system requires it to declare the prototype) define _REENTRANT
dnl
dnl $1 = one or more stdio functions to check for existence and prototype.
AC_DEFUN([CF_STDIO_UNLOCKED],
[
cf_stdio_unlocked=no
AC_CHECK_FUNCS(ifelse([$1],,[getc_unlocked putc_unlocked],[$1]),
	[cf_stdio_unlocked="$ac_func"])
if test "$cf_stdio_unlocked" != no ; then
	case "$CPPFLAGS" in
	(*-D_REENTRANT*)
		;;
	(*)
	AC_CACHE_CHECK(if we should define _REENTRANT,cf_cv_stdio_unlocked,[
	AC_TRY_COMPILE([#include ],[
		extern void *$cf_stdio_unlocked(void *);
		void *dummy = $cf_stdio_unlocked(0)],
			[cf_cv_stdio_unlocked=yes],
			[cf_cv_stdio_unlocked=no])])
		if test "$cf_cv_stdio_unlocked" = yes ; then
			AC_DEFINE(_REENTRANT,1,[Define to 1 if we should define _REENTRANT])
		fi
		;;
	esac
fi
])
dnl ---------------------------------------------------------------------------
dnl CF_STRUCT_TERMIOS version: 11 updated: 2020/03/19 20:46:13
dnl -----------------
dnl Some machines require _POSIX_SOURCE to completely define struct termios.
AC_DEFUN([CF_STRUCT_TERMIOS],[
AC_REQUIRE([CF_XOPEN_SOURCE])

AC_CHECK_HEADERS( \
termio.h \
termios.h \
unistd.h \
sys/ioctl.h \
sys/termio.h \
)

if test "$ac_cv_header_termios_h" = yes ; then
	case "$CFLAGS $CPPFLAGS" in
	(*-D_POSIX_SOURCE*)
		termios_bad=dunno ;;
	(*)	termios_bad=maybe ;;
	esac
	if test "$termios_bad" = maybe ; then
	AC_MSG_CHECKING(whether termios.h needs _POSIX_SOURCE)
	AC_TRY_COMPILE([#include ],
		[struct termios foo; int x = foo.c_iflag = 1; (void)x],
		termios_bad=no, [
		AC_TRY_COMPILE([
#define _POSIX_SOURCE
#include ],
			[struct termios foo; int x = foo.c_iflag = 2; (void)x],
			termios_bad=unknown,
			termios_bad=yes AC_DEFINE(_POSIX_SOURCE,1,[Define to 1 if we must define _POSIX_SOURCE]))
			])
	AC_MSG_RESULT($termios_bad)
	fi
fi
])dnl
dnl ---------------------------------------------------------------------------
dnl CF_SUBDIR_PATH version: 7 updated: 2014/12/04 04:33:06
dnl --------------
dnl Construct a search-list for a nonstandard header/lib-file
dnl	$1 = the variable to return as result
dnl	$2 = the package name
dnl	$3 = the subdirectory, e.g., bin, include or lib
AC_DEFUN([CF_SUBDIR_PATH],
[
$1=

CF_ADD_SUBDIR_PATH($1,$2,$3,$prefix,NONE)

for cf_subdir_prefix in \
	/usr \
	/usr/local \
	/usr/pkg \
	/opt \
	/opt/local \
	[$]HOME
do
	CF_ADD_SUBDIR_PATH($1,$2,$3,$cf_subdir_prefix,$prefix)
done
])dnl
dnl ---------------------------------------------------------------------------
dnl CF_SYS_ERRLIST version: 6 updated: 2001/12/30 13:03:23
dnl --------------
dnl Check for declaration of sys_nerr and sys_errlist in one of stdio.h and
dnl errno.h.  Declaration of sys_errlist on BSD4.4 interferes with our
dnl declaration.  Reported by Keith Bostic.
AC_DEFUN([CF_SYS_ERRLIST],
[
    CF_CHECK_ERRNO(sys_nerr)
    CF_CHECK_ERRNO(sys_errlist)
])dnl
dnl ---------------------------------------------------------------------------
dnl CF_TERMCAP_LIBS version: 15 updated: 2015/04/15 19:08:48
dnl ---------------
dnl Look for termcap libraries, or the equivalent in terminfo.
dnl
dnl The optional parameter may be "ncurses", "ncursesw".
AC_DEFUN([CF_TERMCAP_LIBS],
[
AC_CACHE_VAL(cf_cv_termlib,[
cf_cv_termlib=none
AC_TRY_LINK([],[char *x=(char*)tgoto("",0,0)],
[AC_TRY_LINK([],[int x=tigetstr("")],
	[cf_cv_termlib=terminfo],
	[cf_cv_termlib=termcap])
	CF_VERBOSE(using functions in predefined $cf_cv_termlib LIBS)
],[
ifelse([$1],,,[
case "$1" in
(ncurses*)
	CF_NCURSES_CONFIG($1)
	cf_cv_termlib=terminfo
	;;
esac
])
if test "$cf_cv_termlib" = none; then
	# FreeBSD's linker gives bogus results for AC_CHECK_LIB, saying that
	# tgetstr lives in -lcurses when it is only an unsatisfied extern.
	cf_save_LIBS="$LIBS"
	for cf_lib in tinfo curses ncurses termlib termcap
	do
		LIBS="-l$cf_lib $cf_save_LIBS"
		for cf_func in tigetstr tgetstr
		do
			AC_MSG_CHECKING(for $cf_func in -l$cf_lib)
			AC_TRY_LINK([],[int x=$cf_func("")],[cf_result=yes],[cf_result=no])
			AC_MSG_RESULT($cf_result)
			if test "$cf_result" = yes ; then
				if test "$cf_func" = tigetstr ; then
					cf_cv_termlib=terminfo
				else
					cf_cv_termlib=termcap
				fi
				break
			fi
		done
		test "$cf_result" = yes && break
	done
	test "$cf_result" = no && LIBS="$cf_save_LIBS"
fi
if test "$cf_cv_termlib" = none; then
	# allow curses library for broken AIX system.
	AC_CHECK_LIB(curses, initscr, [CF_ADD_LIBS(-lcurses)])
	AC_CHECK_LIB(termcap, tgoto, [CF_ADD_LIBS(-ltermcap) cf_cv_termlib=termcap])
fi
])
if test "$cf_cv_termlib" = none; then
	AC_MSG_WARN([Cannot find -ltermlib, -lcurses, or -ltermcap])
fi
])])dnl
dnl ---------------------------------------------------------------------------
dnl CF_TERMIOS_TYPES version: 2 updated: 2020/03/10 18:53:47
dnl ----------------
dnl https://pubs.opengroup.org/onlinepubs/009695399/basedefs/termios.h.html
dnl says that tcflag_t, speed_t and cc_t are typedef'd.  If they are not,
dnl fallback to historical values.
AC_DEFUN([CF_TERMIOS_TYPES],[

AC_CACHE_CHECK(for termios type tcflag_t, cf_cv_havetype_tcflag_t,[
	AC_TRY_COMPILE([#include ],[
		tcflag_t x = 0; (void)x],
		[cf_cv_havetype_tcflag_t=yes],
		[cf_cv_havetype_tcflag_t=no])
])
test "$cf_cv_havetype_tcflag_t" = no && AC_DEFINE(tcflag_t,unsigned long,[Define usable value of tcflag_t if not declared])

AC_CACHE_CHECK(for termios type speed_t, cf_cv_havetype_speed_t,[
	AC_TRY_COMPILE([#include ],[
		speed_t x = 0; (void)x],
		[cf_cv_havetype_speed_t=yes],
		[cf_cv_havetype_speed_t=no])
])
test "$cf_cv_havetype_speed_t" = no && AC_DEFINE(speed_t,unsigned short,[Define usable value of speed_t if not declared])

AC_CACHE_CHECK(for termios type cc_t, cf_cv_havetype_cc_t,[
	AC_TRY_COMPILE([#include ],[
		cc_t x = 0; (void)x],
		[cf_cv_havetype_cc_t=yes],
		[cf_cv_havetype_cc_t=no])
])
test "$cf_cv_havetype_cc_t" = no && AC_DEFINE(cc_t,unsigned char,[Define usable value of cc_t if not declared])
])dnl
dnl ---------------------------------------------------------------------------
dnl CF_TERM_HEADER version: 6 updated: 2021/01/02 09:31:20
dnl --------------
dnl Look for term.h, which is part of X/Open curses.  It defines the interface
dnl to terminfo database.  Usually it is in the same include-path as curses.h,
dnl but some packagers change this, breaking various applications.
AC_DEFUN([CF_TERM_HEADER],[
AC_CACHE_CHECK(for terminfo header, cf_cv_term_header,[
case "${cf_cv_ncurses_header}" in
(*/ncurses.h|*/ncursesw.h)
	cf_term_header=`echo "$cf_cv_ncurses_header" | sed -e 's%ncurses[[^.]]*\.h$%term.h%'`
	;;
(*)
	cf_term_header=term.h
	;;
esac

for cf_test in $cf_term_header "ncurses/term.h" "ncursesw/term.h"
do
AC_TRY_COMPILE([#include 
#include <${cf_cv_ncurses_header:-curses.h}>
#include <$cf_test>
],[int x = auto_left_margin; (void)x],[
	cf_cv_term_header="$cf_test"],[
	cf_cv_term_header=unknown
	])
	test "$cf_cv_term_header" != unknown && break
done
])

# Set definitions to allow ifdef'ing to accommodate subdirectories

case "$cf_cv_term_header" in
(*term.h)
	AC_DEFINE(HAVE_TERM_H,1,[Define to 1 if we have term.h])
	;;
esac

case "$cf_cv_term_header" in
(ncurses/term.h)
	AC_DEFINE(HAVE_NCURSES_TERM_H,1,[Define to 1 if we have ncurses/term.h])
	;;
(ncursesw/term.h)
	AC_DEFINE(HAVE_NCURSESW_TERM_H,1,[Define to 1 if we have ncursesw/term.h])
	;;
esac
])dnl
dnl ---------------------------------------------------------------------------
dnl CF_TRANSFORM_PROGRAM version: 3 updated: 2020/12/31 20:19:42
dnl --------------------
dnl From AC_ARG_PROGRAM, (re)compute $program_transform_name based on the
dnl $program_prefix and $program_suffix values.
AC_DEFUN([CF_TRANSFORM_PROGRAM],[
program_transform_name=s,x,x,
test "$program_prefix" != NONE &&
  program_transform_name="s,^,$program_prefix,;$program_transform_name"
# Use a double $ so make ignores it.
test "$program_suffix" != NONE &&
  program_transform_name="s,\$,$program_suffix,;$program_transform_name"
# Double any \ or $.  echo might interpret backslashes.
# By default was `s,x,x', remove it if useless.
cat <<\_ACEOF >conftest.sed
s/[[\\$]]/&&/g;s/;s,x,x,$//
_ACEOF
program_transform_name="`echo "$program_transform_name" | sed -f conftest.sed`"
rm conftest.sed
])
dnl ---------------------------------------------------------------------------
dnl CF_TRIM_X_LIBS version: 3 updated: 2015/04/12 15:39:00
dnl --------------
dnl Trim extra base X libraries added as a workaround for inconsistent library
dnl dependencies returned by "new" pkg-config files.
AC_DEFUN([CF_TRIM_X_LIBS],[
	for cf_trim_lib in Xmu Xt X11
	do
		case "$LIBS" in
		(*-l$cf_trim_lib\ *-l$cf_trim_lib*)
			LIBS=`echo "$LIBS " | sed -e 's/  / /g' -e 's%-l'"$cf_trim_lib"' %%' -e 's/ $//'`
			CF_VERBOSE(..trimmed $LIBS)
			;;
		esac
	done
])
dnl ---------------------------------------------------------------------------
dnl CF_TRY_PKG_CONFIG version: 6 updated: 2020/12/31 10:54:15
dnl -----------------
dnl This is a simple wrapper to use for pkg-config, for libraries which may be
dnl available in that form.
dnl
dnl $1 = package name, which may be a shell variable
dnl $2 = extra logic to use, if any, after updating CFLAGS and LIBS
dnl $3 = logic to use if pkg-config does not have the package
AC_DEFUN([CF_TRY_PKG_CONFIG],[
AC_REQUIRE([CF_PKG_CONFIG])

if test "$PKG_CONFIG" != none && "$PKG_CONFIG" --exists "$1"; then
	CF_VERBOSE(found package $1)
	cf_pkgconfig_incs="`$PKG_CONFIG --cflags "$1" 2>/dev/null`"
	cf_pkgconfig_libs="`$PKG_CONFIG --libs   "$1" 2>/dev/null`"
	CF_VERBOSE(package $1 CFLAGS: $cf_pkgconfig_incs)
	CF_VERBOSE(package $1 LIBS: $cf_pkgconfig_libs)
	CF_ADD_CFLAGS($cf_pkgconfig_incs)
	CF_ADD_LIBS($cf_pkgconfig_libs)
	ifelse([$2],,:,[$2])
else
	cf_pkgconfig_incs=
	cf_pkgconfig_libs=
	ifelse([$3],,:,[$3])
fi
])
dnl ---------------------------------------------------------------------------
dnl CF_TRY_XOPEN_SOURCE version: 3 updated: 2021/08/28 15:20:37
dnl -------------------
dnl If _XOPEN_SOURCE is not defined in the compile environment, check if we
dnl can define it successfully.
AC_DEFUN([CF_TRY_XOPEN_SOURCE],[
AC_CACHE_CHECK(if we should define _XOPEN_SOURCE,cf_cv_xopen_source,[
	AC_TRY_COMPILE([
#include 
#include 
#include 
],[
#ifndef _XOPEN_SOURCE
make an error
#endif],
	[cf_cv_xopen_source=no],
	[cf_save="$CPPFLAGS"
	 CF_APPEND_TEXT(CPPFLAGS,-D_XOPEN_SOURCE=$cf_XOPEN_SOURCE)
	 AC_TRY_COMPILE([
#include 
#include 
#include 
],[
#ifdef _XOPEN_SOURCE
make an error
#endif],
	[cf_cv_xopen_source=no],
	[cf_cv_xopen_source=$cf_XOPEN_SOURCE])
	CPPFLAGS="$cf_save"
	])
])

if test "$cf_cv_xopen_source" != no ; then
	CF_REMOVE_DEFINE(CFLAGS,$CFLAGS,_XOPEN_SOURCE)
	CF_REMOVE_DEFINE(CPPFLAGS,$CPPFLAGS,_XOPEN_SOURCE)
	cf_temp_xopen_source="-D_XOPEN_SOURCE=$cf_cv_xopen_source"
	CF_APPEND_CFLAGS($cf_temp_xopen_source)
fi
])
dnl ---------------------------------------------------------------------------
dnl CF_TYPE_FD_SET version: 6 updated: 2020/03/10 18:53:47
dnl --------------
dnl Check for the declaration of fd_set.  Some platforms declare it in
dnl , and some in , which requires .
dnl Finally, if we are using this for an X application, Xpoll.h may include
dnl , so we don't want to do it twice.
AC_DEFUN([CF_TYPE_FD_SET],
[
AC_CHECK_HEADERS(X11/Xpoll.h)

AC_CACHE_CHECK(for declaration of fd_set,cf_cv_type_fd_set,
	[CF_MSG_LOG(sys/types alone)
AC_TRY_COMPILE([
#include ],
	[fd_set x; (void)x],
	[cf_cv_type_fd_set=sys/types.h],
	[CF_MSG_LOG(X11/Xpoll.h)
AC_TRY_COMPILE([
#ifdef HAVE_X11_XPOLL_H
#include 
#endif],
	[fd_set x; (void)x],
	[cf_cv_type_fd_set=X11/Xpoll.h],
	[CF_MSG_LOG(sys/select.h)
AC_TRY_COMPILE([
#include 
#include ],
	[fd_set x; (void)x],
	[cf_cv_type_fd_set=sys/select.h],
	[cf_cv_type_fd_set=unknown])])])])
if test $cf_cv_type_fd_set = sys/select.h ; then
	AC_DEFINE(USE_SYS_SELECT_H,1,[Define to 1 to include sys/select.h to declare fd_set])
fi
])
dnl ---------------------------------------------------------------------------
dnl CF_TYPE_OUTCHAR version: 15 updated: 2015/05/15 19:42:24
dnl ---------------
dnl Check for return and param type of 3rd -- OutChar() -- param of tputs().
dnl
dnl For this check, and for CF_CURSES_TERMCAP, the $CHECK_DECL_HDRS variable
dnl must point to a header file containing this (or equivalent):
dnl
dnl	#ifdef NEED_CURSES_H
dnl	# ifdef HAVE_NCURSES_NCURSES_H
dnl	#  include 
dnl	# else
dnl	#  ifdef HAVE_NCURSES_H
dnl	#   include 
dnl	#  else
dnl	#   include 
dnl	#  endif
dnl	# endif
dnl	#endif
dnl
dnl	#ifdef HAVE_NCURSES_TERM_H
dnl	#  include 
dnl	#else
dnl	# ifdef HAVE_TERM_H
dnl	#  include 
dnl	# endif
dnl	#endif
dnl
dnl	#if NEED_TERMCAP_H
dnl	# include 
dnl	#endif
dnl
AC_DEFUN([CF_TYPE_OUTCHAR],
[
AC_REQUIRE([CF_CURSES_TERMCAP])

AC_CACHE_CHECK(declaration of tputs 3rd param, cf_cv_type_outchar,[

cf_cv_type_outchar="int OutChar(int)"
cf_cv_found=no
cf_save_CPPFLAGS="$CPPFLAGS"
CPPFLAGS="$CPPFLAGS $CHECK_DECL_FLAG"

for P in int void; do
for Q in int void; do
for R in int char; do
for S in "" const; do
	CF_MSG_LOG(loop variables [P:[$]P, Q:[$]Q, R:[$]R, S:[$]S])
	AC_TRY_COMPILE([$CHECK_DECL_HDRS],
	[extern $Q OutChar($R);
	extern $P tputs ($S char *string, int nlines, $Q (*_f)($R));
	tputs("", 1, OutChar)],
	[cf_cv_type_outchar="$Q OutChar($R)"
	 cf_cv_found=yes
	 break])
done
	test $cf_cv_found = yes && break
done
	test $cf_cv_found = yes && break
done
	test $cf_cv_found = yes && break
done
])

case $cf_cv_type_outchar in
(int*)
	AC_DEFINE(OUTC_RETURN,1,[Define to 1 if tputs outc function returns a value])
	;;
esac
case $cf_cv_type_outchar in
(*char*)
	AC_DEFINE(OUTC_ARGS,char c,[Define to actual type to override tputs outc parameter type])
	;;
esac

CPPFLAGS="$cf_save_CPPFLAGS"
])dnl
dnl ---------------------------------------------------------------------------
dnl CF_UPPER version: 5 updated: 2001/01/29 23:40:59
dnl --------
dnl Make an uppercase version of a variable
dnl $1=uppercase($2)
AC_DEFUN([CF_UPPER],
[
$1=`echo "$2" | sed y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%`
])dnl
dnl ---------------------------------------------------------------------------
dnl CF_UTF8_LIB version: 9 updated: 2021/05/19 19:35:25
dnl -----------
dnl Check for multibyte support, and if not found, utf8 compatibility library
AC_DEFUN([CF_UTF8_LIB],
[
AC_HAVE_HEADERS(wchar.h)
AC_CACHE_CHECK(for multibyte character support,cf_cv_utf8_lib,[
	cf_save_LIBS="$LIBS"
	AC_TRY_LINK([
#include 
#include 
#ifdef HAVE_WCHAR_H
#include 
#endif
],[putwc(0,0);],
	[cf_cv_utf8_lib=yes],
	[CF_FIND_LINKAGE([
#include ],[putwc(0,0);],utf8,
		[cf_cv_utf8_lib=add-on],
		[cf_cv_utf8_lib=no])
])])

# HAVE_LIBUTF8_H is used by ncurses if curses.h is shared between
# ncurses/ncursesw:
if test "$cf_cv_utf8_lib" = "add-on" ; then
	AC_DEFINE(HAVE_LIBUTF8_H,1,[Define to 1 if we should include libutf8.h])
	CF_ADD_INCDIR($cf_cv_header_path_utf8)
	CF_ADD_LIBDIR($cf_cv_library_path_utf8)
	CF_ADD_LIBS($cf_cv_library_file_utf8)
fi
])dnl
dnl ---------------------------------------------------------------------------
dnl CF_VA_COPY version: 6 updated: 2018/12/04 18:14:25
dnl ----------
dnl check for va_copy, part of stdarg.h starting with ISO C 1999.
dnl Also, workaround for glibc's __va_copy, by checking for both.
dnl Finally, try to accommodate pre-ISO C 1999 headers.
AC_DEFUN([CF_VA_COPY],[
AC_CACHE_CHECK(for va_copy, cf_cv_have_va_copy,[
AC_TRY_LINK([
#include 
],[
	static va_list dst;
	static va_list src;
	va_copy(dst, src)],
	cf_cv_have_va_copy=yes,
	cf_cv_have_va_copy=no)])

if test "$cf_cv_have_va_copy" = yes;
then
	AC_DEFINE(HAVE_VA_COPY,1,[Define to 1 if we have va_copy])
else # !cf_cv_have_va_copy

AC_CACHE_CHECK(for __va_copy, cf_cv_have___va_copy,[
AC_TRY_LINK([
#include 
],[
	static va_list dst;
	static va_list src;
	__va_copy(dst, src)],
	cf_cv_have___va_copy=yes,
	cf_cv_have___va_copy=no)])

if test "$cf_cv_have___va_copy" = yes
then
	AC_DEFINE(HAVE___VA_COPY,1,[Define to 1 if we have __va_copy])
else # !cf_cv_have___va_copy

AC_CACHE_CHECK(for __builtin_va_copy, cf_cv_have___builtin_va_copy,[
AC_TRY_LINK([
#include 
],[
	static va_list dst;
	static va_list src;
	__builtin_va_copy(dst, src)],
	cf_cv_have___builtin_va_copy=yes,
	cf_cv_have___builtin_va_copy=no)])

test "$cf_cv_have___builtin_va_copy" = yes &&
	AC_DEFINE(HAVE___BUILTIN_VA_COPY,1,[Define to 1 if we have __builtin_va_copy])

fi # cf_cv_have___va_copy

fi # cf_cv_have_va_copy

case "${cf_cv_have_va_copy}${cf_cv_have___va_copy}${cf_cv_have___builtin_va_copy}" in
(*yes*)
	;;

(*)
	AC_CACHE_CHECK(if we can simply copy va_list, cf_cv_pointer_va_list,[
AC_TRY_LINK([
#include 
],[
	va_list dst;
	va_list src;
	dst = src],
	cf_cv_pointer_va_list=yes,
	cf_cv_pointer_va_list=no)])

	if test "$cf_cv_pointer_va_list" = no
	then
		AC_CACHE_CHECK(if we can copy va_list indirectly, cf_cv_array_va_list,[
AC_TRY_LINK([
#include 
],[
	va_list dst;
	va_list src;
	*dst = *src],
			cf_cv_array_va_list=yes,
			cf_cv_array_va_list=no)])
		test "$cf_cv_array_va_list" = yes && AC_DEFINE(ARRAY_VA_LIST,1,[Define to 1 if we can copy va_list indirectly])
	fi
	;;
esac
])
dnl ---------------------------------------------------------------------------
dnl CF_VERBOSE version: 3 updated: 2007/07/29 09:55:12
dnl ----------
dnl Use AC_VERBOSE w/o the warnings
AC_DEFUN([CF_VERBOSE],
[test -n "$verbose" && echo "	$1" 1>&AC_FD_MSG
CF_MSG_LOG([$1])
])dnl
dnl ---------------------------------------------------------------------------
dnl CF_WCTYPE version: 6 updated: 2012/10/06 11:17:15
dnl ---------
dnl Look for  and related functions.  This is needed with glibc to
dnl see the codes above 127.
AC_DEFUN([CF_WCTYPE],
[
AC_CACHE_CHECK(for  and functions, cf_cv_have_wctype,[
AC_TRY_COMPILE([
#include ],[
	wint_t temp = 101;
	int test = (wctype("alnum") != 0)
       		|| iswalnum(temp)
		|| iswalpha(temp)
		|| iswblank(temp)
		|| iswcntrl(temp)
		|| iswdigit(temp)
		|| iswgraph(temp)
		|| iswlower(temp)
		|| iswprint(temp)
		|| iswpunct(temp)
		|| iswspace(temp)
		|| iswupper(temp)
		|| iswxdigit(temp);],
	[cf_cv_have_wctype=yes],
	[cf_cv_have_wctype=no])
])
if test "$cf_cv_have_wctype" = yes ; then
	AC_SEARCH_LIBS(wctype,[w],[AC_DEFINE(HAVE_WCTYPE,1,[Define to 1 if we have usable wctype.h])])
fi
])dnl
dnl ---------------------------------------------------------------------------
dnl CF_WITH_APP_CLASS version: 3 updated: 2015/04/12 15:39:00
dnl -----------------
dnl Handle configure option "--with-app-class", setting the $APP_CLASS
dnl variable, used for X resources.
dnl
dnl $1 = default value.
AC_DEFUN([CF_WITH_APP_CLASS],[
AC_MSG_CHECKING(for X applications class)
AC_ARG_WITH(app-class,
	[  --with-app-class=XXX    override X applications class (default $1)],
	[APP_CLASS=$withval],
	[APP_CLASS=$1])

case x$APP_CLASS in
(*[[/@,%]]*)
	AC_MSG_WARN(X applications class cannot contain punctuation)
	APP_CLASS=$1
	;;
(x[[A-Z]]*)
	;;
(*)
	AC_MSG_WARN([X applications class must start with capital, ignoring $APP_CLASS])
	APP_CLASS=$1
	;;
esac

AC_MSG_RESULT($APP_CLASS)

AC_SUBST(APP_CLASS)
])dnl
dnl ---------------------------------------------------------------------------
dnl CF_WITH_APP_DEFAULTS version: 6 updated: 2015/01/02 09:05:50
dnl --------------------
dnl Handle configure option "--with-app-defaults", setting these shell
dnl variables:
dnl
dnl $APPSDIR is the option value, used for installing app-defaults files.
dnl $no_appsdir is a "#" (comment) if "--without-app-defaults" is given.
dnl
dnl Most Linux's use this:
dnl 	/usr/share/X11/app-defaults
dnl Debian uses this:
dnl 	/etc/X11/app-defaults
dnl DragonFlyBSD ports uses this:
dnl 	/usr/pkg/lib/X11/app-defaults
dnl FreeBSD ports use these:
dnl 	/usr/local/lib/X11/app-defaults
dnl 	/usr/local/share/X11/app-defaults
dnl Mandriva has these:
dnl 	/usr/lib/X11/app-defaults
dnl 	/usr/lib64/X11/app-defaults
dnl NetBSD has these
dnl 	/usr/X11R7/lib/X11/app-defaults
dnl OpenSolaris uses
dnl 	32-bit:
dnl 	/usr/X11/etc/X11/app-defaults
dnl 	/usr/X11/share/X11/app-defaults
dnl 	/usr/X11/lib/X11/app-defaults
dnl OSX uses
dnl		/opt/local/share/X11/app-defaults (MacPorts)
dnl		/opt/X11/share/X11/app-defaults (non-ports)
dnl	64-bit:
dnl 	/usr/X11/etc/X11/app-defaults
dnl 	/usr/X11/share/X11/app-defaults (I mkdir'd this)
dnl 	/usr/X11/lib/amd64/X11/app-defaults
dnl Solaris10 uses (in this order):
dnl 	/usr/openwin/lib/X11/app-defaults
dnl 	/usr/X11/lib/X11/app-defaults
AC_DEFUN([CF_WITH_APP_DEFAULTS],[
AC_MSG_CHECKING(for directory to install resource files)
AC_ARG_WITH(app-defaults,
	[  --with-app-defaults=DIR directory in which to install resource files (EPREFIX/lib/X11/app-defaults)],
	[APPSDIR=$withval],
	[APPSDIR='${exec_prefix}/lib/X11/app-defaults'])

if test "x[$]APPSDIR" = xauto
then
	APPSDIR='${exec_prefix}/lib/X11/app-defaults'
	for cf_path in \
		/opt/local/share/X11/app-defaults \
		/opt/X11/share/X11/app-defaults \
		/usr/share/X11/app-defaults \
		/usr/X11/share/X11/app-defaults \
		/usr/X11/lib/X11/app-defaults \
		/usr/lib/X11/app-defaults \
		/etc/X11/app-defaults \
		/usr/pkg/lib/X11/app-defaults \
		/usr/X11R7/lib/X11/app-defaults \
		/usr/X11R6/lib/X11/app-defaults \
		/usr/X11R5/lib/X11/app-defaults \
		/usr/X11R4/lib/X11/app-defaults \
		/usr/local/lib/X11/app-defaults \
		/usr/local/share/X11/app-defaults \
		/usr/lib64/X11/app-defaults
	do
		if test -d "$cf_path" ; then
			APPSDIR="$cf_path"
			break
		fi
	done
else
	cf_path=$APPSDIR
	CF_PATH_SYNTAX(cf_path)
fi

AC_MSG_RESULT($APPSDIR)
AC_SUBST(APPSDIR)

no_appsdir=
if test "$APPSDIR" = no
then
	no_appsdir="#"
else
	EXTRA_INSTALL_DIRS="$EXTRA_INSTALL_DIRS \$(APPSDIR)"
fi
AC_SUBST(no_appsdir)
])dnl
dnl ---------------------------------------------------------------------------
dnl CF_WITH_CURSES_DIR version: 4 updated: 2021/01/02 19:22:58
dnl ------------------
dnl Wrapper for AC_ARG_WITH to specify directory under which to look for curses
dnl libraries.
AC_DEFUN([CF_WITH_CURSES_DIR],[

AC_MSG_CHECKING(for specific curses-directory)
AC_ARG_WITH(curses-dir,
	[  --with-curses-dir=DIR   directory in which (n)curses is installed],
	[cf_cv_curses_dir=$withval],
	[cf_cv_curses_dir=no])
AC_MSG_RESULT($cf_cv_curses_dir)

if test -n "$cf_cv_curses_dir" && test "$cf_cv_curses_dir" != "no"
then
	CF_PATH_SYNTAX(withval)
	if test -d "$cf_cv_curses_dir"
	then
		CF_ADD_INCDIR($cf_cv_curses_dir/include)
		CF_ADD_LIBDIR($cf_cv_curses_dir/lib)
	fi
fi
])dnl
dnl ---------------------------------------------------------------------------
dnl CF_WITH_DBMALLOC version: 7 updated: 2010/06/21 17:26:47
dnl ----------------
dnl Configure-option for dbmalloc.  The optional parameter is used to override
dnl the updating of $LIBS, e.g., to avoid conflict with subsequent tests.
AC_DEFUN([CF_WITH_DBMALLOC],[
CF_NO_LEAKS_OPTION(dbmalloc,
	[  --with-dbmalloc         test: use Conor Cahill's dbmalloc library],
	[USE_DBMALLOC])

if test "$with_dbmalloc" = yes ; then
	AC_CHECK_HEADER(dbmalloc.h,
		[AC_CHECK_LIB(dbmalloc,[debug_malloc]ifelse([$1],,[],[,$1]))])
fi
])dnl
dnl ---------------------------------------------------------------------------
dnl CF_WITH_DMALLOC version: 7 updated: 2010/06/21 17:26:47
dnl ---------------
dnl Configure-option for dmalloc.  The optional parameter is used to override
dnl the updating of $LIBS, e.g., to avoid conflict with subsequent tests.
AC_DEFUN([CF_WITH_DMALLOC],[
CF_NO_LEAKS_OPTION(dmalloc,
	[  --with-dmalloc          test: use Gray Watson's dmalloc library],
	[USE_DMALLOC])

if test "$with_dmalloc" = yes ; then
	AC_CHECK_HEADER(dmalloc.h,
		[AC_CHECK_LIB(dmalloc,[dmalloc_debug]ifelse([$1],,[],[,$1]))])
fi
])dnl
dnl ---------------------------------------------------------------------------
dnl CF_WITH_ICONDIR version: 5 updated: 2012/07/22 09:18:02
dnl ---------------
dnl Handle configure option "--with-icondir", setting these shell variables:
dnl
dnl $ICONDIR is the option value, used for installing icon files.
dnl $no_icondir is a "#" (comment) if "--without-icondir" is given.
AC_DEFUN([CF_WITH_ICONDIR],[
AC_MSG_CHECKING(for directory to install icons)
AC_ARG_WITH(icondir,
	[  --with-icondir=DIR      directory in which to install icons for desktop],
	[ICONDIR=$withval],
	[test -z "$ICONDIR" && ICONDIR=no])

if test "x[$]ICONDIR" = xauto
then
	ICONDIR='${datadir}/icons'
	for cf_path in \
		/usr/share/icons \
		/usr/X11R6/share/icons
	do
		if test -d "$cf_path" ; then
			ICONDIR="$cf_path"
			break
		fi
	done
else
	cf_path=$ICONDIR
	CF_PATH_SYNTAX(cf_path)
fi
AC_MSG_RESULT($ICONDIR)
AC_SUBST(ICONDIR)

no_icondir=
if test "$ICONDIR" = no
then
	no_icondir="#"
else
	EXTRA_INSTALL_DIRS="$EXTRA_INSTALL_DIRS \$(ICONDIR)"
fi
AC_SUBST(no_icondir)
])dnl
dnl ---------------------------------------------------------------------------
dnl CF_WITH_ICON_THEME version: 13 updated: 2020/12/31 10:54:15
dnl ------------------
dnl If asked, check for prerequisites and setup symbols to permit installing
dnl one or more application icons in the Red Hat icon-theme directory
dnl hierarchy.
dnl
dnl If the prerequisites are missing, give a warning and revert to the long-
dnl standing pixmaps directory.
dnl
dnl Parameters:
dnl
dnl $1 = application icon.  This can be a list, and is not optional.
dnl $2 = default theme (defaults to hicolor)
dnl $3 = formats (defaults to list [.svg .png .xpm])
dnl $4 = alternate icon if no theme is used (defaults to $1).
dnl
dnl Result:
dnl ICON_NAME = basename of first item in $1, unless already set
dnl ICON_LIST = reprocessed $1
dnl ICON_THEME = reprocessed $2
dnl ICON_FORMAT = reprocessed $3
AC_DEFUN([CF_WITH_ICON_THEME],
[
ifelse([$1],,[
	AC_MSG_ERROR([macro [CF_WITH_ICON_THEME] requires application-icon name])
],[

CF_WITH_PIXMAPDIR
CF_WITH_ICONDIR

AC_MSG_CHECKING(if icon theme should be used)
AC_ARG_WITH(icon-theme,
	[  --with-icon-theme=XXX   install icons into desktop theme (hicolor)],
	[ICON_THEME=$withval],
	[ICON_THEME=no])

case "x$ICON_THEME" in
(xno)
	;;
(x|xyes)
	ICON_THEME=ifelse([$2],,hicolor,$2)
	;;
esac
AC_MSG_RESULT($ICON_THEME)

if test "x$ICON_THEME" = xno
then
	if test "x$ICONDIR" != xno
	then
		CF_VERBOSE(ignoring icondir without theme)
		no_icondir="#"
	fi
else
	if test "x$ICONDIR" = xno
	then
		AC_MSG_ERROR(icondir must be set for icon theme)
	fi
fi

: ${ICON_FORMAT:=ifelse([$3],,[".svg .png .xpm"],[$3])}

ICON_LIST=

ifelse([$4],,[cf_icon_list=$1],[
if test "x$ICON_THEME" != xno
then
	cf_icon_list="$1"
else
	cf_icon_list="$4"
fi
])

AC_MSG_CHECKING([for icon(s) to install])
for cf_name in $cf_icon_list
do
	CF_VERBOSE(using $ICON_FORMAT)
	for cf_suffix in $ICON_FORMAT
	do
		cf_icon="${cf_name}${cf_suffix}"
		cf_left=`echo "$cf_icon" | sed -e 's/:.*//'`
		if test ! -f "${cf_left}"
		then
			if test "x$srcdir" != "x."
			then
				cf_icon="${srcdir}/${cf_left}"
				cf_left=`echo "$cf_icon" | sed -e 's/:.*//'`
				if test ! -f "${cf_left}"
				then
					continue
				fi
			else
				continue
			fi
		fi
		if test "x$ICON_THEME" != xno
		then
			cf_base=`basename "$cf_left"`
			cf_trim=`echo "$cf_base" | sed -e 's/_[[0-9]][[0-9]]x[[0-9]][[0-9]]\././'`
			case "x${cf_base}" in
			(*:*)
				cf_next=$cf_base
				# user-defined mapping
				;;
			(*.png)
				cf_size=`file "$cf_left"|sed -e 's/^[[^:]]*://' -e 's/^.*[[^0-9]]\([[0-9]][[0-9]]* x [[0-9]][[0-9]]*\)[[^0-9]].*$/\1/' -e 's/ //g'`
				if test -z "$cf_size"
				then
					AC_MSG_WARN(cannot determine size of $cf_left)
					continue
				fi
				cf_next="$cf_size/apps/$cf_trim"
				;;
			(*.svg)
				cf_next="scalable/apps/$cf_trim"
				;;
			(*.xpm)
				CF_VERBOSE(ignored XPM file in icon theme)
				continue
				;;
			(*_[[0-9]][[0-9]]*x[[0-9]][[0-9]]*.*)
				cf_size=`echo "$cf_left"|sed -e 's/^.*_\([[0-9]][[0-9]]*x[[0-9]][[0-9]]*\)\..*$/\1/'`
				cf_left=`echo "$cf_left"|sed -e 's/^\(.*\)_\([[0-9]][[0-9]]*x[[0-9]][[0-9]]*\)\(\..*\)$/\1\3/'`
				cf_next="$cf_size/apps/$cf_base"
				;;
			esac
			CF_VERBOSE(adding $cf_next)
			cf_icon="${cf_icon}:${cf_next}"
		fi
		test -n "$ICON_LIST" && ICON_LIST="$ICON_LIST "
		ICON_LIST="$ICON_LIST${cf_icon}"
		if test -z "$ICON_NAME"
		then
			ICON_NAME=`basename "$cf_icon" | sed -e 's/[[.:]].*//'`
		fi
	done
done

if test -n "$verbose"
then
	AC_MSG_CHECKING(result)
fi
AC_MSG_RESULT($ICON_LIST)

if test -z "$ICON_LIST"
then
	AC_MSG_ERROR(no icons found)
fi
])

AC_MSG_CHECKING(for icon name)
AC_MSG_RESULT($ICON_NAME)

AC_SUBST(ICON_FORMAT)
AC_SUBST(ICON_THEME)
AC_SUBST(ICON_LIST)
AC_SUBST(ICON_NAME)
])dnl
dnl ---------------------------------------------------------------------------
dnl CF_WITH_IMAKE_CFLAGS version: 10 updated: 2015/04/12 15:39:00
dnl --------------------
dnl xterm and similar programs build more readily when propped up with imake's
dnl hand-tuned definitions.  If we do not use imake, provide fallbacks for the
dnl most common definitions that we're not likely to do by autoconf tests.
AC_DEFUN([CF_WITH_IMAKE_CFLAGS],[
AC_REQUIRE([CF_ENABLE_NARROWPROTO])

AC_MSG_CHECKING(if we should use imake to help)
CF_ARG_DISABLE(imake,
	[  --disable-imake         disable use of imake for definitions],
	[enable_imake=no],
	[enable_imake=yes])
AC_MSG_RESULT($enable_imake)

if test "$enable_imake" = yes ; then
	CF_IMAKE_CFLAGS(ifelse([$1],,,[$1]))
fi

if test -n "$IMAKE" && test -n "$IMAKE_CFLAGS" ; then
	CF_ADD_CFLAGS($IMAKE_CFLAGS)
else
	IMAKE_CFLAGS=
	IMAKE_LOADFLAGS=
	CF_VERBOSE(make fallback definitions)

	# We prefer config.guess' values when we can get them, to avoid
	# inconsistent results with uname (AIX for instance).  However,
	# config.guess is not always consistent either.
	case $host_os in
	(*[[0-9]].[[0-9]]*)
		UNAME_RELEASE="$host_os"
		;;
	(*)
		UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown
		;;
	esac

	case .$UNAME_RELEASE in
	(*[[0-9]].[[0-9]]*)
		OSMAJORVERSION=`echo "$UNAME_RELEASE" |sed -e 's/^[[^0-9]]*//' -e 's/\..*//'`
		OSMINORVERSION=`echo "$UNAME_RELEASE" |sed -e 's/^[[^0-9]]*//' -e 's/^[[^.]]*\.//' -e 's/\..*//' -e 's/[[^0-9]].*//' `
		test -z "$OSMAJORVERSION" && OSMAJORVERSION=1
		test -z "$OSMINORVERSION" && OSMINORVERSION=0
		IMAKE_CFLAGS="-DOSMAJORVERSION=$OSMAJORVERSION -DOSMINORVERSION=$OSMINORVERSION $IMAKE_CFLAGS"
		;;
	esac

	# FUNCPROTO is standard with X11R6, but XFree86 drops it, leaving some
	# fallback/fragments for NeedPrototypes, etc.
	IMAKE_CFLAGS="-DFUNCPROTO=15 $IMAKE_CFLAGS"

	# If this is not set properly, Xaw's scrollbars will not work
	if test "$enable_narrowproto" = yes ; then
		IMAKE_CFLAGS="-DNARROWPROTO=1 $IMAKE_CFLAGS"
	fi

	# Other special definitions:
	case $host_os in
	(aix*)
		# imake on AIX 5.1 defines AIXV3.  really.
		IMAKE_CFLAGS="-DAIXV3 -DAIXV4 $IMAKE_CFLAGS"
		;;
	(irix[[56]].*)
		# these are needed to make SIGWINCH work in xterm
		IMAKE_CFLAGS="-DSYSV -DSVR4 $IMAKE_CFLAGS"
		;;
	esac

	CF_ADD_CFLAGS($IMAKE_CFLAGS)

	AC_SUBST(IMAKE_CFLAGS)
	AC_SUBST(IMAKE_LOADFLAGS)
fi
])dnl
dnl ---------------------------------------------------------------------------
dnl CF_WITH_MAN2HTML version: 12 updated: 2021/01/03 18:30:50
dnl ----------------
dnl Check for man2html and groff.  Prefer man2html over groff, but use groff
dnl as a fallback.  See
dnl
dnl		http://invisible-island.net/scripts/man2html.html
dnl
dnl Generate a shell script which hides the differences between the two.
dnl
dnl We name that "man2html.tmp".
dnl
dnl The shell script can be removed later, e.g., using "make distclean".
AC_DEFUN([CF_WITH_MAN2HTML],[
AC_REQUIRE([CF_PROG_GROFF])dnl
AC_REQUIRE([AC_PROG_FGREP])dnl

case "x${with_man2html}" in
(xno)
	cf_man2html=no
	;;
(x|xyes)
	AC_PATH_PROG(cf_man2html,man2html,no)
	case "x$cf_man2html" in
	(x/*)
		AC_MSG_CHECKING(for the modified Earl Hood script)
		if ( $cf_man2html -help 2>&1 | grep 'Make an index of headers at the end' >/dev/null )
		then
			cf_man2html_ok=yes
		else
			cf_man2html=no
			cf_man2html_ok=no
		fi
		AC_MSG_RESULT($cf_man2html_ok)
		;;
	(*)
		cf_man2html=no
		;;
	esac
esac

AC_MSG_CHECKING(for program to convert manpage to html)
AC_ARG_WITH(man2html,
	[  --with-man2html=XXX     use XXX rather than groff],
	[cf_man2html=$withval],
	[cf_man2html=$cf_man2html])

cf_with_groff=no

case $cf_man2html in
(yes)
	AC_MSG_RESULT(man2html)
	AC_PATH_PROG(cf_man2html,man2html,no)
	;;
(no|groff|*/groff*)
	cf_with_groff=yes
	cf_man2html=$GROFF_PATH
	AC_MSG_RESULT($cf_man2html)
	;;
(*)
	AC_MSG_RESULT($cf_man2html)
	;;
esac

MAN2HTML_TEMP="man2html.tmp"
	cat >$MAN2HTML_TEMP <>$MAN2HTML_TEMP <conftest.in <conftest.out

	cf_man2html_1st="`${FGREP-fgrep} -n MARKER conftest.out |sed -e 's/^[[^0-9]]*://' -e 's/:.*//'`"
	cf_man2html_top=`expr "$cf_man2html_1st" - 2`
	cf_man2html_bot="`wc -l conftest.out |sed -e 's/[[^0-9]]//g'`"
	cf_man2html_bot=`expr "$cf_man2html_bot" - 2 - "$cf_man2html_top"`
	cf_man2html_top_bot="-topm=$cf_man2html_top -botm=$cf_man2html_bot"

	AC_MSG_RESULT($cf_man2html_top_bot)

	AC_MSG_CHECKING(for pagesize to use)
	for cf_block in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
	do
	cat >>conftest.in <conftest.out
	cf_man2html_page="`${FGREP-fgrep} -n HEAD1 conftest.out |sed -n '$p' |sed -e 's/^[[^0-9]]*://' -e 's/:.*//'`"
	test -z "$cf_man2html_page" && cf_man2html_page=99999
	test "$cf_man2html_page" -gt 100 && cf_man2html_page=99999

	rm -rf conftest*
	AC_MSG_RESULT($cf_man2html_page)

	cat >>$MAN2HTML_TEMP <
#include 
#include 
#undef main],[
		PerlInterpreter* interp = perl_alloc();
		perl_construct(interp);
		perl_parse(interp, 0, 0, (char **)0, (char **)0);
		Perl_croak("Why:%s\\n", "Bye!");
],[
		eval `$PERL -le 'for $f (qw/xsubpp typemap/) {
				   @p = grep -f, map "$_/ExtUtils/$f", @INC;
				   print "cf_path_$f=", $p[[0]];
				 }'`

		PERL_XSUBPP="${cf_path_xsubpp:?} -typemap ${cf_path_typemap:?}"

		CF_VERBOSE(setting perl xs compiler to $PERL_XSUBPP)

		AC_DEFINE(OPT_PERL,1,[Define to 1 if we should compile-in the perl extension])

		EXTRAOBJS="$EXTRAOBJS perl\$o"
		BUILTSRCS="$BUILTSRCS perl.c"

		EXTRA_INSTALL_DIRS="$EXTRA_INSTALL_DIRS \$(INSTALL_PERL_DIRS)"
		EXTRA_INSTALL_FILES="$EXTRA_INSTALL_FILES \$(INSTALL_PERL_FILES)"
],[
		AC_MSG_WARN(Cannot link with Perl interpreter)

		CF_VERBOSE([undoing changes to CFLAGS, etc])

		CFLAGS="$cf_perl_CFLAGS"
		CPPFLAGS="$cf_perl_CPPFLAGS"
		ac_link="$cf_perl_link"
		LIBS="$cf_perl_LIBS"
])
	fi
fi
AC_SUBST(PERL)
AC_SUBST(PERL_XSUBPP)
AC_SUBST(EXTRA_INSTALL_DIRS)
AC_SUBST(EXTRA_INSTALL_FILES)
])
dnl ---------------------------------------------------------------------------
dnl CF_WITH_PIXMAPDIR version: 3 updated: 2012/07/22 09:18:02
dnl -----------------
dnl Handle configure option "--with-pixmapdir", setting these shell variables:
dnl
dnl $PIXMAPDIR is the option value, used for installing pixmap files.
dnl $no_pixmapdir is a "#" (comment) if "--without-pixmapdir" is given.
AC_DEFUN([CF_WITH_PIXMAPDIR],[
AC_MSG_CHECKING(for directory to install pixmaps)
AC_ARG_WITH(pixmapdir,
	[  --with-pixmapdir=DIR    directory in which to install pixmaps (DATADIR/pixmaps)],
	[PIXMAPDIR=$withval],
	[test -z "$PIXMAPDIR" && PIXMAPDIR='${datadir}/pixmaps'])

if test "x[$]PIXMAPDIR" = xauto
then
	PIXMAPDIR='${datadir}/pixmaps'
	for cf_path in \
		/usr/share/pixmaps \
		/usr/X11R6/share/pixmaps
	do
		if test -d "$cf_path" ; then
			PIXMAPDIR="$cf_path"
			break
		fi
	done
else
	cf_path=$PIXMAPDIR
	CF_PATH_SYNTAX(cf_path)
fi
AC_MSG_RESULT($PIXMAPDIR)
AC_SUBST(PIXMAPDIR)

no_pixmapdir=
if test "$PIXMAPDIR" = no
then
	no_pixmapdir="#"
else
	EXTRA_INSTALL_DIRS="$EXTRA_INSTALL_DIRS \$(PIXMAPDIR)"
fi
AC_SUBST(no_pixmapdir)
])dnl
dnl ---------------------------------------------------------------------------
dnl CF_WITH_PURIFY version: 2 updated: 2006/12/14 18:43:43
dnl --------------
AC_DEFUN([CF_WITH_PURIFY],[
CF_NO_LEAKS_OPTION(purify,
	[  --with-purify           test: use Purify],
	[USE_PURIFY],
	[LINK_PREFIX="$LINK_PREFIX purify"])
AC_SUBST(LINK_PREFIX)
])dnl
dnl ---------------------------------------------------------------------------
dnl CF_WITH_SYMLINK version: 6 updated: 2020/12/31 20:19:42
dnl ---------------
dnl If any of --program-prefix, --program-suffix or --program-transform-name is
dnl given, accept an option tell the makefile to create a symbolic link, e.g.,
dnl to the given program on install.
dnl
dnl $1 = variable to substitute
dnl $2 = program name
dnl $3 = option default
AC_DEFUN([CF_WITH_SYMLINK],[
$1=NONE
AC_SUBST($1)
if test "$program_transform_name" != "CF__INIT_TRANSFORM" ; then
cf_name=`echo "$program_transform_name" | sed -e '[s,\\$\\$,$,g]'`
cf_name=`echo "$2" |sed -e "$cf_name"`
AC_MSG_CHECKING(for symbolic link to create to $cf_name)
AC_ARG_WITH(symlink,
	[  --with-symlink=XXX      make symbolic link to installed application],
	[with_symlink=$withval],
	[with_symlink=$3])
AC_MSG_RESULT($with_symlink)
test "$with_symlink" = yes && with_symlink=$2
test -n "$with_symlink" && \
	test "$with_symlink" != no && \
	test "$with_symlink" != "$cf_name" && \
	$1="$with_symlink"
else
	with_symlink=$3
fi
])
dnl ---------------------------------------------------------------------------
dnl CF_WITH_VALGRIND version: 1 updated: 2006/12/14 18:00:21
dnl ----------------
AC_DEFUN([CF_WITH_VALGRIND],[
CF_NO_LEAKS_OPTION(valgrind,
	[  --with-valgrind         test: use valgrind],
	[USE_VALGRIND])
])dnl
dnl ---------------------------------------------------------------------------
dnl CF_WITH_XPM version: 3 updated: 2012/10/04 06:57:36
dnl -----------
dnl Test for Xpm library, update compiler/loader flags if it is wanted and
dnl found.
dnl
dnl Also sets ICON_SUFFIX
AC_DEFUN([CF_WITH_XPM],
[
ICON_SUFFIX=.xbm

cf_save_cppflags="${CPPFLAGS}"
cf_save_ldflags="${LDFLAGS}"

AC_MSG_CHECKING(if you want to use the Xpm library for colored icon)
AC_ARG_WITH(xpm,
[  --with-xpm=DIR          use Xpm library for colored icon, may specify path],
	[cf_Xpm_library="$withval"],
	[cf_Xpm_library=yes])
AC_MSG_RESULT($cf_Xpm_library)

if test "$cf_Xpm_library" != no ; then
    if test "$cf_Xpm_library" != yes ; then
	CPPFLAGS="$CPPFLAGS -I$withval/include"
	LDFLAGS="$LDFLAGS -L$withval/lib"
    fi
    AC_CHECK_HEADER(X11/xpm.h,[
	AC_CHECK_LIB(Xpm, XpmCreatePixmapFromData,[
	    AC_DEFINE(HAVE_LIBXPM,1,[Define to 1 if we should use Xpm library])
	    ICON_SUFFIX=.xpm
	    LIBS="-lXpm $LIBS"],
	    [CPPFLAGS="${cf_save_cppflags}" LDFLAGS="${cf_save_ldflags}"],
	    [-lX11 $X_LIBS])],
	[CPPFLAGS="${cf_save_cppflags}" LDFLAGS="${cf_save_ldflags}"])
fi

AC_SUBST(ICON_SUFFIX)
])dnl
dnl ---------------------------------------------------------------------------
dnl CF_WITH_X_DESKTOP_UTILS version: 2 updated: 2010/01/25 20:34:54
dnl -----------------------
dnl Option for specifying desktop-utils program and flags.
AC_DEFUN([CF_WITH_X_DESKTOP_UTILS],
[
	# Comment-out the install-desktop rule if the desktop-utils are not found.
	AC_MSG_CHECKING(if you want to install desktop files)
	CF_ARG_OPTION(desktop,
		[  --disable-desktop       disable install of X desktop files],
		[enable_desktop=$enableval],
		[enable_desktop=$enableval],yes)
	AC_MSG_RESULT($enable_desktop)

	desktop_utils=
	if test "$enable_desktop" = yes ; then
	AC_CHECK_PROG(desktop_utils,desktop-file-install,yes,no)
	fi

	test "$desktop_utils" = yes && desktop_utils= || desktop_utils="#"
	AC_SUBST(DESKTOP_FLAGS)
])
dnl ---------------------------------------------------------------------------
dnl CF_XOPEN_CURSES version: 17 updated: 2021/07/10 12:22:27
dnl ---------------
dnl Test if we should define X/Open source for curses, needed on Digital Unix
dnl 4.x, to see the extended functions, but breaks on IRIX 6.x.
dnl
dnl The getbegyx() check is needed for HPUX, which omits legacy macros such
dnl as getbegy().  The latter is better design, but the former is standard.
AC_DEFUN([CF_XOPEN_CURSES],
[
AC_REQUIRE([CF_CURSES_CPPFLAGS])dnl
AC_CACHE_CHECK(definition to turn on extended curses functions,cf_cv_need_xopen_extension,[
cf_cv_need_xopen_extension=unknown
AC_TRY_LINK([
#include 
#include <${cf_cv_ncurses_header:-curses.h}>],[
#if defined(NCURSES_VERSION_PATCH)
#if (NCURSES_VERSION_PATCH < 20100501) && (NCURSES_VERSION_PATCH >= 20100403)
	make an error
#endif
#endif
#ifdef NCURSES_WIDECHAR
make an error	/* prefer to fall-through on the second checks */
#endif
	cchar_t check;
	int check2 = curs_set((int)sizeof(check));
	long x = winnstr(stdscr, "", 0);
	int x1, y1;
	(void)check2;
	getbegyx(stdscr, y1, x1);
	(void)x;
	(void)y1;
	(void)x1;
	],
	[cf_cv_need_xopen_extension=none],
	[
	for cf_try_xopen_extension in _XOPEN_SOURCE_EXTENDED NCURSES_WIDECHAR
	do
		AC_TRY_LINK([
#define $cf_try_xopen_extension 1
#include 
#include <${cf_cv_ncurses_header:-curses.h}>],[
		cchar_t check;
		int check2 = curs_set((int)sizeof(check));
		long x = winnstr(stdscr, "", 0);
		int x1, y1;
		getbegyx(stdscr, y1, x1);
		(void)check2;
		(void)x;
		(void)y1;
		(void)x1;
		],
		[cf_cv_need_xopen_extension=$cf_try_xopen_extension; break])
	done
	])
])

case "$cf_cv_need_xopen_extension" in
(*_*)
	CF_APPEND_TEXT(CPPFLAGS,-D$cf_cv_need_xopen_extension)
	;;
esac

])dnl
dnl ---------------------------------------------------------------------------
dnl CF_XOPEN_SOURCE version: 59 updated: 2021/08/28 15:20:37
dnl ---------------
dnl Try to get _XOPEN_SOURCE defined properly that we can use POSIX functions,
dnl or adapt to the vendor's definitions to get equivalent functionality,
dnl without losing the common non-POSIX features.
dnl
dnl Parameters:
dnl	$1 is the nominal value for _XOPEN_SOURCE
dnl	$2 is the nominal value for _POSIX_C_SOURCE
AC_DEFUN([CF_XOPEN_SOURCE],[
AC_REQUIRE([AC_CANONICAL_HOST])
AC_REQUIRE([CF_POSIX_VISIBLE])

if test "$cf_cv_posix_visible" = no; then

cf_XOPEN_SOURCE=ifelse([$1],,500,[$1])
cf_POSIX_C_SOURCE=ifelse([$2],,199506L,[$2])
cf_xopen_source=

case "$host_os" in
(aix[[4-7]]*)
	cf_xopen_source="-D_ALL_SOURCE"
	;;
(msys)
	cf_XOPEN_SOURCE=600
	;;
(darwin[[0-8]].*)
	cf_xopen_source="-D_APPLE_C_SOURCE"
	;;
(darwin*)
	cf_xopen_source="-D_DARWIN_C_SOURCE"
	cf_XOPEN_SOURCE=
	;;
(freebsd*|dragonfly*|midnightbsd*)
	# 5.x headers associate
	#	_XOPEN_SOURCE=600 with _POSIX_C_SOURCE=200112L
	#	_XOPEN_SOURCE=500 with _POSIX_C_SOURCE=199506L
	cf_POSIX_C_SOURCE=200112L
	cf_XOPEN_SOURCE=600
	cf_xopen_source="-D_BSD_TYPES -D__BSD_VISIBLE -D_POSIX_C_SOURCE=$cf_POSIX_C_SOURCE -D_XOPEN_SOURCE=$cf_XOPEN_SOURCE"
	;;
(hpux11*)
	cf_xopen_source="-D_HPUX_SOURCE -D_XOPEN_SOURCE=500"
	;;
(hpux*)
	cf_xopen_source="-D_HPUX_SOURCE"
	;;
(irix[[56]].*)
	cf_xopen_source="-D_SGI_SOURCE"
	cf_XOPEN_SOURCE=
	;;
(linux*|uclinux*|gnu*|mint*|k*bsd*-gnu|cygwin)
	CF_GNU_SOURCE($cf_XOPEN_SOURCE)
	;;
(minix*)
	cf_xopen_source="-D_NETBSD_SOURCE" # POSIX.1-2001 features are ifdef'd with this...
	;;
(mirbsd*)
	# setting _XOPEN_SOURCE or _POSIX_SOURCE breaks  and other headers which use u_int / u_short types
	cf_XOPEN_SOURCE=
	CF_POSIX_C_SOURCE($cf_POSIX_C_SOURCE)
	;;
(netbsd*)
	cf_xopen_source="-D_NETBSD_SOURCE" # setting _XOPEN_SOURCE breaks IPv6 for lynx on NetBSD 1.6, breaks xterm, is not needed for ncursesw
	;;
(openbsd[[6-9]]*)
	# OpenBSD 6.x has broken locale support, both compile-time and runtime.
	# see https://www.mail-archive.com/bugs@openbsd.org/msg13200.html
	# Abusing the conformance level is a workaround.
	AC_MSG_WARN(this system does not provide usable locale support)
	cf_xopen_source="-D_BSD_SOURCE"
	cf_XOPEN_SOURCE=700
	;;
(openbsd[[4-5]]*)
	# setting _XOPEN_SOURCE lower than 500 breaks g++ compile with wchar.h, needed for ncursesw
	cf_xopen_source="-D_BSD_SOURCE"
	cf_XOPEN_SOURCE=600
	;;
(openbsd*)
	# setting _XOPEN_SOURCE breaks xterm on OpenBSD 2.8, is not needed for ncursesw
	;;
(osf[[45]]*)
	cf_xopen_source="-D_OSF_SOURCE"
	;;
(nto-qnx*)
	cf_xopen_source="-D_QNX_SOURCE"
	;;
(sco*)
	# setting _XOPEN_SOURCE breaks Lynx on SCO Unix / OpenServer
	;;
(solaris2.*)
	cf_xopen_source="-D__EXTENSIONS__"
	cf_cv_xopen_source=broken
	;;
(sysv4.2uw2.*) # Novell/SCO UnixWare 2.x (tested on 2.1.2)
	cf_XOPEN_SOURCE=
	cf_POSIX_C_SOURCE=
	;;
(*)
	CF_TRY_XOPEN_SOURCE
	CF_POSIX_C_SOURCE($cf_POSIX_C_SOURCE)
	;;
esac

if test -n "$cf_xopen_source" ; then
	CF_APPEND_CFLAGS($cf_xopen_source,true)
fi

dnl In anything but the default case, we may have system-specific setting
dnl which is still not guaranteed to provide all of the entrypoints that
dnl _XOPEN_SOURCE would yield.
if test -n "$cf_XOPEN_SOURCE" && test -z "$cf_cv_xopen_source" ; then
	AC_MSG_CHECKING(if _XOPEN_SOURCE really is set)
	AC_TRY_COMPILE([#include ],[
#ifndef _XOPEN_SOURCE
make an error
#endif],
	[cf_XOPEN_SOURCE_set=yes],
	[cf_XOPEN_SOURCE_set=no])
	AC_MSG_RESULT($cf_XOPEN_SOURCE_set)
	if test "$cf_XOPEN_SOURCE_set" = yes
	then
		AC_TRY_COMPILE([#include ],[
#if (_XOPEN_SOURCE - 0) < $cf_XOPEN_SOURCE
make an error
#endif],
		[cf_XOPEN_SOURCE_set_ok=yes],
		[cf_XOPEN_SOURCE_set_ok=no])
		if test "$cf_XOPEN_SOURCE_set_ok" = no
		then
			AC_MSG_WARN(_XOPEN_SOURCE is lower than requested)
		fi
	else
		CF_TRY_XOPEN_SOURCE
	fi
fi
fi # cf_cv_posix_visible
])
dnl ---------------------------------------------------------------------------
dnl CF_X_ATHENA version: 24 updated: 2020/03/10 18:53:47
dnl -----------
dnl Check for Xaw (Athena) libraries
dnl
dnl Sets $cf_x_athena according to the flavor of Xaw which is used.
AC_DEFUN([CF_X_ATHENA],
[
cf_x_athena=${cf_x_athena:-Xaw}

AC_MSG_CHECKING(if you want to link with Xaw 3d library)
withval=
AC_ARG_WITH(Xaw3d,
	[  --with-Xaw3d            link with Xaw 3d library])
if test "$withval" = yes ; then
	cf_x_athena=Xaw3d
	AC_MSG_RESULT(yes)
else
	AC_MSG_RESULT(no)
fi

AC_MSG_CHECKING(if you want to link with Xaw 3d xft library)
withval=
AC_ARG_WITH(Xaw3dxft,
	[  --with-Xaw3dxft         link with Xaw 3d xft library])
if test "$withval" = yes ; then
	cf_x_athena=Xaw3dxft
	AC_MSG_RESULT(yes)
else
	AC_MSG_RESULT(no)
fi

AC_MSG_CHECKING(if you want to link with neXT Athena library)
withval=
AC_ARG_WITH(neXtaw,
	[  --with-neXtaw           link with neXT Athena library])
if test "$withval" = yes ; then
	cf_x_athena=neXtaw
	AC_MSG_RESULT(yes)
else
	AC_MSG_RESULT(no)
fi

AC_MSG_CHECKING(if you want to link with Athena-Plus library)
withval=
AC_ARG_WITH(XawPlus,
	[  --with-XawPlus          link with Athena-Plus library])
if test "$withval" = yes ; then
	cf_x_athena=XawPlus
	AC_MSG_RESULT(yes)
else
	AC_MSG_RESULT(no)
fi

cf_x_athena_lib=""

if test "$PKG_CONFIG" != none ; then
	cf_athena_list=
	test "$cf_x_athena" = Xaw && cf_athena_list="xaw8 xaw7 xaw6"
	for cf_athena_pkg in \
		$cf_athena_list \
		${cf_x_athena} \
		${cf_x_athena}-devel \
		lib${cf_x_athena} \
		lib${cf_x_athena}-devel
	do
		CF_TRY_PKG_CONFIG($cf_athena_pkg,[
			cf_x_athena_lib="$cf_pkgconfig_libs"
			CF_UPPER(cf_x_athena_LIBS,HAVE_LIB_$cf_x_athena)
			AC_DEFINE_UNQUOTED($cf_x_athena_LIBS)

			CF_TRIM_X_LIBS

AC_CACHE_CHECK(for usable $cf_x_athena/Xmu package,cf_cv_xaw_compat,[
AC_TRY_LINK([
#include 
],[
int check = XmuCompareISOLatin1("big", "small");
(void)check;
],[cf_cv_xaw_compat=yes],[cf_cv_xaw_compat=no])])

			if test "$cf_cv_xaw_compat" = no
			then
				# workaround for broken ".pc" files...
				case "$cf_x_athena_lib" in
				(*-lXmu*)
					;;
				(*)
					CF_VERBOSE(work around broken package)
					cf_save_xmu="$LIBS"
					cf_first_lib=`echo "$cf_save_xmu" | sed -e 's/^[ ][ ]*//' -e 's/ .*//'`
					CF_TRY_PKG_CONFIG(xmu,[
							LIBS="$cf_save_xmu"
							CF_ADD_LIB_AFTER($cf_first_lib,$cf_pkgconfig_libs)
						],[
							CF_ADD_LIB_AFTER($cf_first_lib,-lXmu)
						])
					CF_TRIM_X_LIBS
					;;
				esac
			fi

			break])
	done
fi

if test -z "$cf_x_athena_lib" ; then
	CF_X_EXT
	CF_X_TOOLKIT
	CF_X_ATHENA_CPPFLAGS($cf_x_athena)
	CF_X_ATHENA_LIBS($cf_x_athena)
fi
])dnl
dnl ---------------------------------------------------------------------------
dnl CF_X_ATHENA_CPPFLAGS version: 9 updated: 2020/12/31 10:54:15
dnl --------------------
dnl Normally invoked by CF_X_ATHENA, with $1 set to the appropriate flavor of
dnl the Athena widgets, e.g., Xaw, Xaw3d, neXtaw.
AC_DEFUN([CF_X_ATHENA_CPPFLAGS],
[
AC_REQUIRE([AC_PATH_XTRA])
cf_x_athena_root=ifelse([$1],,Xaw,[$1])
cf_x_athena_inc=""

for cf_path in default \
	/usr/contrib/X11R6 \
	/usr/contrib/X11R5 \
	/usr/lib/X11R5 \
	/usr/local
do
	if test -z "$cf_x_athena_inc" ; then
		CF_SAVE_XTRA_FLAGS([CF_X_ATHENA_CPPFLAGS])
		cf_test=X11/$cf_x_athena_root/SimpleMenu.h
		if test "$cf_path" != default ; then
			CF_APPEND_TEXT(CPPFLAGS,-I$cf_path/include)
			AC_MSG_CHECKING(for $cf_test in $cf_path)
		else
			AC_MSG_CHECKING(for $cf_test)
		fi
		AC_TRY_COMPILE([
#include 
#include <$cf_test>],[],
			[cf_result=yes],
			[cf_result=no])
		AC_MSG_RESULT($cf_result)
		CF_RESTORE_XTRA_FLAGS([CF_X_ATHENA_CPPFLAGS])
		if test "$cf_result" = yes ; then
			test "$cf_path"  = default && cf_x_athena_inc=default
			test "$cf_path" != default && cf_x_athena_inc="$cf_path/include"
			break
		fi
	fi
done

if test -z "$cf_x_athena_inc" ; then
	AC_MSG_WARN([Unable to find Athena header files])
elif test "$cf_x_athena_inc" != default ; then
	CF_APPEND_TEXT(CPPFLAGS,-I$cf_x_athena_inc)
fi
])
dnl ---------------------------------------------------------------------------
dnl CF_X_ATHENA_LIBS version: 13 updated: 2020/01/11 18:16:10
dnl ----------------
dnl Normally invoked by CF_X_ATHENA, with $1 set to the appropriate flavor of
dnl the Athena widgets, e.g., Xaw, Xaw3d, neXtaw.
AC_DEFUN([CF_X_ATHENA_LIBS],
[AC_REQUIRE([CF_X_TOOLKIT])
cf_x_athena_root=ifelse([$1],,Xaw,[$1])
cf_x_athena_lib=""

for cf_path in default \
	/usr/contrib/X11R6 \
	/usr/contrib/X11R5 \
	/usr/lib/X11R5 \
	/usr/local
do
	for cf_lib in \
		${cf_x_athena_root} \
		${cf_x_athena_root}7 \
		${cf_x_athena_root}6
	do
	for cf_libs in \
		"-l$cf_lib -lXmu" \
		"-l$cf_lib -lXpm -lXmu" \
		"-l${cf_lib}_s -lXmu_s"
	do
		test -n "$cf_x_athena_lib" && break

		CF_SAVE_XTRA_FLAGS([CF_X_ATHENA_LIBS])
		cf_test=XawSimpleMenuAddGlobalActions
		test "$cf_path" != default && cf_libs="-L$cf_path/lib $cf_libs"
		CF_ADD_LIBS($cf_libs)
		AC_MSG_CHECKING(for $cf_test in $cf_libs)
		AC_TRY_LINK([
#include 
#include 
],[
$cf_test((XtAppContext) 0)],
			[cf_result=yes],
			[cf_result=no])
		AC_MSG_RESULT($cf_result)
		CF_RESTORE_XTRA_FLAGS([CF_X_ATHENA_LIBS])

		if test "$cf_result" = yes ; then
			cf_x_athena_lib="$cf_libs"
			break
		fi
	done # cf_libs
		test -n "$cf_x_athena_lib" && break
	done # cf_lib
done

if test -z "$cf_x_athena_lib" ; then
	AC_MSG_ERROR(
[Unable to successfully link Athena library (-l$cf_x_athena_root) with test program])
fi

CF_ADD_LIBS($cf_x_athena_lib)
CF_UPPER(cf_x_athena_LIBS,HAVE_LIB_$cf_x_athena)
AC_DEFINE_UNQUOTED($cf_x_athena_LIBS)
])
dnl ---------------------------------------------------------------------------
dnl CF_X_EXT version: 3 updated: 2010/06/02 05:03:05
dnl --------
AC_DEFUN([CF_X_EXT],[
CF_TRY_PKG_CONFIG(Xext,,[
	AC_CHECK_LIB(Xext,XextCreateExtension,
		[CF_ADD_LIB(Xext)])])
])dnl
dnl ---------------------------------------------------------------------------
dnl CF_X_FONTCONFIG version: 7 updated: 2020/03/10 18:53:47
dnl ---------------
dnl Check for fontconfig library, a dependency of the X FreeType library.
AC_DEFUN([CF_X_FONTCONFIG],
[
AC_REQUIRE([CF_X_FREETYPE])

if test "$cf_cv_found_freetype" = yes ; then
AC_CACHE_CHECK(for usable Xft/fontconfig package,cf_cv_xft_compat,[
AC_TRY_LINK([
#include 
],[
	XftPattern *pat = 0;
	XftPatternBuild(pat,
					XFT_FAMILY, XftTypeString, "mono",
					(void *) 0);
],[cf_cv_xft_compat=yes],[cf_cv_xft_compat=no])
])

if test "$cf_cv_xft_compat" = no
then
	# workaround for broken ".pc" files used for Xft.
	case "$cf_cv_x_freetype_libs" in
	(*-lfontconfig*)
		;;
	(*)
		CF_VERBOSE(work around broken package)
		cf_save_fontconfig="$LIBS"
		CF_TRY_PKG_CONFIG(fontconfig,[
				CF_ADD_CFLAGS($cf_pkgconfig_incs)
				LIBS="$cf_save_fontconfig"
				CF_ADD_LIB_AFTER(-lXft,$cf_pkgconfig_libs)
			],[
				CF_ADD_LIB_AFTER(-lXft,-lfontconfig)
			])
		;;
	esac
fi
fi
])dnl
dnl ---------------------------------------------------------------------------
dnl CF_X_FREETYPE version: 28 updated: 2020/03/10 18:53:47
dnl -------------
dnl Check for X FreeType headers and libraries (XFree86 4.x, etc).
dnl
dnl First check for the appropriate config program, since the developers for
dnl these libraries change their configuration (and config program) more or
dnl less randomly.  If we cannot find the config program, do not bother trying
dnl to guess the latest variation of include/lib directories.
dnl
dnl If either or both of these configure-script options are not given, rely on
dnl the output of the config program to provide the cflags/libs options:
dnl	--with-freetype-cflags
dnl	--with-freetype-libs
AC_DEFUN([CF_X_FREETYPE],
[
AC_REQUIRE([CF_PKG_CONFIG])

cf_cv_x_freetype_incs=no
cf_cv_x_freetype_libs=no
cf_extra_freetype_libs=
FREETYPE_CONFIG=none
FREETYPE_PARAMS=

AC_MSG_CHECKING(for FreeType configuration script)
AC_ARG_WITH(freetype-config,
	[  --with-freetype-config  configure script to use for FreeType],
	[cf_cv_x_freetype_cfgs="$withval"],
	[cf_cv_x_freetype_cfgs=auto])
test -z $cf_cv_x_freetype_cfgs && cf_cv_x_freetype_cfgs=auto
test $cf_cv_x_freetype_cfgs = no && cf_cv_x_freetype_cfgs=none
AC_MSG_RESULT($cf_cv_x_freetype_cfgs)

case $cf_cv_x_freetype_cfgs in
(none)
	AC_MSG_CHECKING(if you specified -D/-I options for FreeType)
	AC_ARG_WITH(freetype-cflags,
		[  --with-freetype-cflags  -D/-I options for compiling with FreeType],
		[cf_cv_x_freetype_incs="$with_freetype_cflags"],
		[cf_cv_x_freetype_incs=no])
	AC_MSG_RESULT($cf_cv_x_freetype_incs)

	AC_MSG_CHECKING(if you specified -L/-l options for FreeType)
	AC_ARG_WITH(freetype-libs,
		[  --with-freetype-libs    -L/-l options to link FreeType],
		[cf_cv_x_freetype_libs="$with_freetype_libs"],
		[cf_cv_x_freetype_libs=no])
	AC_MSG_RESULT($cf_cv_x_freetype_libs)
	;;
(auto)
	if test "$PKG_CONFIG" != none && "$PKG_CONFIG" --exists xft; then
		FREETYPE_CONFIG=$PKG_CONFIG
		FREETYPE_PARAMS=xft
	else
		AC_PATH_PROG(FREETYPE_CONFIG, freetype-config, none)
		if test "$FREETYPE_CONFIG" != none; then
			FREETYPE_CONFIG=$FREETYPE_CONFIG
			cf_extra_freetype_libs="-lXft"
		else
			AC_PATH_PROG(FREETYPE_OLD_CONFIG, xft-config, none)
			if test "$FREETYPE_OLD_CONFIG" != none; then
				FREETYPE_CONFIG=$FREETYPE_OLD_CONFIG
			fi
		fi
	fi
	;;
(pkg*)
	if test "$PKG_CONFIG" != none && "$PKG_CONFIG" --exists xft; then
		FREETYPE_CONFIG=$cf_cv_x_freetype_cfgs
		FREETYPE_PARAMS=xft
	else
		AC_MSG_WARN(cannot find pkg-config for Xft)
	fi
	;;
(*)
	AC_PATH_PROG(FREETYPE_XFT_CONFIG, $cf_cv_x_freetype_cfgs, none)
	if test "$FREETYPE_XFT_CONFIG" != none; then
		FREETYPE_CONFIG=$FREETYPE_XFT_CONFIG
	else
		AC_MSG_WARN(cannot find config script for Xft)
	fi
	;;
esac

if test "$FREETYPE_CONFIG" != none ; then
	AC_MSG_CHECKING(for FreeType config)
	AC_MSG_RESULT($FREETYPE_CONFIG $FREETYPE_PARAMS)

	if test "$cf_cv_x_freetype_incs" = no ; then
		AC_MSG_CHECKING(for $FREETYPE_CONFIG cflags)
		cf_cv_x_freetype_incs="`$FREETYPE_CONFIG $FREETYPE_PARAMS --cflags 2>/dev/null`"
		AC_MSG_RESULT($cf_cv_x_freetype_incs)
	fi

	if test "$cf_cv_x_freetype_libs" = no ; then
		AC_MSG_CHECKING(for $FREETYPE_CONFIG libs)
		cf_cv_x_freetype_libs="$cf_extra_freetype_libs `$FREETYPE_CONFIG $FREETYPE_PARAMS --libs 2>/dev/null`"
		AC_MSG_RESULT($cf_cv_x_freetype_libs)
	fi
fi

if test "$cf_cv_x_freetype_incs" = no ; then
	cf_cv_x_freetype_incs=
fi

if test "$cf_cv_x_freetype_libs" = no ; then
	cf_cv_x_freetype_libs=-lXft
fi

AC_MSG_CHECKING(if we can link with FreeType libraries)

cf_save_LIBS="$LIBS"
cf_save_INCS="$CPPFLAGS"

CF_ADD_LIBS($cf_cv_x_freetype_libs)
CPPFLAGS="$CPPFLAGS $cf_cv_x_freetype_incs"

AC_TRY_LINK([
#include 
#include 
#include ],[
	XftPattern  *pat = XftNameParse ("name"); (void)pat],
	[cf_cv_found_freetype=yes],
	[cf_cv_found_freetype=no])
AC_MSG_RESULT($cf_cv_found_freetype)

LIBS="$cf_save_LIBS"
CPPFLAGS="$cf_save_INCS"

if test "$cf_cv_found_freetype" = yes ; then
	CF_ADD_LIBS($cf_cv_x_freetype_libs)
	CF_ADD_CFLAGS($cf_cv_x_freetype_incs)
	AC_DEFINE(XRENDERFONT,1,[Define to 1 if we can/should link with FreeType libraries])

AC_CHECK_FUNCS( \
	XftDrawCharSpec \
	XftDrawSetClip \
	XftDrawSetClipRectangles \
)

else
	AC_MSG_WARN(No libraries found for FreeType)
	CPPFLAGS=`echo "$CPPFLAGS" | sed -e s/-DXRENDERFONT//`
fi

# FIXME: revisit this if needed
AC_SUBST(HAVE_TYPE_FCCHAR32)
AC_SUBST(HAVE_TYPE_XFTCHARSPEC)
])
dnl ---------------------------------------------------------------------------
dnl CF_X_MOTIF version: 3 updated: 2008/03/23 14:48:54
dnl ----------
dnl Check for Motif or Lesstif libraries (they should be indistinguishable)
AC_DEFUN([CF_X_MOTIF],
[AC_REQUIRE([CF_X_TOOLKIT])dnl
AC_CHECK_HEADERS(X11/IntrinsicI.h Xm/XmP.h)
AC_CHECK_LIB(gen,regcmp)
AC_CHECK_LIB(Xmu,XmuClientWindow)
AC_CHECK_LIB(Xp,XpStartDoc,,,[$LIBS $X_EXTRA_LIBS])
AC_CHECK_LIB(Xext,XextCreateExtension,
	[LIBS="-lXext $LIBS"])
AC_CHECK_LIB(Xpm, XpmCreatePixmapFromXpmImage,
	[LIBS="-lXpm $LIBS"],,
	[$LIBS $X_EXTRA_LIBS])
AC_CHECK_LIB(XIM,XmbTextListToTextProperty)dnl needed for Unixware's Xm
AC_CHECK_LIB(Xm, XmProcessTraversal, [LIBS="-lXm $LIBS"],
	AC_MSG_ERROR(
[Unable to successfully link Motif library (-lXm) with test program]),
	[$X_PRE_LIBS $LIBS $X_EXTRA_LIBS]) dnl
])dnl
dnl ---------------------------------------------------------------------------
dnl CF_X_TOOLKIT version: 26 updated: 2021/01/02 09:31:20
dnl ------------
dnl Check for X Toolkit libraries
AC_DEFUN([CF_X_TOOLKIT],
[
AC_REQUIRE([AC_PATH_XTRA])
AC_REQUIRE([CF_CHECK_CACHE])

# OSX is schizoid about who owns /usr/X11 (old) versus /opt/X11 (new) (and
# in some cases has installed dummy files in the former, other cases replaced
# it with a link to the new location).  This complicates the configure script.
# Check for that pitfall, and recover using pkg-config
#
# If none of these are set, the configuration is almost certainly broken.
if test -z "${X_CFLAGS}${X_PRE_LIBS}${X_LIBS}${X_EXTRA_LIBS}"
then
	CF_TRY_PKG_CONFIG(x11,,[AC_MSG_WARN(unable to find X11 library)])
	CF_TRY_PKG_CONFIG(ice,,[AC_MSG_WARN(unable to find ICE library)])
	CF_TRY_PKG_CONFIG(sm,,[AC_MSG_WARN(unable to find SM library)])
	CF_TRY_PKG_CONFIG(xt,,[AC_MSG_WARN(unable to find Xt library)])
else
	LIBS="$X_PRE_LIBS $LIBS $X_EXTRA_LIBS"
fi

cf_have_X_LIBS=no

CF_TRY_PKG_CONFIG(xt,[

	case "x$LIBS" in
	(*-lX11*)
		;;
	(*)
# we have an "xt" package, but it may omit Xt's dependency on X11
AC_CACHE_CHECK(for usable X dependency,cf_cv_xt_x11_compat,[
AC_TRY_LINK([
#include 
],[
	int rc1 = XDrawLine((Display*) 0, (Drawable) 0, (GC) 0, 0, 0, 0, 0);
	int rc2 = XClearWindow((Display*) 0, (Window) 0);
	int rc3 = XMoveWindow((Display*) 0, (Window) 0, 0, 0);
	int rc4 = XMoveResizeWindow((Display*)0, (Window)0, 0, 0, 0, 0);
],[cf_cv_xt_x11_compat=yes],[cf_cv_xt_x11_compat=no])])
		if test "$cf_cv_xt_x11_compat" = no
		then
			CF_VERBOSE(work around broken X11 dependency)
			# 2010/11/19 - good enough until a working Xt on Xcb is delivered.
			CF_TRY_PKG_CONFIG(x11,,[CF_ADD_LIB_AFTER(-lXt,-lX11)])
		fi
		;;
	esac

AC_CACHE_CHECK(for usable X Toolkit package,cf_cv_xt_ice_compat,[
AC_TRY_LINK([
#include 
],[int num = IceConnectionNumber(0); (void) num
],[cf_cv_xt_ice_compat=yes],[cf_cv_xt_ice_compat=no])])

	if test "$cf_cv_xt_ice_compat" = no
	then
		# workaround for broken ".pc" files used for X Toolkit.
		case "x$X_PRE_LIBS" in
		(*-lICE*)
			case "x$LIBS" in
			(*-lICE*)
				;;
			(*)
				CF_VERBOSE(work around broken ICE dependency)
				CF_TRY_PKG_CONFIG(ice,
					[CF_TRY_PKG_CONFIG(sm)],
					[CF_ADD_LIB_AFTER(-lXt,$X_PRE_LIBS)])
				;;
			esac
			;;
		esac
	fi

	cf_have_X_LIBS=yes
],[

	LDFLAGS="$X_LIBS $LDFLAGS"
	CF_CHECK_CFLAGS($X_CFLAGS)

	AC_CHECK_FUNC(XOpenDisplay,,[
	AC_CHECK_LIB(X11,XOpenDisplay,
		[CF_ADD_LIB(X11)])])

	AC_CHECK_FUNC(XtAppInitialize,,[
	AC_CHECK_LIB(Xt, XtAppInitialize,
		[AC_DEFINE(HAVE_LIBXT,1,[Define to 1 if we can compile with the Xt library])
		 cf_have_X_LIBS=Xt
		 LIBS="-lXt $LIBS"])])
])

if test "$cf_have_X_LIBS" = no ; then
	AC_MSG_WARN(
[Unable to successfully link X Toolkit library (-lXt) with
test program.  You will have to check and add the proper libraries by hand
to makefile.])
fi
])dnl
dnl ---------------------------------------------------------------------------
dnl CF__CURSES_HEAD version: 2 updated: 2010/10/23 15:54:49
dnl ---------------
dnl Define a reusable chunk which includes  and  when they
dnl are both available.
define([CF__CURSES_HEAD],[
#ifdef HAVE_XCURSES
#include 
char * XCursesProgramName = "test";
#else
#include <${cf_cv_ncurses_header:-curses.h}>
#if defined(NCURSES_VERSION) && defined(HAVE_NCURSESW_TERM_H)
#include 
#elif defined(NCURSES_VERSION) && defined(HAVE_NCURSES_TERM_H)
#include 
#elif defined(HAVE_TERM_H)
#include 
#endif
#endif
])
dnl ---------------------------------------------------------------------------
dnl CF__ICONV_BODY version: 2 updated: 2007/07/26 17:35:47
dnl --------------
dnl Test-code needed for iconv compile-checks
define([CF__ICONV_BODY],[
	iconv_t cd = iconv_open("","");
	iconv(cd,NULL,NULL,NULL,NULL);
	iconv_close(cd);]
)dnl
dnl ---------------------------------------------------------------------------
dnl CF__ICONV_HEAD version: 1 updated: 2007/07/26 15:57:03
dnl --------------
dnl Header-files needed for iconv compile-checks
define([CF__ICONV_HEAD],[
#include 
#include ]
)dnl
dnl ---------------------------------------------------------------------------
dnl CF__INIT_TRANSFORM version: 1 updated: 2010/01/26 06:48:38
dnl ------------------
dnl The initial/inactive value for $program_transform_name is a dummy
dnl substitution.
define([CF__INIT_TRANSFORM],[s,x,x,])dnl
vile-9.8v/ansi.c000066400000000000000000000204521415556424100136270ustar00rootroot00000000000000/*
 * The routines in this file provide support for ANSI style terminals
 * over a serial line. The serial I/O services are provided by routines in
 * "termio.c". It compiles into nothing if not an ANSI device.
 *
 *
 * $Id: ansi.c,v 1.54 2020/01/17 23:17:05 tom Exp $
 */

#include	"estruct.h"
#include	"edef.h"

#if DISP_ANSI

#define SCROLL_REG 1

#if SYS_MSDOS
#define NROW    25
#define NCOL    80
#define MAXNROW	60
#define MAXNCOL	132
#undef SCROLL_REG		/* ANSI.SYS can't do scrolling */
#define SCROLL_REG 0
#endif

#ifdef ANSI_RESIZE
#define NROW    77
#define NCOL    132
#endif

#if    !defined NROW && defined(linux)
#define NROW	25		/* Screen size.                 */
#define NCOL	80		/* Edit if you want to.         */
#endif

#ifndef NROW
#define NROW	24		/* Screen size.                 */
#define NCOL	80		/* Edit if you want to.         */
#endif
#ifndef MAXNROW
#define MAXNROW	NROW
#define MAXNCOL	NCOL
#endif

#if OPT_COLOR

static int cfcolor = -1;	/* current foreground color */
static int cbcolor = -1;	/* current background color */

	/* ANSI: black, red, green, yellow, blue, magenta, cyan, white   */
static const char ANSI_palette[] =
{"0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15"};

#endif /* OPT_COLOR */

static void
csi(void)
{
    ttputc(ESC);
    ttputc('[');
}

static void
ansi_parm(register int n)
{
    register int q, r;

#ifdef optimize_works		/* i don't think it does, although it should, to be ANSI */
    if (n == 1)
	return;
#endif

    q = n / 10;
    if (q != 0) {
	r = q / 10;
	if (r != 0) {
	    ttputc((r % 10) + '0');
	}
	ttputc((q % 10) + '0');
    }
    ttputc((n % 10) + '0');
}

#if OPT_COLOR
static void
textcolor(int color)
{
    csi();
    ansi_parm(color >= 0 ? (color + 30) : 39);
    ttputc('m');
}

static void
textbackground(int color)
{
    csi();
    ansi_parm(color >= 0 ? (color + 40) : 49);
    ttputc('m');
}

static void
ansi_fcol(int color)		/* set the current output color */
{
    if (color < 0)
	color = C_WHITE;
    if (color == cfcolor)
	return;
    textcolor(color);
    cfcolor = color;
}

static void
ansi_bcol(int color)		/* set the current background color */
{
    if (color < 0)
	color = C_BLACK;
    if (color == cbcolor)
	return;
    textbackground(color);
    cbcolor = color;
}

static void
ansi_spal(const char *thePalette)
{				/* reset the palette registers */
    set_ctrans(thePalette);
}
#endif

static void
ansi_move(int row, int col)
{
    csi();
    ansi_parm(row + 1);
    ttputc(';');
    ansi_parm(col + 1);
    ttputc('H');
}

static void
ansi_eeol(void)
{
    csi();
    ttputc('K');
}

static void
ansi_eeop(void)
{
#if OPT_COLOR
    ansi_fcol(gfcolor);
    ansi_bcol(gbcolor);
#endif
    csi();
    ttputc('2');
    ttputc('J');
}

#if OPT_COLOR && !OPT_VIDEO_ATTRS
static void
force_colors(int fc, int bc)
{
    cfcolor =
	cbcolor = -1;
    ansi_fcol(fc);
    ansi_bcol(bc);
}
#endif

#if OPT_VIDEO_ATTRS
static void
ansi_attr(UINT attr)		/* change video attributes */
{
    static UINT last;
    UINT next;
    int colored = FALSE;

    if (attr != last) {
	last = attr;

	attr = VATTRIB(attr);
	if (attr & VASPCOL) {
	    colored = TRUE;
	    attr = VCOLORATTR((VCOLORNUM(attr) & (ncolors - 1)));
	} else {
	    if (attr & VACOLOR) {
		attr &= (VCOLORATTR(ncolors - 1) | ~VACOLOR);
		colored = TRUE;
	    }
	    attr &= ~(VAML | VAMLFOC);
	}

	next = ctrans[VCOLORNUM(attr)];
	if (attr & (VASEL | VAREV)) {
	    textcolor((colored ? next : cbcolor));
	    textbackground(cfcolor);
	} else {
	    textcolor((colored ? next : cfcolor));
	    textbackground(cbcolor);
	}
    }
}
#else /* ! OPT_VIDEO_ATTRS */
#ifdef BROKEN_REVERSE_VIDEO
/* there was something wrong with this "fix".  the "else" of
		the ifdef just uses "ESC [ 7 m" to set reverse
		video, and it works under DOS for me....  but then, i
		use an "after-market" ansi driver -- nnansi593.zip, from
		oak.oakland.edu, or any simtel mirror. */
static void
ansi_rev(			/* change reverse video state */
	    UINT state)		/* TRUE = reverse, FALSE = normal */
{
#if !OPT_COLOR
    static UINT revstate = SORTOFTRUE;
    if (state == revstate)
	return;
    revstate = state;
#endif

    csi();
#if OPT_COLOR && SYS_MSDOS
    ttputc('1');		/* bold-on */
#else
    if (state)
	ttputc('7');		/* reverse-video on */
#endif
    ttputc('m');

#if OPT_COLOR && !OPT_VIDEO_ATTRS
#if SYS_MSDOS
    /*
     * Setting reverse-video with ANSI.SYS seems to reset the colors to
     * monochrome.  Using the colors directly to simulate reverse video
     * works better. Bold-face makes the foreground colors "look" right.
     */
    if (state)
	force_colors(cbcolor, cfcolor);
    else
	force_colors(cfcolor, cbcolor);
#else /* normal ANSI-reverse */
    if (state == FALSE) {
	force_colors(cfcolor, cbcolor);
    }
#endif /* MSDOS vs ANSI-reverse */
#endif /* OPT_COLOR */
}

#else

static void
ansi_rev(			/* change reverse video state */
	    UINT state)		/* TRUE = reverse, FALSE = normal */
{
    static UINT revstate = SORTOFTRUE;
    if (state == revstate)
	return;
    revstate = state;

    csi();
    if (state)
	ttputc('7');		/* reverse-video on */
    ttputc('m');
#if OPT_COLOR
    force_colors(cfcolor, cbcolor);
#endif
}

#endif
#endif /* ! OPT_VIDEO_ATTRS */

static void
ansi_beep(void)
{
    ttputc(BEL);
    ttflush();
}

#if SCROLL_REG
static void
ansi_scrollregion(int top, int bot)
{
    csi();
    ansi_parm(top + 1);
    ttputc(';');
    if (bot != term.rows - 1)
	ansi_parm(bot + 1);
    ttputc('r');
}
#endif

/* if your ansi terminal can scroll regions, like the vt100, then define
	SCROLL_REG.  If not, you can use delete/insert line code, which
	is prettier but slower if you do it a line at a time instead of
	all at once.
*/

/* move howmany lines starting at from to to */
static void
ansi_scroll(int from, int to, int n)
{
    int i;
    if (to == from)
	return;
#if SCROLL_REG
    if (to < from) {
	ansi_scrollregion(to, from + n - 1);
	ansi_move(from + n - 1, 0);
	for (i = from - to; i > 0; i--)
	    ttputc('\n');
    } else {			/* from < to */
	ansi_scrollregion(from, to + n - 1);
	ansi_move(from, 0);
	for (i = to - from; i > 0; i--) {
	    ttputc(ESC);
	    ttputc('M');
	}
    }
    ansi_scrollregion(0, term.maxrows - 1);

#else /* use insert and delete line */
#if OPT_PRETTIER_SCROLL
    if (absol(from - to) > 1) {
	ansi_scroll(from, (from < to) ? to - 1 : to + 1, n);
	if (from < to)
	    from = to - 1;
	else
	    from = to + 1;
    }
#endif
    if (to < from) {
	ansi_move(to, 0);
	csi();
	ansi_parm(from - to);
	ttputc('M');		/* delete */
	ansi_move(to + n, 0);
	csi();
	ansi_parm(from - to);
	ttputc('L');		/* insert */
    } else {
	ansi_move(from + n, 0);
	csi();
	ansi_parm(to - from);
	ttputc('M');		/* delete */
	ansi_move(from, 0);
	csi();
	ansi_parm(to - from);
	ttputc('L');		/* insert */
    }
#endif
}

static void
ansi_open(void)
{
    static int already_open = FALSE;
    if (!already_open) {
	already_open = TRUE;
	strcpy(screen_desc, "NORMAL");
	revexist = TRUE;
#if ! SYS_MSDOS
	/* Get screen size from system */
	getscreensize(&term.cols, &term.rows);
	if (term.rows <= 1)
	    term.rows = 24;

	if (term.cols <= 1)
	    term.cols = 80;
	/* we won't resize, but need the measured size */
	term.maxrows = term.rows;
	term.maxcols = term.cols;
#endif
#if OPT_COLOR
	set_palette(ANSI_palette);
#endif
	ttopen();
    }
}

static void
ansi_close(void)
{
    term.curmove(term.rows - 1, 0);	/* cf: dumbterm.c */
    ansi_eeol();
#if OPT_COLOR
    ansi_fcol(C_WHITE);
    ansi_bcol(C_BLACK);
#endif
}

/*
 * Standard terminal interface dispatch table. Most of the fields point into
 * "termio" code.
 */
TERM term =
{
    MAXNROW,			/* max */
    NROW,			/* current */
    MAXNCOL,			/* max */
    NCOL,			/* current */
    dumb_set_encoding,
    dumb_get_encoding,
    ansi_open,
    nullterm_kopen,
    nullterm_kclose,
    ansi_close,
    ttclean,
    ttunclean,
    nullterm_openup,
    ttgetc,
    ttputc,
    tttypahead,
    ttflush,
    ansi_move,
    ansi_eeol,
    ansi_eeop,
    ansi_beep,
#if OPT_VIDEO_ATTRS
    ansi_attr,
#else
    ansi_rev,
#endif
    nullterm_setdescrip,
#if OPT_COLOR
    ansi_fcol,
    ansi_bcol,
    ansi_spal,
#else
    nullterm_setfore,
    nullterm_setback,
    nullterm_setpal,
#endif
    nullterm_setccol,
    ansi_scroll,
    nullterm_pflush,
    nullterm_icursor,
    nullterm_settitle,
    nullterm_watchfd,
    nullterm_unwatchfd,
    nullterm_cursorvis,
    nullterm_mopen,
    nullterm_mclose,
    nullterm_mevent,
};

#endif /* DISP_ANSI */
vile-9.8v/api.c000066400000000000000000000457011415556424100134520ustar00rootroot00000000000000/*
 * api.c -- (roughly) nvi's api to perl and tcl
 *
 * Status of this file:  Some of the functions in this file are unused.
 * Early on, I was trying for compatibility with nvi's perl interface.
 * Now that I'm not, I've gotten lazy and have occasionally been skipping
 * this layer.
 *
 * Some of the code in this file is still used and is, in fact, very
 * important.  There's other code which may simply be removed.
 *
 * OTOH, if someone ever does a TCL interface (it probably won't
 * be me -- I really like Perl and would probably lack motivation to
 * do a proper job of it), some of the as now unused stuff might come
 * in handy.
 *				- kev 4/7/1998
 *
 * $Id: api.c,v 1.54 2020/01/17 23:11:28 tom Exp $
 */

#include "estruct.h"

#if OPT_PERL || OPT_PLUGIN

#include "edef.h"
#include "api.h"

WINDOW *curwp_visible;

static void propagate_dot(void);

/* Maybe this should go in line.c ? */
static int
linsert_chars(char *s, int len)
{
    /* I wrote the code this way both for efficiency reasons and
     * so that the MARK denoting the end of the range wouldn't
     * be moved to one of the newly inserted lines.
     */
    int nlcount = 0;
    int nlatend = 0;
    int nlsuppress = 0;
    int mdnewline = b_val(curbp, MDNEWLINE);

    if (len <= 0)
	return 0;

    if (DOT.l == buf_head(curbp)) {
	if (!mdnewline) {
	    DOT.l = lback(DOT.l);
	    DOT.o = llength(DOT.l);
	}
	if (s[len - 1] == '\n') {
	    if (len > 1)
		nlsuppress = TRUE;
	    if (!mdnewline) {
		set_local_b_val(curbp, MDNEWLINE, TRUE);
	    }
	} else {
	    if (mdnewline) {
		set_local_b_val(curbp, MDNEWLINE, FALSE);
	    }
	}
    }

    if (s[len - 1] == '\n') {
	if (!mdnewline
	    && lforw(DOT.l) == buf_head(curbp)
	    && DOT.o == llength(DOT.l)) {
	    nlsuppress = TRUE;
	    set_local_b_val(curbp, MDNEWLINE, TRUE);
	}
	if (!nlsuppress) {

	    /* We implicitly get a newline by inserting anything at
	     * the head of a buffer (which includes the empty buffer
	     * case).  So if we actually insert a newline, we'll end
	     * up getting two of them.  (Which is something we don't
	     * want unless MDNEWLINE is TRUE.)
	     */
	    lnewline();
	    nlcount++;
	    DOT.l = lback(DOT.l);	/* back up DOT to the newly */
	    DOT.o = llength(DOT.l);	/* inserted line */
	}
	nlatend = 1;
	len--;
    }

    while (len > 0) {
	if (*s == '\n') {
	    lnewline();
	    nlcount++;
	    s++;
	    len--;
	} else {
	    int i;
	    /* Find next newline so we can do block insert; We
	     * start at 1, because we know the first character
	     * can't be a newline.
	     */
	    for (i = 1; i < len && s[i] != '\n'; i++) ;
	    lins_bytes(i, *s);
	    if (i > 1) {
		memcpy(lvalue(DOT.l) + DOT.o - i + 1, s + 1, (size_t) (i - 1));
	    }
	    len -= i;
	    s += i;
	}
    }

    if (nlatend) {
	/* Advance DOT to where it's supposed to be */
	dot_next_bol();
    }

    return nlcount;
}

/* Another candidate for line.c */
static int
lreplace(char *s, int len)
{
    LINE *lp = DOT.l;
    int i;
    char *t;
    WINDOW *wp;

    CopyForUndo(lp);

    DOT.o = b_left_margin(curbp);

    if (len > (int) lp->l_size) {
	size_t nlen;
	char *ntext;

#define roundlenup(n) ((n+NBLOCK-1) & ~(NBLOCK-1))

	nlen = (size_t) roundlenup(len);
	ntext = castalloc(char, nlen);
	if (ntext == 0)
	    return FALSE;
	if (lvalue(lp))
	    ltextfree(lp, curbp);
	lvalue(lp) = ntext;
	lp->l_size = nlen;
#if OPT_LINE_ATTRS
	FreeAndNull(lp->l_attrs);
#endif
    }

    llength(lp) = len;

    /* FIXME: Handle embedded newlines */
    for (i = len - 1, t = lvalue(lp); i >= 0; i--)
	t[i] = s[i];

    /* We'd normally need a call to chg_buff here, but I don't want
       to pay the price.

       BUT...

       We do call chg_buff before returning to vile.  See
       api_command_cleanup below.
     */

    for_each_window(wp) {
	if (wp->w_dot.l == lp && wp->w_dot.o > len)
	    wp->w_dot.o = len;
	if (wp->w_lastdot.l == lp && wp->w_lastdot.o > len)
	    wp->w_lastdot.o = len;
    }
    do_mark_iterate(mp, {
	if (mp->l == lp && mp->o > len)
	    mp->o = len;
    });
#if OPT_LINE_ATTRS
    FreeAndNull(lp->l_attrs);
#endif

    return TRUE;
}

void
api_setup_fake_win(VileBuf * vbp, int do_delete)
{
    if (vbp != 0) {
	if (curwp_visible == 0)
	    curwp_visible = curwp;

	if (vbp->fwp) {
	    curwp = vbp->fwp;
	    curbp = curwp->w_bufp;
	} else {
	    (void) push_fake_win(vbp->bp);
	    vbp->fwp = curwp;
	    vbp->changed = 0;
	}

	if (vbp->ndel != 0 && do_delete) {
	    int status;
	    /* Do lazy delete; FALSE means don't put text in kill buffer */
	    status = ldel_bytes(vbp->ndel, FALSE);
	    vbp->ndel = 0;
	    if (status == FALSE
		|| (lforw(DOT.l) == buf_head(curbp) && DOT.o >= llength(DOT.l))) {
		set_local_b_val(curbp, MDNEWLINE, FALSE);
	    }
	}
    }
}

/* I considered three possible solutions for preventing stale
   regions from being used.  Here they are:

    1) Validate the region in question.  I.e, make sure that
       the region start and end lines are still in the buffer.
       Set the region to reasonable defaults if not.

       The problem with this approach is that we need something
       else to hold the end marker of the region while we're
       working on it.  One possible solution is to use the
       per-buffer w_lastdot field.  But I'm not entirely sure
       this is safe.

    2) Make the region and attributed region and put it on
       the attribute list.  The marks representing the
       ends of the region will certainly be updated correctly
       if this is done.  The downside is that we'd have to
       beef up the code which deals with attributes to allow
       external pointers to the attributes.  It wouldn't
       do for one of the attribute lists to be freed up with
       one of our VileBuf structures still pointer to one of the
       structures.

    3) Make line.c and undo.c aware of the VileBuf regions.
       This solution has no serious downside aside from
       further bulking up the files in question.

    I chose option 3 since I was able to bury the work
    inside do_mark_iterate (see estruct.h).  The following
    function (api_mark_iterator) is the helper function
    found in do_mark_iterate.
*/

MARK *
api_mark_iterator(BUFFER *bp, int *iterp)
{
    MARK *mp = NULL;
    VileBuf *vbp = bp2vbp(bp);

    if (vbp != NULL) {
	switch (*iterp) {
	case 0:
	    mp = &vbp->region.r_orig;
	    break;
	case 1:
	    mp = &vbp->region.r_end;
	    break;
	default:
	    break;
	}
	(*iterp)++;
    }

    return mp;
}

/*
 * This is a variant of gotoline in basic.c.  It differs in that
 * it attempts to use the line number information to more efficiently
 * find the line in question.  It will also position DOT at the beginning
 * of the line.
 */
int
api_gotoline(VileBuf * vbp, int lno)
{
#if !SMALLER
    int count;
    LINE *lp;
    BUFFER *bp = vbp->bp;

    if (!b_is_counted(bp))
	bsizes(bp);

    count = lno - DOT.l->l_number;
    lp = DOT.l;

    while (count < 0 && lp != buf_head(bp)) {
	lp = lback(lp);
	count++;
    }
    while (count > 0) {
	lp = lforw(lp);
	count--;
	if (lp == buf_head(bp))
	    break;
    }

    DOT.o = b_left_margin(curbp);

    if (lp != buf_head(bp) && lno == lp->l_number) {
	DOT.l = lp;
	return TRUE;
    } else {
	DOT.l = buf_head(bp);
	return FALSE;
    }

#else
    return vl_gotoline(lno);
#endif
}

int
api_aline(VileBuf * vbp, int lno, char *line, int len)
{
    api_setup_fake_win(vbp, TRUE);

    if (lno >= 0 && lno < vl_line_count(vbp->bp)) {
	api_gotoline(vbp, lno + 1);
	linsert_chars(line, len);
	lnewline();
    } else {			/* append to the end */
	gotoeob(FALSE, 0);
	gotoeol(FALSE, 0);
	lnewline();
	linsert_chars(line, len);
    }

    return TRUE;
}

int
api_dotinsert(VileBuf * vbp, char *text, int len)
{

    /* Set up the fake window; but we'll do any pending deletes
       ourselves. */
    api_setup_fake_win(vbp, FALSE);

    /* FIXME: Check to see if the buffer needs to be modified at all.
       We'll save our undo space better this way.  We'll also be able
       to better preserve the user's marks. */

    linsert_chars(text, len);
    if (vbp->ndel) {
	int status;
	status = ldel_bytes(vbp->ndel, FALSE);
	vbp->ndel = 0;
	if (status == FALSE
	    || (lforw(DOT.l) == buf_head(curbp) && DOT.o >= llength(DOT.l))) {
	    set_local_b_val(curbp, MDNEWLINE, FALSE);
	}
    }
    vbp->changed = 1;
    return TRUE;
}

int
api_dline(VileBuf * vbp, int lno)
{
    int status = TRUE;

    api_setup_fake_win(vbp, TRUE);

    if (lno > 0 && lno <= vl_line_count(vbp->bp)) {
	api_gotoline(vbp, lno);
	gotobol(TRUE, TRUE);
	status = ldel_bytes((B_COUNT) (llength(DOT.l) + 1), FALSE);
    } else
	status = FALSE;

    return status;
}

int
api_gline(VileBuf * vbp, int lno, char **linep, int *lenp)
{
    static char empty[1];
    int status = TRUE;

    api_setup_fake_win(vbp, TRUE);

    if (lno > 0 && lno <= vl_line_count(vbp->bp)) {
	api_gotoline(vbp, lno);
	*linep = lvalue(DOT.l);
	*lenp = llength(DOT.l);
	if (*lenp == 0) {
	    *linep = empty;	/* Make sure we pass back a zero length,
				   null terminated value when the length
				   is zero.  Otherwise perl gets confused.
				   (It thinks it should calculate the length
				   when given a zero length.)
				 */
	}
    } else
	status = FALSE;

    return status;
}

#if 0				/* Not used. */
int
api_dotgline(VileBuf * vbp, char **linep, B_COUNT * lenp, int *neednewline)
{

    api_setup_fake_win(vbp, TRUE);
    if (!vbp->dot_inited) {
	DOT = vbp->region.r_orig;	/* set DOT to beginning of region */
	vbp->dot_inited = 1;
    }

    /* FIXME: Handle rectangular regions. */

    if (is_header_line(DOT, curbp)
	|| !lisreal(DOT.l)
	|| DOT.o < 0) {
	return FALSE;
    }

    if ((DOT.l == vbp->region.r_end.l
	 && (vbp->regionshape == rgn_FULLLINE
	     || (vbp->regionshape == rgn_EXACT
		 && DOT.o >= vbp->region.r_end.o)))) {
	return FALSE;
    }

    *linep = lvalue(DOT.l) + DOT.o;

    if (llength(DOT.l) >= DOT.o) {
	*lenp = llength(DOT.l) - DOT.o;

	if (vbp->regionshape == rgn_EXACT && DOT.l == vbp->region.r_end.l) {
	    B_COUNT next = *lenp + vbp->region.r_end.o;
	    if (next >= (B_COUNT) llength(DOT.l)) {
		*lenp = next - llength(DOT.l);
	    } else {
		*lenp = 0;
	    }
	}
    } else {
	*lenp = 0;
    }

    if (*lenp == 0) {
	*linep = "";		/* Make sure we pass back a zero length,
				   null terminated value when the length
				   is zero.  Otherwise perl gets confused.
				   (It thinks it should calculate the length
				   when given a zero length.)
				 */
    }

    if (vbp->inplace_edit) {
	if (vbp->regionshape == rgn_EXACT && DOT.l == vbp->region.r_end.l) {
	    vbp->ndel = *lenp;
	    *neednewline = 0;
	} else {
	    vbp->ndel = *lenp + 1;
	    *neednewline = 1;
	}
    } else {
	if (vbp->regionshape == rgn_EXACT && DOT.l == vbp->region.r_end.l) {
	    DOT.o += *lenp;
	    *neednewline = 0;
	} else {
	    dot_next_bol();
	    *neednewline = 1;
	}
    }
    return TRUE;
}
#endif /* Not used */

int
api_sline(VileBuf * vbp, int lno, char *line, int len)
{
    int status = TRUE;

    api_setup_fake_win(vbp, TRUE);

    if (lno > 0 && lno <= vl_line_count(vbp->bp)) {
	api_gotoline(vbp, lno);
	if (lvalue(DOT.l) != line
	    && (llength(DOT.l) != len
		|| memcmp(line, lvalue(DOT.l), (size_t) len) != 0)) {
	    lreplace(line, len);
	    vbp->changed = 1;
	}
    } else
	status = FALSE;

    return status;
}

int
api_iline(VileBuf * vbp, int lno, char *line, int len)
{
    return api_aline(vbp, lno - 1, line, len);
}

int
api_lline(VileBuf * vbp, int *lnop)
{
    *lnop = vl_line_count(vbp->bp);
    return TRUE;
}

VileBuf *
api_fscreen(char *name)
{
    BUFFER *bp;

    bp = find_b_file(name);

    if (bp)
	return api_bp2vbp(bp);
    else
	return 0;
}

int
api_delregion(VileBuf * vbp)
{

    api_setup_fake_win(vbp, TRUE);

    haveregion = NULL;
    DOT = vbp->region.r_orig;
    MK = vbp->region.r_end;
    regionshape = vbp->regionshape;

    if (vbp->regionshape == rgn_FULLLINE) {
	MK.l = lback(MK.l);
    }

    return killregion();
}

int
api_motion(VileBuf * vbp, char *mstr)
{
    const CMDFUNC *cfp;
    char *mp;
    int c, f, n, s;
    int status;
    int saved_clexec, saved_vl_echo, saved_vl_msgs, saved_isnamedcmd;

    if (mstr == NULL)
	return FALSE;

    status = TRUE;

    saved_clexec = clexec;
    saved_vl_msgs = vl_msgs;
    saved_vl_echo = vl_echo;
    saved_isnamedcmd = isnamedcmd;

    clexec = FALSE;		/* Not executing a command line */
    vl_msgs = FALSE;		/* Don't display commands / arg counts */
    vl_echo = FALSE;		/* Don't display input */
    isnamedcmd = FALSE;		/* Not a named command */

    api_setup_fake_win(vbp, TRUE);

    mp = mstr + strlen(mstr);

    mapungetc((int) ((unsigned char) esc_c | NOREMAP));
    /* Should we allow remapping?  Seems to me like it introduces too
       many variables. */
    while (mp-- > mstr) {
	mapungetc((int) ((unsigned char) *mp | NOREMAP));
    }

    while (mapped_ungotc_avail()) {

	/* Get the character */
	c = kbd_seq();

	if (ABORTED(c)) {
	    if (mapped_ungotc_avail()) {
		/* Not our esc_c */
		while (mapped_ungotc_avail())
		    (void) kbd_seq();
		status = FALSE;
		break;
	    } else
		break;		/* okay, it's ours */
	}

	f = FALSE;
	n = 1;

	do_repeats(&c, &f, &n);

	/* and execute the command */
	cfp = DefaultKeyBinding(c);
	if ((cfp != NULL) && ((cfp->c_flags & (GOAL | MOTION)) != 0))
	    s = execute(cfp, f, n);
	else {
	    while (mapped_ungotc_avail())
		(void) kbd_seq();
	    status = FALSE;
	    break;
	}
    }

    clexec = saved_clexec;
    vl_msgs = saved_vl_msgs;
    vl_echo = saved_vl_echo;
    isnamedcmd = saved_isnamedcmd;

    return status;
}

int
api_edit(char *fname, VileBuf ** retvbpp)
{
    BUFFER *bp;
    if (fname == NULL) {
	char bufname[NBUFN];
	static int unnamed_cnt = 0;
	sprintf(bufname, "[unnamed-%d]", ++unnamed_cnt);
	bp = bfind(bufname, 0);
	bp->b_active = TRUE;
    } else {
	bp = getfile2bp(fname, FALSE, FALSE);
	if (bp == 0) {
	    *retvbpp = 0;
	    return 1;
	}
    }

    *retvbpp = api_bp2vbp(bp);
    api_setup_fake_win(*retvbpp, TRUE);
    return !swbuffer_lfl(bp, FALSE, FALSE);
}

int
api_swscreen(VileBuf * oldsp, VileBuf * newsp)
{
    /*
     * Calling api_command_cleanup nukes various state, like DOT
     * Now if DOT got propagated, all is (likely) well.  But if it didn't,
     * then DOT will likely be in the wrong place if the executing perl
     * script expects to access a buffer on either side of a switchscreen
     * call.
     *
     * I see two different solutions for this.  1) Maintain a copy of
     * dot in the VileBuf structure. 2) Don't destroy the fake windows by
     * popping them off.  Which means that we either teach the rest
     * of vile about fake windows (scary) or we temporarily unlink the
     * fake windows from the buffer list.
     *
     * I'm in favor of temporarily unlinking the fake windows from
     * the buffer list.  The only problem with this is that the unlinked
     * window's version of DOT is not iterated over in do_mark_iterate.
     * (Probably won't be a problem that often, but we need to account
     * for it.)
     *
     * So... I guess we could maintain a separate structure which
     * has the unlinked window pointers.  And then api_mark_iterate
     * could walk these.  (Yuck.)
     *
     * Anyhow, there's a lot of issues here requiring careful
     * consideration.  Which is why I haven't already done it.
     *          - kev 4/3/1998
     *
     * Okay, I put in the stuff for detaching and reattaching fake
     * windows, but the above noted caveats still apply.
     *          - kev 4/18/1998
     *
     * I decided that the fake window stuff was too much of a hack
     * So I blew it away.  The rest of vile has limited knowledge
     * of fake windows now where it needs it.  This knowledge is
     * buried in the macro "for_each_visible_window".
     *          - kev 4/20/1998
     */
    TRACE((T_CALLED "api_swscreen(oldsp=%p, newsp=%p)\n",
	   (void *) oldsp,
	   (void *) newsp));

    curwp = curwp_visible ? curwp_visible : curwp;
    curbp = curwp->w_bufp;

    if (oldsp)
	swbuffer(vbp2bp(oldsp));
    swbuffer(vbp2bp(newsp));

    curwp_visible = curwp;

    returnCode(TRUE);
}

/* Causes the screen(s) to be updated */
void
api_update(void)
{
    TRACE((T_CALLED "api_update\n"));

    propagate_dot();

    curwp = curwp_visible ? curwp_visible : curwp;
    curbp = curwp->w_bufp;

    update(TRUE);

    curwp_visible = curwp;

    returnVoid();
}

/*
 * The following are not in the nvi API. But I needed them in order to
 * do an efficient implementation for vile.
 */

/* Propagate DOT for the fake windows that need it;
   Also do any outstanding (deferred) deletes. */
static void
propagate_dot(void)
{
    WINDOW *wp;

    for_each_window(wp) {
	if (!is_fake_window(wp)) {
	    /* We happen to know that the fake windows will always
	       be first in the buffer list.  So we exit the loop
	       when we hit one that isn't fake. */
	    break;
	}

	/* Do outstanding delete (if any) */
	api_setup_fake_win(bp2vbp(wp->w_bufp), TRUE);

	if (bp2vbp(wp->w_bufp)->dot_changed) {
	    if (curwp_visible && curwp_visible->w_bufp == wp->w_bufp) {
		curwp_visible->w_dot = wp->w_dot;
		curwp_visible->w_flag |= WFHARD;
	    } else {
		int found = 0;
		WINDOW *pwp;
		for_each_window(pwp) {
		    if (wp->w_bufp == pwp->w_bufp
			&& !is_fake_window(pwp)) {
			found = 1;
			pwp->w_dot = wp->w_dot;
			pwp->w_flag |= WFHARD;
			break;	/* out of inner for_each_window */
		    }
		}
		if (!found) {
		    /* No window to propagate DOT in, so just use the
		       buffer's traits */
		    wp->w_bufp->b_dot = wp->w_dot;
		}
	    }
	}
    }
}

void
api_command_cleanup(void)
{
    BUFFER *bp;

    if (curwp_visible == 0)
	curwp_visible = curwp;

    /* Propgate dot to the visible windows and do any deferred deletes */
    propagate_dot();

    /* Pop the fake windows */

    while ((bp = pop_fake_win(curwp_visible, (BUFFER *) 0)) != NULL) {
	if (bp2vbp(bp) != NULL) {
	    bp2vbp(bp)->fwp = 0;
	    bp2vbp(bp)->dot_inited = 0;		/* for next time */
	    bp2vbp(bp)->dot_changed = 0;	/* ditto */
	    if (bp2vbp(bp)->changed) {
		int buf_flag_says_changed = b_is_changed(bp);
		chg_buff(bp, WFHARD);
		bp2vbp(bp)->changed = 0;
		/* Make sure results of an unmark get propagated back */
		if (buf_flag_says_changed)
		    b_set_changed(bp);
		else
		    b_clr_changed(bp);
	    }
	}
    }

    curwp_visible = 0;

    /* Not needed? */
    if (curbp != curwp->w_bufp)
	make_current(curwp->w_bufp);

    MK = DOT;			/* make sure MK is in same buffer as DOT */

#if OPT_PERL
    perl_free_deferred();
#endif
}

void
api_free_private(void *vsp)
{
    VileBuf *vbp = (VileBuf *) vsp;

    if (vbp) {
	vbp->bp->b_api_private = 0;
#if OPT_PERL && !NO_LEAKS
	perl_free_handle(vbp->perl_handle);
#endif
	free(vbp);
    }
}

/* Given a buffer pointer, returns a pointer to a VileBuf structure,
 * creating it if necessary.
 */
VileBuf *
api_bp2vbp(BUFFER *bp)
{
    VileBuf *vbp;

    vbp = bp2vbp(bp);
    if (vbp == 0) {
	vbp = typecalloc(VileBuf);
	if (vbp != 0) {
	    bp->b_api_private = vbp;
	    vbp->bp = bp;
	    vbp->regionshape = rgn_FULLLINE;
	    vbp->region.r_orig.l =
		vbp->region.r_end.l = buf_head(bp);
	    vbp->region.r_orig.o =
		vbp->region.r_end.o = 0;
	    vbp->dot_inited = 0;
	    vbp->dot_changed = 0;
	    vbp->ndel = 0;
	}
    }
    return vbp;
}

#endif
vile-9.8v/api.h000066400000000000000000000053621415556424100134560ustar00rootroot00000000000000/*
 * $Id: api.h,v 1.16 2020/01/17 23:11:59 tom Exp $
 */

/*
 * The VileBuf structure is used by an extension language (such
 * as Perl) interface to provide an interface to BUFFER.  In this
 * structure, we have a pointer to a BUFFER as well as other fields.
 *
 * In particular, the fwp (fake window pointer) is needed because
 * most of vile's editing operations will not work right unless there
 * is also an associated window.  We don't necessarily want to change
 * the user visible windows, so we create a fake window (and then
 * later destroy it) for the express purpose of fooling the rest of
 * vile into thinking that it's working on a real window.  Care
 * must be taken not to enter any display code, however, since these
 * fake windows use negative numbers to denote the top line of the
 * screen.
 */

typedef struct {
	BUFFER    * bp;
	WINDOW    * fwp;		/* fake window pointer */
	REGION      region;		/* Region to traverse */
	REGIONSHAPE regionshape;
	int         inplace_edit;	/* Delete after get? */
	int         dot_inited;		/* Has dot been initialized
	                                   for api_dotgline? */
	int         changed;		/* Were any changes done? */
	int         dot_changed;	/* DOT explicitly changed --
					   implies that DOT should
					   be propagated */
	B_COUNT	    ndel;		/* number of characters to delete upon
					   setup; related to the inplace_edit
					   stuff */
#if OPT_PERL
	void      * perl_handle;	/* perl visible handle to this
					   data structure */
#endif
} VileBuf;

/*
 * A VileWin is a good deal simpler.  It is simply a Window *.  But
 * to perl (and other extension languages as well), the window is
 * represented by its id.  When the actual window is needed, we use
 * id2win (see window.c) to convert the id to the window.
 */
typedef WINDOW *VileWin;

extern	int	api_aline(VileBuf *, int, char *, int);
extern	int	api_edit(char *fname, VileBuf **retspp);
extern	int	api_dline(VileBuf *, int);
extern	int	api_gline(VileBuf *, int, char **, int *);
extern	int	api_sline(VileBuf *, int, char *, int);
extern	int	api_iline(VileBuf *, int, char *, int);
extern	int	api_lline(VileBuf *, int *);
extern	int	api_swscreen(VileBuf *, VileBuf *);
extern	VileBuf *api_fscreen(char *);
extern	VileBuf *api_bp2vbp(BUFFER *bp);
extern	void	api_command_cleanup(void);
extern	int	api_dotinsert(VileBuf *sp, char *text, int len);
extern	int	api_dotgline(VileBuf *, char **, B_COUNT *, int *);
extern	int	api_gotoline(VileBuf *sp, int lno);
extern	void	api_setup_fake_win(VileBuf *sp, int do_delete);
extern	int	api_delregion(VileBuf *vbp);
extern	int	api_motion(VileBuf *vbp, char *mstr);
extern	void	api_update(void);

extern	WINDOW *curwp_visible;

#define vbp2bp(sp) (((VileBuf *)(sp))->bp)
#define bp2vbp(bp) ((VileBuf *) (bp)->b_api_private)
vile-9.8v/basic.c000066400000000000000000001123661415556424100137640ustar00rootroot00000000000000/*
 * The routines in this file move the cursor around on the screen. They
 * compute a new value for the cursor, then adjust ".". The display code
 * always updates the cursor location, so only moves between lines, or
 * functions that adjust the top line in the window and invalidate the
 * framing, are hard.
 *
 * $Id: basic.c,v 1.178 2020/08/30 23:47:37 tom Exp $
 *
 */

#include	"estruct.h"
#include	"edef.h"

#define	RegexpLen(exp) ((exp->mlen) ? (int)(exp->mlen) : 1)

/*
 * Replace "DOT.o++".
 */
#if OPT_MULTIBYTE
#define lp_bytes_at0(lp, off) bytes_at0(lvalue(lp), llength(lp), off)
#define tb_bytes_at0(tb, off) bytes_at0(tb_values(tb), (int) tb_length(tb), off)

static int
bytes_at0(const char *value, int length, int off)
{
    return ((length > off && off >= 0)
	    ? vl_conv_to_utf32((UINT *) 0,
			       value + off,
			       (B_COUNT) (length - off))
	    : 0);
}

int
bytes_at(LINE *lp, int off)
{
    int rc = lp_bytes_at0(lp, off);
    return rc ? rc : 1;
}

/*
 * Replace "DOT.o--", find the number of bytes of a multibyte character before
 * the given offset.
 */
int
bytes_before(LINE *lp, int off)
{
    int rc = 0;
    int first = off;
    int legal = FALSE;

    while (off-- > 0) {
	++rc;
	if (lp_bytes_at0(lp, off) == rc) {
	    legal = TRUE;
	    break;
	}
    }
    if (!legal && first)
	rc = 1;
    return rc;
}

int
tb_bytes_before(TBUFF *tb, int off)
{
    int rc = 0;
    int first = off;
    int legal = FALSE;

    while (off-- > 0) {
	++rc;
	if (tb_bytes_at0(tb, off) == rc) {
	    legal = TRUE;
	    break;
	}
    }
    if (!legal && first)
	rc = 1;
    return rc;
}

/*
 * Count the number of characters from the given offset to the end of the line.
 */
int
chars_to_eol(LINE *lp, int off)
{
    int rc = bytes_to_eol(lp, off);
    if (b_is_utfXX(curbp)) {
	rc = 0;
	while (off < llength(lp)) {
	    off += bytes_at(lp, off);
	    ++rc;
	}
    }
    return rc;
}

/*
 * Count the number of characters from the given offset to the beginning of the
 * line.
 */
int
chars_to_bol(LINE *lp, int off)
{
    int rc = bytes_to_bol(lp, off);
    if (b_is_utfXX(curbp)) {
	int xx = 0;
	rc = 0;
	while (xx < off) {
	    xx += bytes_at(lp, xx);
	    ++rc;
	}
    }
    return rc;
}

/*
 * Count the number of bytes in the given number of characters in the line
 * starting from the given offset.
 */
int
count_bytes(LINE *lp, int off, int chars)
{
    int rc = chars;
    if (b_is_utfXX(curbp)) {
	int xx = 0;
	while (off < llength(lp) && chars-- > 0) {
	    int value = bytes_at(lp, off);
	    off += value;
	    xx += value;
	}
	rc = xx;
    }
    return rc;
}

/*
 * Count the number of characters in the given number of bytes in the line
 * starting from the given offset.
 */
int
count_chars(LINE *lp, int off, int bytes)
{
    int rc = bytes;
    if (b_is_utfXX(curbp)) {
	int xx = 0;
	while (off < llength(lp) && bytes > 0) {
	    int value = bytes_at(lp, off);
	    off += value;
	    bytes -= value;
	    ++xx;
	}
	rc = xx;
    }
    return rc;
}

int
mb_cellwidth(WINDOW *wp, const char *text, int limit)
{
    UINT value;
    int rc = COLS_UTF8;		/* "\uXXXX" */

    vl_conv_to_utf32(&value, text, (B_COUNT) limit);
    if (isPrint(value) && FoldTo8bits((int) value)) {
	rc = 1;
	if (w_val(wp, WMDUNICODE_AS_HEX)) {
	    rc = COLS_UTF8;
	} else if (!isPrint(value)) {
	    rc = COLS_8BIT;
	}
    } else if (term_is_utfXX()) {
	rc = vl_wcwidth((int) value);
	if (rc <= 0)
	    rc = COLS_UTF8;
    }
    return rc;
}
#endif /* OPT_MULTIBYTE */

/* utility routine for 'forwpage()' and 'backpage()' */
static int
full_pages(int f, int n)
{
    if (f == FALSE) {
	n = curwp->w_ntrows - 2;	/* Default scroll.      */
	if (n <= 0)		/* Don't blow up if the */
	    n = 1;		/* window is tiny.  */
    }
#if OPT_CVMVAS
    else if (n > 0)		/* Convert from pages */
	n *= curwp->w_ntrows;	/* to lines.  */
#endif
    return n;
}

/* utility routine for 'forwhpage()' and 'backhpage()' */
static int
half_pages(int f, int n)
{
    if (f == FALSE) {
	n = curwp->w_ntrows / 2;	/* Default scroll.  */
	if (n <= 0)		/* Forget the overlap */
	    n = 1;		/* if tiny window.  */
    }
#if OPT_CVMVAS
    else if (n > 0)		/* Convert from pages */
	n *= curwp->w_ntrows / 2;	/* to lines.  */
#endif
    return n;
}

static void
skipblanksf(void)
{
    while (lforw(DOT.l) != buf_head(curbp) && is_empty_line(DOT)) {
	dot_next_bol();
    }
}

static void
skipblanksb(void)
{
    while (lback(DOT.l) != buf_head(curbp) && is_empty_line(DOT)) {
	dot_prev_bol();
    }
}

/*
 * Implements the vi "0" command.
 *
 * Move the cursor to the beginning of the current line.
 */
/* ARGSUSED */
int
gotobol(int f GCC_UNUSED, int n GCC_UNUSED)
{
    DOT.o = w_left_margin(curwp);
    return mvleftwind(TRUE, w_val(curwp, WVAL_SIDEWAYS));
}

/*
 * Move the cursor backwards by "n" characters. If "n" is less than zero call
 * "forwchar" to actually do the move. Otherwise compute the new cursor
 * location. Error if you try and move out of the buffer. Set the flag if the
 * line pointer for dot changes.
 */
int
backchar(int f, int n)
{
    LINE *lp;

    n = need_a_count(f, n, 1);

    if (n < 0)
	return (forwchar(f, -n));
    while (n--) {
	if (DOT.o == w_left_margin(curwp)) {
	    if ((lp = lback(DOT.l)) == buf_head(curbp))
		return (FALSE);
	    DOT.l = lp;
	    DOT.o = llength(lp);
	    curwp->w_flag |= WFMOVE;
	} else {
	    DOT.o -= BytesBefore(DOT.l, DOT.o);
	}
    }
    return (TRUE);
}

/*
 * Implements the vi "h" command.
 *
 * Move the cursor backwards by "n" characters. Stop at beginning of line.
 */
int
backchar_to_bol(int f, int n)
{
    int rc = TRUE;

    n = need_a_count(f, n, 1);

    if (n < 0) {
	rc = forwchar_to_eol(f, -n);
    } else {
	while (n--) {
	    if (DOT.o == w_left_margin(curwp)) {
		rc = doingopcmd;
		break;
	    } else {
		DOT.o -= BytesBefore(DOT.l, DOT.o);
	    }
	}
    }
    return rc;
}

/*
 * Implements the vi "$" command.
 *
 * Move the cursor to the end of the current line.  Trivial.
 */
int
gotoeol(int f, int n)
{
    if (f == TRUE) {
	if (n > 0)
	    --n;
	else if (n < 0)
	    ++n;
	if (forwline(f, n) != TRUE)
	    return FALSE;
    }
    DOT.o = llength(DOT.l);
    curgoal = VL_HUGE;
    return (TRUE);
}

/*
 * Move the cursor forwards by "n" characters. If "n" is less than zero call
 * "backchar" to actually do the move. Otherwise compute the new cursor
 * location, and move ".". Error if you try and move off the end of the
 * buffer. Set the flag if the line pointer for dot changes.
 */
int
forwchar(int f, int n)
{
    int rc = TRUE;

    n = need_a_count(f, n, 1);

    if (n < 0) {
	rc = backchar(f, -n);
    } else {
	while (n--) {
	    /* if an explicit arg was given, allow us to land
	       on the newline, else skip it */
	    if (is_at_end_of_line(DOT) ||
		(f == FALSE && !insertmode &&
		 llength(DOT.l) && DOT.o == llength(DOT.l) - 1)) {
		if (is_header_line(DOT, curbp) ||
		    is_last_line(DOT, curbp)) {
		    rc = FALSE;
		    break;
		}
		DOT.l = lforw(DOT.l);
		DOT.o = w_left_margin(curwp);
		curwp->w_flag |= WFMOVE;
	    } else {
		DOT.o += BytesAt(DOT.l, DOT.o);
	    }
	}
    }
    return (rc);
}

/*
 * Implements the vi "l" command.
 *
 * Move the cursor forwards by "n" characters. Don't go past end-of-line
 *
 * If the flag 'doingopcmd' is set, implements a vi "l"-like motion for
 * internal use.  The end-of-line test is off-by-one from the true "l" command
 * to allow for substitutions at the end of a line.
 */
int
forwchar_to_eol(int f, int n)
{
    int rc = TRUE;
    int nwas = n;
    int lim;

    n = need_a_count(f, n, 1);

    if (n < 0) {
	rc = backchar_to_bol(f, -n);
    } else if (n != 0) {

	/* normally, we're confined to the text on the line itself.  if
	   we're doing an opcmd, then we're allowed to move to the newline
	   as well, to take care of the internal cases:  's', 'x', and '~'. */
	if (doingopcmd || insertmode)
	    lim = llength(DOT.l);
	else
	    lim = llength(DOT.l) - 1;
	do {
	    if (DOT.o >= lim) {
		rc = (n != nwas);	/* return ok if we moved at all */
		break;
	    } else {
		DOT.o += BytesAt(DOT.l, DOT.o);
	    }
	} while (--n != 0);
    }
    return rc;
}

/*
 * Move to a particular line (the argument).  Count from bottom of file if
 * argument is negative.
 */
int
vl_gotoline(int n)
{
    int status = TRUE;		/* status return */

    MARK odot;

    if (n == 0)			/* if a bogus argument...then leave */
	return (FALSE);

    odot = DOT;

    DOT.o = w_left_margin(curwp);
    if (n < 0) {
	DOT.l = lback(buf_head(curbp));
	status = backline(TRUE, -n - 1);
    } else {
	DOT.l = lforw(buf_head(curbp));
	status = forwline(TRUE, n - 1);
    }
    if (status != TRUE) {
	DOT = odot;
	return status;
    }
    (void) firstnonwhite(FALSE, 1);
    curwp->w_flag |= WFMOVE;
    return TRUE;
}

/*
 * Implements the vi "G" command.
 *
 * Move to a particular line (the argument).  Count from bottom of file if
 * argument is negative.
 */
int
gotoline(int f, int n)
{
    int status;			/* status return */

    if (f == FALSE) {
	status = gotoeob(f, n);
    } else {
	status = vl_gotoline(n);
	if (status != TRUE)
	    mlwarn("[Not that many lines in buffer: %ld]", absol((long) n));
    }
    return status;
}

/*
 * Goto the beginning of the buffer. Massive adjustment of dot. This is
 * considered to be hard motion; it really isn't if the original value of dot
 * is the same as the new value of dot.
 */
/* ARGSUSED */
int
gotobob(int f GCC_UNUSED, int n GCC_UNUSED)
{
    DOT.l = lforw(buf_head(curbp));
    DOT.o = w_left_margin(curwp);
    curwp->w_flag |= WFMOVE;
    return (TRUE);
}

/*
 * Move to the end of the buffer. Dot is always put at the end of the file.
 */
/* ARGSUSED */
int
gotoeob(int f GCC_UNUSED, int n GCC_UNUSED)
{
    DOT.l = lback(buf_head(curbp));
    curwp->w_flag |= WFMOVE;
    return firstnonwhite(FALSE, 1);
}

/*
 * Implements the vi "H" command.
 *
 * Move to first (or nth) line in window
 */
int
gotobos(int f, int n)
{
    LINE *last = DOT.l;
    int nn = curwp->w_ntrows;

    n = need_at_least(f, n, 1);

    DOT.l = curwp->w_line.l;
    while (--n != 0) {
	if (is_last_line(DOT, curbp))
	    break;
	nn -= line_height(curwp, DOT.l);
	dot_next_bol();
    }

    if (DOT.l != last)
	curwp->w_flag |= WFMOVE;
    return firstnonwhite(FALSE, 1);
}

/*
 * Implements the vi "M" command.
 *
 * Move to the middle of lines displayed in window
 */
/* ARGSUSED */
int
gotomos(int f GCC_UNUSED, int n)
{
    LINE *last = DOT.l;
    LINE *lp, *head;
    int half = (curwp->w_ntrows + 1) / 2;

    head = buf_head(curbp);
    for (n = 0, lp = curwp->w_line.l; lp != head; lp = lforw(lp)) {
	if (n < half)
	    DOT.l = lp;
	if ((n += line_height(curwp, lp)) >= curwp->w_ntrows)
	    break;
    }
    if (n < curwp->w_ntrows) {	/* then we hit eof before eos */
	half = (n + 1) / 2;	/* go back up */
	for (n = 0, lp = curwp->w_line.l; lp != head; lp = lforw(lp)) {
	    DOT.l = lp;
	    if ((n += line_height(curwp, lp)) >= half)
		break;
	}
    }

    if (DOT.l != last)
	curwp->w_flag |= WFMOVE;
    return firstnonwhite(FALSE, 1);
}

/*
 * Implements the vi "L" command.
 *
 * Move to the last (or nth last) line in window
 */
int
gotoeos(int f, int n)
{
    LINE *last = DOT.l;
    int nn;

    n = need_at_least(f, n, 1);

    /* first get to the end */
    DOT.l = curwp->w_line.l;
    nn = curwp->w_ntrows;
    while ((nn -= line_height(curwp, DOT.l)) > 0) {
	if (is_last_line(DOT, curbp))
	    break;
	dot_next_bol();
    }
#ifdef WMDLINEWRAP
    /* adjust if we pointed to a line-fragment */
    if (w_val(curwp, WMDLINEWRAP)
	&& nn < 0
	&& DOT.l != curwp->w_line.l)
	DOT.l = lback(DOT.l);
#endif
    /* and then go back up */
    /* (we're either at eos or eof) */
    while (--n != 0) {
	if (sameline(DOT, curwp->w_line))
	    break;
	DOT.l = lback(DOT.l);
    }
    if (DOT.l != last)
	curwp->w_flag |= WFMOVE;
    return firstnonwhite(FALSE, 1);
}

/*
 * Implements the vi "j" command.
 *
 * Move forward by full lines. If the number of lines to move is less than
 * zero, call the backward line function to actually do it. The last command
 * controls how the goal column is set.
 */
int
forwline(int f, int n)
{
    int rc;
    LINE *dlp;

    n = need_a_count(f, n, 1);

    if (n < 0) {
	rc = backline(f, -n);
    } else if (n == 0) {
	rc = TRUE;
    } else {

	/* set the "goal" column if necessary */
	if (curgoal < 0)
	    curgoal = getccol(FALSE);

	/* loop downwards */
	dlp = DOT.l;
	rc = TRUE;
	do {
	    LINE *nlp = lforw(dlp);
	    if (nlp == buf_head(curbp)) {
		rc = FALSE;
		break;
	    }
	    dlp = nlp;
	} while (--n != 0);

	if (rc) {
	    /* set dot */
	    DOT.l = dlp;
	    DOT.o = getgoal(dlp);
	    curwp->w_flag |= WFMOVE;
	}
    }
    return rc;
}
/*
 * Implements the vi "^" command.
 *
 * Move to the first nonwhite character on the current line.  No errors are
 * returned.
 */
/* ARGSUSED */
int
firstnonwhite(int f GCC_UNUSED, int n GCC_UNUSED)
{
    DOT.o = firstchar(DOT.l);
    if (DOT.o < w_left_margin(curwp)) {
	if (llength(DOT.l) <= w_left_margin(curwp))
	    DOT.o = w_left_margin(curwp);
	else
	    DOT.o = llength(DOT.l) - 1;
    }
    return TRUE;
}

/* ARGSUSED */
#if !SMALLER
int
lastnonwhite(int f GCC_UNUSED, int n GCC_UNUSED)
{
    DOT.o = lastchar(DOT.l);
    if (DOT.o < w_left_margin(curwp))
	DOT.o = w_left_margin(curwp);
    return TRUE;
}
#endif

/* return the offset of the first non-white character on the line,
	or -1 if there are no non-white characters on the line */
int
firstchar(LINE *lp)
{
    int off = w_left_margin(curwp);
    while (off < llength(lp) && isBlank(lgetc(lp, off)))
	off++;
    if (off == llength(lp))
	return -1;
    return off;
}

/* return the offset of the next non-white character on the line,
	or -1 if there are no more non-white characters on the line */
int
nextchar(LINE *lp, int off)
{
    while (off < llength(lp)) {
	if (!isSpace(lgetc(lp, off)))
	    return off;
	off++;
    }
    return -1;
}

/* return the offset of the last non-white character on the line
	or -1 if there are no non-white characters on the line */
int
lastchar(LINE *lp)
{
    int off = llength(lp) - 1;
    while (off >= 0 && isSpace(lgetc(lp, off)))
	off--;
    return off;
}

/*
 * Implements the vi "^M" command.
 *
 * Like 'forwline()', but goes to the first non-white character position.
 */
int
forwbline(int f, int n)
{
    int s;

    n = need_a_count(f, n, 1);

    if ((s = forwline(f, n)) != TRUE)
	return (s);
    return firstnonwhite(FALSE, 1);
}

/*
 * Implements the vi "-" command.
 *
 * Like 'backline()', but goes to the first non-white character position.
 */
int
backbline(int f, int n)
{
    int s;

    n = need_a_count(f, n, 1);

    if ((s = backline(f, n)) != TRUE)
	return (s);
    return firstnonwhite(FALSE, 1);
}

/*
 * Implements the vi "k" command.
 *
 * This function is like "forwline", but goes backwards.
 */
int
backline(int f, int n)
{
    int rc;
    LINE *dlp;

    n = need_a_count(f, n, 1);

    if (n < 0) {
	rc = forwline(f, -n);
    } else if (is_first_line(DOT, curbp)) {
	/* cannot move up */
	rc = FALSE;
    } else {
	/* set the "goal" column if necessary */
	if (curgoal < 0)
	    curgoal = getccol(FALSE);

	/* loop upwards */
	dlp = DOT.l;
	while (n-- && lback(dlp) != buf_head(curbp))
	    dlp = lback(dlp);

	/* set dot */
	DOT.l = dlp;
	DOT.o = getgoal(dlp);
	curwp->w_flag |= WFMOVE;
	rc = TRUE;
    }
    return rc;
}

/*
 * Go to the beginning of the current paragraph.
 */
int
gotobop(int f, int n)
{
    MARK odot;
    int was_on_empty;
    int fc;

    n = need_a_count(f, n, 1);

    was_on_empty = is_empty_line(DOT);
    odot = DOT;

    fc = firstchar(DOT.l);
    if (doingopcmd &&
	((fc >= 0 && DOT.o <= fc) || fc < 0) &&
	!is_first_line(DOT, curbp)) {
	backchar(TRUE, DOT.o + 1);
	pre_op_dot = DOT;
    }
    while (n) {
	if (findpat(TRUE, 1, b_val_rexp(curbp, VAL_PARAGRAPHS)->reg,
		    REVERSE) != TRUE) {
	    (void) gotobob(f, n);
	} else if (is_empty_line(DOT)) {
	    /* special case -- if we found an empty line,
	       and it's adjacent to where we started,
	       skip all adjacent empty lines, and try again */
	    if ((was_on_empty && lforw(DOT.l) == odot.l) ||
		(n > 0 && llength(lforw(DOT.l)) == 0)) {
		/* then we haven't really found what we
		   wanted.  keep going */
		skipblanksb();
		continue;
	    }
	}
	n--;
    }
    if (doingopcmd) {
	fc = firstchar(DOT.l);
	if (!sameline(DOT, odot) &&
	    (pre_op_dot.o > lastchar(pre_op_dot.l)) &&
	    ((fc >= 0 && DOT.o <= fc) || fc < 0)) {
	    regionshape = rgn_FULLLINE;
	}
    }
    return TRUE;
}

/*
 * Go to the end of the current paragraph.
 */
int
gotoeop(int f, int n)
{
    MARK odot;
    int was_at_bol;
    int was_on_empty;
    int fc;

    n = need_a_count(f, n, 1);

    fc = firstchar(DOT.l);
    was_on_empty = is_empty_line(DOT);
    was_at_bol = ((fc >= 0 && DOT.o <= fc) || fc < 0);
    odot = DOT;

    while (n) {
	if (findpat(TRUE, 1, b_val_rexp(curbp, VAL_PARAGRAPHS)->reg,
		    FORWARD) != TRUE) {
	    DOT = curbp->b_line;
	} else if (is_empty_line(DOT)) {
	    /* special case -- if we found an empty line. */
	    /* either as the very next line, or at the end of
	       our search */
	    if ((was_on_empty && lback(DOT.l) == odot.l) ||
		(n > 0 && llength(lback(DOT.l)) == 0)) {
		/* then we haven't really found what we
		   wanted.  keep going */
		skipblanksf();
		continue;
	    }
	}
	n--;
    }
    if (doingopcmd) {
	/* if we're now at the beginning of a line and we can back up,
	   do so to avoid eating the newline and leading whitespace */
	fc = firstchar(DOT.l);
	if (((fc >= 0 && DOT.o <= fc) || fc < 0) &&
	    !is_first_line(DOT, curbp) &&
	    !sameline(DOT, odot)) {
	    backchar(TRUE, DOT.o + 1);
	}
	/* if we started at the start of line, eat the whole line */
	if (!sameline(DOT, odot) && was_at_bol)
	    regionshape = rgn_FULLLINE;
    }
    return TRUE;
}

#if OPT_STUTTER_SEC_CMD
getstutter(void)
{
    int thiskey;
    if (!clexec) {
	thiskey = lastkey;
	kbd_seq();
	if (thiskey != lastkey) {
	    return FALSE;
	}
    }
    return TRUE;
}
#endif

/*
 * Go to the beginning of the current section (or paragraph if no section
 * marker found).
 */
int
gotobosec(int f, int n)
{
#if OPT_STUTTER_SEC_CMD
    if (!getstutter())
	return FALSE;
#endif
    if (findpat(f, n, b_val_rexp(curbp, VAL_SECTIONS)->reg,
		REVERSE) != TRUE) {
	(void) gotobob(f, n);
    }
    return TRUE;
}

/*
 * Go to the end of the current section (or paragraph if no section marker
 * found).
 */
int
gotoeosec(int f, int n)
{
#if OPT_STUTTER_SEC_CMD
    if (!getstutter())
	return FALSE;
#endif
    if (findpat(f, n, b_val_rexp(curbp, VAL_SECTIONS)->reg,
		FORWARD) != TRUE) {
	DOT = curbp->b_line;
    }
    return TRUE;
}

/*
 * Go to the beginning of the current sentence. If we skip into an empty line
 * (from a non-empty line), return at that point -- that's what vi does.
 */
int
gotobosent(int f, int n)
{
    MARK savepos;
    int looped = 0;
    int extra;
    int empty = is_empty_line(DOT);
    regexp *exp;
    int s = TRUE;

    savepos = DOT;
    exp = b_val_rexp(curbp, VAL_SENTENCES)->reg;

    while (s && (is_at_end_of_line(DOT) || isSpace(CharAtDot()))) {
	s = backchar(TRUE, 1);
	if (is_empty_line(DOT) && !empty)
	    return TRUE;
    }
  top:
    extra = 0;
    if (findpat(f, n, exp, REVERSE) != TRUE) {
	return gotobob(f, n);
    }
    s = forwchar(TRUE, RegexpLen(exp));
    while (s && (is_at_end_of_line(DOT) || isSpace(CharAtDot()))) {
	s = forwchar(TRUE, 1);
	extra++;
    }
    if (n == 1 && samepoint(savepos, DOT)) {	/* try again */
	if (looped > 10)
	    return FALSE;
	s = backchar(TRUE, RegexpLen(exp) + extra + looped);
	while (s && is_at_end_of_line(DOT)) {
	    if (!empty && is_empty_line(DOT))
		return TRUE;
	    s = backchar(TRUE, 1);
	}
	looped++;
	goto top;

    }
    return TRUE;
}

/*
 * Go to the end of the current sentence.  Like gotobosent(), if we skip into
 * an empty line, return at that point.
 */
int
gotoeosent(int f, int n)
{
    regexp *exp;
    int s;
    int empty = is_empty_line(DOT);

    exp = b_val_rexp(curbp, VAL_SENTENCES)->reg;
    /* if we're on the end of a sentence now, don't bother scanning
       further, or we'll miss the immediately following sentence */
    if (!(lregexec(exp, DOT.l, DOT.o, llength(DOT.l), FALSE) &&
	  exp->startp[0] - lvalue(DOT.l) == DOT.o)) {
	if (findpat(f, n, exp, FORWARD) != TRUE) {
	    DOT = curbp->b_line;
	} else if (empty || !is_at_end_of_line(DOT)) {
	    s = forwchar(TRUE, RegexpLen(exp));
	    while (s && (is_at_end_of_line(DOT) || isSpace(CharAtDot()))) {
		LINE *lp = DOT.l;
		s = forwchar(TRUE, 1);
		if (lp != DOT.l)
		    break;
	    }
	}
    } else {
	s = forwchar(TRUE, RegexpLen(exp));
	while (s && (is_at_end_of_line(DOT) || isSpace(CharAtDot())))
	    s = forwchar(TRUE, 1);
    }
    return TRUE;
}

/*
 * This routine, given a pointer to a LINE, and the current cursor goal
 * column, return the best choice for the offset. The offset is returned.
 * Used by "C-N" and "C-P".
 */
int
getgoal(LINE *dlp)
{
    int col;
    int newcol;
    int dbo;

    col = 0;
    dbo = w_left_margin(curwp);
    while (dbo < llength(dlp)) {
	newcol = next_column(dlp, dbo, col);
	if (newcol > curgoal)
	    break;
	col = newcol;
	dbo += BytesAt(dlp, dbo);
    }
    return (dbo);
}

int
next_sw(int col)
{
    int width = shiftwid_val(curbp);
    return (((col / width) + 1) * width);
}

int
next_tabcol(int col)
{
    int t = tabstop_val(curbp);
    return (((col / t) + 1) * t);
}

#define NonPrintingCols(c) (((c) & HIGHBIT) ? COLS_8BIT : COLS_CTRL)

/*
 * Return the next column index, given the current char and column.
 */
int
next_column(LINE *lp, int off, int col)
{
    int rc = 1;
    int c;

    if (off < llength(lp)) {
	c = lgetc(lp, off);

	if (c == '\t') {
	    rc = next_tabcol(col) - col;
	}
#if OPT_MULTIBYTE
	else if (b_is_utfXX(curbp)) {
	    if (bytes_at(lp, off) > 1) {
		rc = mb_cellwidth(curwp, lvalue(lp) + off, llength(lp) - off);
	    }
	}
#endif
	else if (!isPrint(CharOf(c))) {
	    rc = NonPrintingCols(c);
	}
    } else {
	rc = 0;
    }
    return col + rc;
}

/*
 * Given a char to add, and the current column, return the next column index,
 */
int
column_after(int c, int col, int list)
{
    int rc = (col + 1);

    if (!list && (c == '\t')) {
	rc = next_tabcol(col);
    }
#if OPT_MULTIBYTE
    else if (b_is_utfXX(curbp)) {
	if (vl_conv_to_utf8((UCHAR *) 0, (UINT) c, (B_COUNT) 10) > 1)
	    rc = col + COLS_UTF8;	/* "\uXXXX" */
    }
#endif
    else if (!isPrint(CharOf(c))) {
	rc = col + NonPrintingCols(c);
    }
    return rc;
}

/*
 * Given a pointer to a LINE's text where we have a "nonprinting" character,
 * and the limit on remaining chars to display, return the number of columns
 * which are needed to display it, e.g., in hex or octal.  As a side-effect,
 * set the *used parameter to the number of chars needed for a multibyte
 * character if we have one.
 */
int
column_sizes(WINDOW *wp, const char *text, unsigned limit, int *used)
{
    int rc = NonPrintingCols(CharOf(*text));

    *used = 1;
#if OPT_MULTIBYTE
    if (b_is_utfXX(wp->w_bufp)) {
	*used = vl_conv_to_utf32((UINT *) 0, text, (B_COUNT) limit);
	if (*used > 1) {
	    rc = COLS_UTF8;	/* "\uXXXX" */
	} else if (*used < 1) {
	    *used = 1;		/* probably a broken character... */
	} else if (isPrint(CharOf(*text))) {
	    rc = 1;
	}
    } else
#else
    (void) wp;
    (void) limit;
#endif
    if (isPrint(CharOf(*text))) {
	rc = 1;
    }
    return rc;
}

/*
 * Implements the vi "^F" command.
 *
 * Scroll forward by a specified number of lines, or by a full page if no
 * argument.
 */
int
forwpage(int f, int n)
{
    LINE *lp;
    int status;

    if ((n = full_pages(f, n)) < 0)
	return backpage(f, -n);

    if ((status = (lforw(DOT.l) != buf_head(curbp))) == TRUE) {
	lp = curwp->w_line.l;
	n -= line_height(curwp, lp);
	while (lp != buf_head(curbp)) {
	    lp = lforw(lp);
	    if ((n -= line_height(curwp, lp)) < 0)
		break;
	}
	if (n < 0)
	    curwp->w_line.l = lp;
	DOT.l = lp;
	(void) firstnonwhite(FALSE, 1);
	curwp->w_flag |= WFHARD | WFMODE;
    }
    return status;
}

/*
 * Implements the vi "^B" command.
 *
 * This command is like "forwpage", but it goes backwards.
 */
int
backpage(int f, int n)
{
    LINE *lp;
    int status;

    if ((n = full_pages(f, n)) < 0)
	return forwpage(f, -n);

    lp = curwp->w_line.l;
    if (lback(lp) != buf_head(curbp)) {
	while ((n -= line_height(curwp, lp)) >= 0
	       && lback(lp) != buf_head(curbp))
	    lp = lback(lp);
	curwp->w_line.l = lp;
	(void) gotoeos(FALSE, 1);
	curwp->w_flag |= WFHARD | WFMODE;
	status = TRUE;
    } else if (DOT.l != lp) {
	DOT.l = lp;
	curwp->w_flag |= WFHARD | WFMODE;
	status = TRUE;
    } else {
	status = FALSE;
    }
    return status;
}

/*
 * Implements the vi "^D" command.
 *
 * Scroll forward by a half-page.  If a repeat count is given, interpret that
 * as the number of half-pages to scroll.
 *
 * Unlike vi, the OPT_CVMVAS option causes the repeat-count to be interpreted as
 * half-page, rather than lines.
 */
int
forwhpage(int f, int n)
{
    LINE *llp, *dlp;
    int status;

    if ((n = half_pages(f, n)) < 0)
	return backhpage(f, -n);

    llp = curwp->w_line.l;
    dlp = DOT.l;
    if ((status = (lforw(dlp) != buf_head(curbp))) == TRUE) {
	n -= line_height(curwp, dlp);
	while (lforw(dlp) != buf_head(curbp)) {
	    llp = lforw(llp);
	    dlp = lforw(dlp);
	    if ((n -= line_height(curwp, dlp)) < 0)
		break;
	}
	curwp->w_line.l = llp;
	DOT.l = dlp;
	curwp->w_flag |= WFHARD | WFKILLS;
    }
    (void) firstnonwhite(FALSE, 1);
    return status;
}

/*
 * Implements the vi "^U" command.
 *
 * This command is like "forwpage", but it goes backwards.  It returns false
 * only if the cursor is on the first line of the buffer.
 *
 * Unlike vi, the OPT_CVMVAS option causes the repeat-count to be interpreted as
 * half-pages, rather than lines.
 */
int
backhpage(int f, int n)
{
    LINE *llp, *dlp;
    int status;

    if ((n = half_pages(f, n)) < 0)
	return forwhpage(f, -n);

    llp = curwp->w_line.l;
    dlp = DOT.l;
    if ((status = (lback(dlp) != buf_head(curbp))) == TRUE) {
	n -= line_height(curwp, dlp);
	while (lback(dlp) != buf_head(curbp)) {
	    llp = lback(llp);
	    dlp = lback(dlp);
	    if ((n -= line_height(curwp, dlp)) < 0)
		break;
	}
	curwp->w_line.l = llp;
	DOT.l = dlp;
	curwp->w_flag |= WFHARD | WFINS;
    }
    (void) firstnonwhite(FALSE, 1);
    return status;
}

/*
 * Move forward n rows on the screen, staying in the same column.  It's ok to
 * scroll, too.
 */
int
forw_row(int f, int n)
{
    int code = TRUE;
    int col, next;

    n = need_a_count(f, n, 1);

    if (n < 0) {
	code = back_row(f, -n);
    } else if (n > 0) {

	/* set the "goal" column if necessary */
	if (curgoal < 0)
	    curgoal = getccol(FALSE);

	col = curgoal;
	next = col;

	while ((n-- > 0) && (code == TRUE)) {
	    int save = next;
	    next += term.cols;
	    if (gotocol(TRUE, next + 1) == FALSE) {
		curgoal %= term.cols;
		gotocol(TRUE, save);
		code = forwline(TRUE, 1);
	    } else {
		curgoal = next;
	    }
	}
    }
    return code;
}

/*
 * Move back n rows on the screen, staying in the same column.  It's ok to
 * scroll, too.
 */
int
back_row(int f, int n)
{
    int code = TRUE;
    int col, next;

    n = need_a_count(f, n, 1);

    if (n < 0) {
	code = forw_row(f, -n);
    } else if (n > 0) {

	/* set the "goal" column if necessary */
	if (curgoal < 0)
	    curgoal = getccol(FALSE);

	col = curgoal;
	next = col;

	while ((n-- > 0) && (code == TRUE)) {
	    next -= term.cols;
	    if (next < 0) {
		if ((code = backline(TRUE, 1)) == TRUE
		    && llength(DOT.l) >= curgoal) {
		    next = llength(DOT.l) / term.cols;
		    next = (next * term.cols) + curgoal;
		    curgoal = next;
		}
	    } else {
		if ((code = gotocol(TRUE, next + 1)) == TRUE)
		    curgoal = next;
	    }
	}
    }
    return code;
}

#if NMARKS > 26
static int
nmark2inx(int c)
{
    if (isDigit(c)) {
	return c - '0' + 26;
    } else if (isLower(c)) {
	return c - 'a';
    }
    return -1;
}

static int
inx2nmark(int c)
{
    if (c > 36 || c < 0) {
	return '?';
    } else if (c >= 26) {
	return c - 26 + '0';
    } else {
	return c + 'a';
    }
}
#else
#define nmark2inx(c) ((c) - 'a')
#define inx2nmark(c) ((c) + 'a')
#endif

#if OPT_SHOW_MARKS
static int
show_mark(int count, BUFFER *bp, MARK mark, int name)
{
    static int tab = 8;		/* no b_val(bp,VAL_TAB) -- set_rdonly uses 8 */
    static int stop;

    if (!samepoint(mark, nullmark)) {

	if (!count) {
	    bprintf("\nMark  Line     Column");
	    if (stop == 0) {
		stop = ((DOT.o + tab - 1) / tab) * tab;
	    }
	    bpadc(' ', stop - DOT.o);
	    bprintf("Text");
	    bprintf("\n----  -------- ------");
	    bpadc(' ', stop - DOT.o);
	    bprintf("----");
	}

	bprintf("\n%c     %8d %8d",
		name,
		line_no(bp, mark.l),
		mk_to_vcol(curwp, mark, FALSE, 0, 0) + 1);
	if (llength(mark.l) > 0) {
	    bpadc(' ', stop - DOT.o);
	    bputsn(lvalue(mark.l), llength(mark.l));
	}
	return 1;
    }
    return 0;
}

static void
makemarkslist(int value GCC_UNUSED, void *dummy GCC_UNUSED)
{
    BUFFER *bp = (BUFFER *) dummy;
    WINDOW *wp;
    int n;
    int done = 0;

    bprintf("Named marks for %s\n", bp->b_bname);
    set_b_val(curbp, VAL_TAB, b_val(bp, VAL_TAB));

    for_each_window(wp) {
	if (wp->w_bufp == bp) {
	    done += show_mark(done, bp, wp->w_lastdot, SQUOTE);
	}
    }
    if (bp->b_nmmarks != 0) {
	for (n = 0; n < NMARKS; n++) {
	    done += show_mark(done, bp, bp->b_nmmarks[n], inx2nmark(n));
	}
    }
#if OPT_SELECTIONS
    if (bp == sel_buffer()) {
	MARK left, right;
	if (sel_get_leftmark(&left)
	    && sel_get_rightmark(&right)
	    && (left.l != right.l
		|| left.o != right.o)) {
	    done += show_mark(done, bp, left, '<');
	    done += show_mark(done, bp, right, '>');
	}
    }
#endif
    if (done)
	bprintf("\n\n%d mark%s", done, PLURAL(done));
    else
	bprintf("\n(none)");
}

int
showmarks(int f, int n GCC_UNUSED)
{
    WINDOW *wp = curwp;
    int s;

    TRACE((T_CALLED "showmarks(f=%d)\n", f));

    s = liststuff(MARKS_BufName, FALSE, makemarkslist, f, (void *) curbp);
    /* back to the buffer whose modes we just listed */
    if (swbuffer(wp->w_bufp))
	curwp = wp;

    returnCode(s);
}

#if OPT_UPBUFF
/* ARGSUSED */
static int
update_marklist(BUFFER *bp GCC_UNUSED)
{
    return showmarks(FALSE, 1);
}
#endif
#endif /* OPT_SHOW_MARKS */

static int
invalid_nmmark(void)
{
    mlforce("[Invalid mark name]");
    return FALSE;
}

int
can_set_nmmark(int c)
{
    if (isLower(c) || c == SQUOTE)
	return TRUE;
#if !SMALLER
    if (isDigit(c))
	return TRUE;
#endif
#if OPT_SELECTIONS
    if (c == '<' || c == '>')
	return TRUE;
#endif
    return FALSE;
}

static int
get_nmmark(int c, MARK *markp)
{
    int result = TRUE;

    *markp = nullmark;
    if (c == SQUOTE) {		/* use the 'last dot' mark */
	*markp = curwp->w_lastdot;
    } else {
#if OPT_SELECTIONS
	if (c == '<') {
	    result = sel_get_leftmark(markp);
	} else if (c == '>') {
	    result = sel_get_rightmark(markp);
	} else
#endif
	if (curbp->b_nmmarks != NULL) {
	    *markp = curbp->b_nmmarks[nmark2inx(c)];
	} else {
	    result = FALSE;
	}
    }
    TRACE(("get_nmmark(%c) ->%d.%d\n",
	   c, result ? line_no(curbp, markp->l) : 0, markp->o));
    return result;
}

int
show_mark_is_set(int c)
{
    int rc = TRUE;
#if OPT_SHOW_MARKS
    int ignore = (curbp != 0 && eql_bname(curbp, MARKS_BufName));
    if (isLower(c)) {
	mlwrite("[Mark '%c' %s]", c, ignore ? "ignored" : "set");
    }
    if (ignore) {
	rc = FALSE;
    } else {
	update_scratch(MARKS_BufName, update_marklist);
    }
#else
    (void) c;
#endif
    return rc;
}

/*
 * Implements the vi "m" command.
 *
 * Set the named mark in the current window to the value of "." in the window.
 */
/* ARGSUSED */
int
setnmmark(int f GCC_UNUSED, int n GCC_UNUSED)
{
    int c, i;

    if (clexec || isnamedcmd) {
	int status;
	static char cbuf[2];
	if ((status = mlreply("Set mark: ", cbuf, 2)) != TRUE)
	    return status;
	c = cbuf[0];
    } else {
	c = keystroke();
	if (ABORTED(c))
	    return ABORT;
    }

    if (nmark2inx(c) < 0) {
	return invalid_nmmark();
    }

    if (curbp->b_nmmarks == NULL) {

	beginDisplay();
	curbp->b_nmmarks = typeallocn(struct MARK, NMARKS);
	endofDisplay();

	if (curbp->b_nmmarks == NULL)
	    return no_memory("named-marks");
	for (i = 0; i < NMARKS; i++) {
	    curbp->b_nmmarks[i] = nullmark;
	}
    }

    curbp->b_nmmarks[nmark2inx(c)] = DOT;
    return show_mark_is_set(c);
}

/*
 * Get the name of the mark to use.  interactively, "last dot" is represented
 * by stuttering the goto-mark command.  From the command line, it's always
 * named ' or `.  I suppose this is questionable.
 */
static int
getnmmarkname(int *cp)
{
    int c;
    int thiskey;
    int useldmark;

    if (clexec || isnamedcmd) {
	int status;
	static char cbuf[2];
	if ((status = mlreply("Goto mark: ", cbuf, 2)) != TRUE)
	    return status;
	c = cbuf[0];
	useldmark = (c == SQUOTE || c == BQUOTE);
    } else {
	thiskey = lastkey;
	c = keystroke();
	if (ABORTED(c))
	    return ABORT;
	useldmark = (lastkey == thiskey);	/* usually '' or `` */
    }

    if (useldmark)
	c = SQUOTE;

    *cp = c;
    TRACE(("getnmmarkname(%c)\n", c));
    return TRUE;
}

/* ARGSUSED */
int
golinenmmark(int f GCC_UNUSED, int n GCC_UNUSED)
{
    int c;
    int s;

    s = getnmmarkname(&c);
    if (s != TRUE)
	return s;
    s = gonmmark(c);
    if (s != TRUE)
	return s;

    return firstnonwhite(FALSE, 1);
}

/* ARGSUSED */
int
goexactnmmark(int f GCC_UNUSED, int n GCC_UNUSED)
{
    int c;
    int s;

    s = getnmmarkname(&c);
    if (s != TRUE)
	return s;

    return gonmmark(c);
}

/* ARGSUSED */
int
gorectnmmark(int f GCC_UNUSED, int n GCC_UNUSED)
{
    int c;
    int s;

    s = getnmmarkname(&c);
    if (s != TRUE)
	return s;

    regionshape = rgn_RECTANGLE;
    return gonmmark(c);
}

int
gonmmark(int c)
{
    MARK my_mark;
    MARK tmark;

    TRACE(("gonmmark(%c)\n", c));

    if (!can_set_nmmark(c)) {
	return invalid_nmmark();
    }

    /* save current dot */
    tmark = DOT;

    /* if we have any named marks, and the one we want isn't null */
    if (!get_nmmark(c, &my_mark) || !restore_dot(my_mark)) {
	mlforce("[Mark not set]");
	return (FALSE);
    }

    if (!doingopcmd)		/* reset last-dot-mark to old dot */
	curwp->w_lastdot = tmark;

    show_mark_is_set(0);
    return (TRUE);
}

/*
 * Set the mark in the current window to the value of "." in the window. No
 * errors are possible.
 */
int
setmark(void)
{
    MK = DOT;
    return (TRUE);
}

/* ARGSUSED */
int
gomark(int f GCC_UNUSED, int n GCC_UNUSED)
{
    DOT = MK;
    curwp->w_flag |= WFMOVE;
    return (TRUE);
}

/* this odd routine puts us at the internal mark, plus an offset of lines */
/*  n == 1 leaves us at mark, n == 2 one line down, etc. */
/*  this is for the use of stuttered commands, and line oriented regions */
int
godotplus(int f, int n)
{
    int s;

    if (!f || n == 1) {
	s = firstnonwhite(FALSE, 1);
    } else if (n < 1) {
	s = FALSE;
    } else {
	s = forwline(TRUE, n - 1);
	if (s && is_header_line(DOT, curbp)) {
	    s = backline(FALSE, 1);
	}
	if (s == TRUE) {
	    (void) firstnonwhite(FALSE, 1);
	}
    }
    return s;
}

/*
 * Swap the values of "." and "mark" in the current window. This is pretty
 * easy, because all of the hard work gets done by the standard routine
 * that moves the mark about. The only possible error is "no mark".
 */
void
swapmark(void)
{
    MARK odot;

    if (samepoint(MK, nullmark)) {
	mlforce("BUG: No mark ");
    } else {
	odot = DOT;
	DOT = MK;
	MK = odot;
	curwp->w_flag |= WFMOVE;
    }
    return;
}

#if OPT_MOUSE
/*
 * Given row & column from the screen, set the MK value.
 * The resulting position will not be past end-of-buffer unless the buffer
 * is empty.
 */
int
setwmark(int row, int col)
{
    MARK save;
    LINE *dlp;

    save = DOT;
    if (row == mode_row(curwp)) {
	(void) gotoeos(FALSE, 1);
	DOT.l = lforw(DOT.l);
	DOT.o = w_left_margin(curwp);
    } else {			/* move to the right row */
	row -= curwp->w_toprow + curwp->w_line.o;
	/*
	 * In the statement above, wp->w_line.o will
	 * normally be zero.  But when the top line of the
	 * window is wrapped and the beginning of the line
	 * is not visible, it will have the number of
	 * lines that would appear before the top line
	 * negated.  (E.g, if the wrapped line occupied
	 * 2 lines before the top window line, then wp->w_line.o
	 * will have the value -2.)
	 */

	dlp = curwp->w_line.l;	/* get pointer to 1st line */
	while ((row -= line_height(curwp, dlp)) >= 0
	       && dlp != buf_head(curbp))
	    dlp = lforw(dlp);
	DOT.l = dlp;		/* set dot line pointer */

	/* now move the dot over until near the requested column */
#ifdef WMDLINEWRAP
	if (w_val(curwp, WMDLINEWRAP))
	    col += term.cols * (row + line_height(curwp, dlp));
#endif
	DOT.o = col2offs(curwp, dlp, col);

#ifdef OPT_MOUSE_NEWLINE
	/* don't allow the cursor to be set past end of line unless we
	 * are in insert mode
	 */
	if (DOT.o >= llength(dlp) && DOT.o > w_left_margin(curwp) &&
	    !insertmode) {
	    DOT.o -= BytesBefore(DOT.l, DOT.o);
	}
#endif
    }
    if (is_header_line(DOT, curwp->w_bufp)) {
	DOT.l = lback(DOT.l);
	DOT.o = llength(DOT.l);
    }
    MK = DOT;
    DOT = save;

    TRACE(("setwmark -> line %d, col %d\n", line_no(curwp->w_bufp, MK.l), MK.o));
    return TRUE;
}

/*
 * Given row & column from the screen, set the curwp and DOT values.
 */
int
setcursor(int row, int col)
{
    int code = FALSE;
    WINDOW *wp0 = curwp;
    WINDOW *wp1;
    MARK saveMK;

    TRACE((T_CALLED "setcursor(%d,%d)\n", row, col));
    if ((wp1 = row2window(row)) != 0) {
	if (!(doingsweep && curwp != wp1)) {
	    saveMK = MK;
	    if (set_curwp(wp1)
		&& setwmark(row, col)) {
		if (insertmode != FALSE
		    && b_val(wp1->w_bufp, MDVIEW)
		    && b_val(wp1->w_bufp, MDSHOWMODE)) {
		    if (b_val(wp0->w_bufp, MDSHOWMODE))
			wp0->w_flag |= WFMODE;
		    if (b_val(wp1->w_bufp, MDSHOWMODE))
			wp1->w_flag |= WFMODE;
		    insertmode = FALSE;
		}
		DOT = MK;
		if (wp0 == wp1)
		    MK = saveMK;
		curwp->w_flag |= WFMOVE;
		code = TRUE;
	    }
	}
    }
    returnCode(code);
}
#endif
vile-9.8v/bind.c000066400000000000000000002370331415556424100136160ustar00rootroot00000000000000/*	This file is for functions having to do with key bindings,
 *	descriptions, help commands and startup file.
 *
 *	written 11-feb-86 by Daniel Lawrence
 *
 * $Id: bind.c,v 1.378 2018/10/24 00:14:57 tom Exp $
 */

#include	"estruct.h"
#include	"edef.h"
#include	"nefunc.h"
#include	"nefsms.h"
#include	"nename.h"

#define BI_DATA NBST_DATA
#include	"btree.h"

#define SHORT_CMD_LEN 4		/* command names longer than this are preferred
				   over those shorter.  e.g. display "quit"
				   instead of "q" if possible */

extern const int nametbl_size;

#define Strcmp(s,d)      cs_strcmp(case_insensitive, s, d)
#define StrNcmp(s,d,len) cs_strncmp(case_insensitive, s, d, len)

#if OPT_REBIND
#define	isSpecialCmd(k) \
		( (k == &f_cntl_a_func)\
		||(k == &f_cntl_x_func)\
		||(k == &f_poundc_func)\
		||(k == &f_reptc_func)\
		||(k == &f_esc_func)\
		)

static int key_to_bind(const CMDFUNC * kcmd);
static int update_binding_list(BUFFER *bp);
static void makebindlist(LIST_ARGS);
static void makebindkeyslist(LIST_ARGS);
#endif /* OPT_REBIND */

#if OPT_NAMEBST
static int kbd_complete_bst(unsigned flags, int c, char *buf, size_t *pos);
#else
#define kbd_complete_bst(params) \
	kbd_complete(params, \
			(const char *)&nametbl[0], sizeof(nametbl[0]))
#endif /* OPT_NAMEBST */

#if OPT_EVAL || OPT_REBIND
static int fnc2ntab(NTAB * result, const CMDFUNC * cfp);
static int prc2kcod(const char *kk);
#endif

BINDINGS dft_bindings =
{
    BINDINGLIST_BufName
    ,asciitbl
    ,kbindtbl
#if OPT_REBIND
    ,kbindtbl
#endif
};

static const CMDFUNC *ins_table[N_chars];
BINDINGS ins_bindings =
{
    INS_BINDINGS_BufName
    ,ins_table
    ,kbindtbl
#if OPT_REBIND
    ,kbindtbl
#endif
};

static const CMDFUNC *cmd_table[N_chars];
BINDINGS cmd_bindings =
{
    CMD_BINDINGS_BufName
    ,cmd_table
    ,kbindtbl
#if OPT_REBIND
    ,kbindtbl
#endif
};

static const CMDFUNC *sel_table[N_chars];
BINDINGS sel_bindings =
{
    SEL_BINDINGS_BufName
    ,sel_table
    ,kbindtbl
#if OPT_REBIND
    ,kbindtbl
#endif
};

static struct {
    const char *name;
    BINDINGS *binding;
} bindings_by_name[] = {

    {
	"command", &cmd_bindings
    },
    {
	"default", &dft_bindings
    },
    {
	"insert", &ins_bindings
    },
    {
	"select", &sel_bindings
    },
};

static UINT which_current;

#if OPT_REBIND
static BINDINGS *bindings_to_describe = &dft_bindings;
#endif

static void kbd_puts(const char *s);

/*----------------------------------------------------------------------------*/

BINDINGS *
vl_get_binding(const char *name)
{
    BINDINGS *result = 0;
    unsigned n;
    for (n = 0; n < TABLESIZE(bindings_by_name); ++n) {
	if (!strncmp(bindings_by_name[n].name, name, strlen(name))) {
	    result = bindings_by_name[n].binding;
	    break;
	}
    }
    return result;
}

/*----------------------------------------------------------------------------*/

#if OPT_NAMEBST
static void
old_namebst(BI_NODE * a)
{
    beginDisplay();
    if (!(a->value.n_flags & NBST_READONLY)) {
	CMDFUNC *cmd = TYPECAST(CMDFUNC, a->value.n_cmd);
	if (cmd != 0) {
	    if ((cmd->c_flags & CMD_TYPE) != CMD_FUNC) {
#if OPT_ONLINEHELP
		if (cmd->c_help)
		    free(TYPECAST(char, cmd->c_help));
#endif
#if OPT_MACRO_ARGS
		if (cmd->c_args) {
		    int n;
		    for (n = 0; cmd->c_args[n].pi_text != 0; ++n) {
			free(cmd->c_args[n].pi_text);
		    }
		    free(cmd->c_args);
		}
#endif
		free(cmd);
		free(TYPECAST(char, BI_KEY(a)));
	    }
	} else {
	    free(TYPECAST(char, BI_KEY(a)));
	}
    }
    free(a);
    endofDisplay();
}

static BI_NODE *
new_namebst(BI_DATA * a)
{
    BI_NODE *p;

    beginDisplay();
    if ((p = typecalloc(BI_NODE)) != 0) {
	p->value = *a;
	if (!(a->n_flags & NBST_READONLY)) {
	    if ((BI_KEY(p) = strmalloc(a->bi_key)) == 0) {
		old_namebst(p);
		p = 0;
	    }
	}
    }
    endofDisplay();

    return p;
}

static void
dpy_namebst(BI_NODE * a GCC_UNUSED, int level GCC_UNUSED)
{
#if OPT_TRACE
    TRACE(("[%d]%s%p -> %s%s (%d)\n",
	   level, alloc_indent(level, '.'),
	   (void *) a,
	   (a->value.n_flags & NBST_READONLY)
	   ? "*"
	   : "",
	   BI_KEY(a), a->balance));
#endif
}

static void
xcg_namebst(BI_NODE * a, BI_NODE * b)
{
    BI_DATA temp = a->value;
    a->value = b->value;
    b->value = temp;
}

#define BI_DATA0 {{0}, 0, {0,0,0}}
#define BI_TREE0 0, 0, BI_DATA0

static BI_TREE namebst =
{new_namebst, old_namebst, dpy_namebst, xcg_namebst, BI_TREE0};

static BI_TREE glbsbst =
{new_namebst, old_namebst, dpy_namebst, xcg_namebst, BI_TREE0};

static BI_TREE redefns =
{new_namebst, old_namebst, dpy_namebst, xcg_namebst, BI_TREE0};

/*----------------------------------------------------------------------------*/
/*
 * Name-completion for global commands uses a different table (a subset) from
 * the normal command-table.  Provide a way to select that table.
 */

static BI_TREE *
bst_pointer(UINT which)
{
    BI_TREE *result;

    if (which == GLOBOK) {
	result = &glbsbst;
    } else {
	result = &namebst;
    }
    return result;
}

static BI_TREE *
bst_current(void)
{
    return bst_pointer(which_current);
}
#endif /* OPT_NAMEBST */

/*----------------------------------------------------------------------------*/

int
no_such_function(const char *fnp)
{
    mlforce("[No such function \"%s\"]", NONNULL(fnp));
    return FALSE;
}

/* give me some help!!!! bring up a buffer and read the help file into it */
/* ARGSUSED */
int
vl_help(int f GCC_UNUSED, int n GCC_UNUSED)
{
    BUFFER *bp;			/* buffer pointer to help */
    char *hname;
    int alreadypopped;

    TRACE((T_CALLED "vl_help()\n"));

    /* first check if we are already here */
    bp = bfind(HELP_BufName, BFSCRTCH);
    if (bp == NULL)
	returnCode(FALSE);

    if (bp->b_active == FALSE) {	/* never been used */
	hname = cfg_locate(helpfile, LOCATE_HELP);
	if (!hname) {
	    mlforce("[Sorry, can't find the help information]");
	    (void) zotbuf(bp);
	    returnCode(FALSE);
	}
	alreadypopped = (bp->b_nwnd != 0);
	/* and read the stuff in */
	if (readin(hname, 0, bp, TRUE) != TRUE ||
	    popupbuff(bp) == FALSE) {
	    (void) zotbuf(bp);
	    returnCode(FALSE);
	}
	set_bname(bp, HELP_BufName);
	set_rdonly(bp, hname, MDVIEW);

	set_local_b_val(bp, MDIGNCASE, TRUE);	/* easy to search, */
	b_set_scratch(bp);
	b_set_recentlychanged(bp);
	if (!alreadypopped)
	    shrinkwrap();
    }

    if (!swbuffer(bp))
	returnCode(FALSE);

    if (help_at >= 0) {
	if (!vl_gotoline(help_at))
	    returnCode(FALSE);
	mlwrite("[Type '1G' to return to start of help information]");
	help_at = -1;		/* until zotbuf is called, we let normal
				   DOT tracking keep our position */
    }
    returnCode(TRUE);
}

/*
 * translate a 10-bit key-binding to the table-pointer
 */
static KBIND *
kcode2kbind(const BINDINGS * bs, int code)
{
    KBIND *kbp;

    TRACE(("kcode2kbind(%s, %#x)\n", bs->bufname, code));
#if OPT_REBIND
    for (kbp = bs->kb_extra; kbp != bs->kb_special; kbp = kbp->k_link) {
	if (kbp->k_code == code) {
	    TRACE(("...found in extra-bindings\n"));
	    return kbp;
	}
    }
#endif
    for (kbp = bs->kb_special; kbp->k_cmd; kbp++) {
	if (kbp->k_code == code) {
	    TRACE(("...found in special-bindings\n"));
	    return kbp;
	}
    }
    return 0;
}

#if OPT_REBIND

#if OPT_TERMCHRS

	/* NOTE: this table and the corresponding initializations should be
	 * generated by 'mktbls'.  In any case, the table must be sorted to use
	 * name-completion on it.
	 */
static const struct {
    const char *name;
    int *value;
    char how_to;
} TermChrs[] = {
		/* *INDENT-OFF* */
		{"backspace",		&backspc,	's'},
		{"interrupt",		&intrc,		's'},
		{"line-kill",		&killc,		's'},
		{"mini-edit",		&editc,		's'},
		{"name-complete",	&name_cmpl,	0},
		{"quote-next",		"ec,	0},
		{"start-output",	&startc,	's'},
		{"stop-output",		&stopc,		's'},
		{"suspend",		&suspc,		's'},
		{"test-completions",	&test_cmpl,	0},
		{"word-kill",		&wkillc,	's'},
		{0,                     0,              0}
		/* *INDENT-ON* */

};

/*----------------------------------------------------------------------------*/

/* list the current chrs into the current buffer */
/* ARGSUSED */
static void
makechrslist(int dum1 GCC_UNUSED, void *ptr GCC_UNUSED)
{
    int i;
    char temp[NLINE];

    bprintf("--- Terminal Character Settings ");
    bpadc('-', term.cols - DOT.o);
    bputc('\n');

    for (i = 0; TermChrs[i].name != 0; i++) {
	bprintf("\n%s = %s",
		TermChrs[i].name,
		kcod2prc(*(TermChrs[i].value), temp));
    }
}

/*
 * Find a special-character definition, given the name
 */
static int
chr_lookup(const char *name)
{
    int j;
    if (name != 0) {
	for (j = 0; TermChrs[j].name != 0; j++)
	    if (!strcmp(name, TermChrs[j].name))
		return j;
    }
    return -1;
}

/*
 * The 'chr_complete()' and 'chr_eol()' functions are invoked from
 * 'kbd_reply()' to setup the mode-name completion and query displays.
 */
static int
chr_complete(DONE_ARGS)
{
    return kbd_complete(PASS_DONE_ARGS, (const char *) &TermChrs[0],
			sizeof(TermChrs[0]));
}

static int
/*ARGSUSED*/
chr_eol(EOL_ARGS)
{
    (void) buffer;
    (void) cpos;
    (void) eolchar;

    return isSpace(c);
}

#if OPT_UPBUFF
/* ARGSUSED */
static int
update_termchrs(BUFFER *bp GCC_UNUSED)
{
    return show_termchrs(FALSE, 1);
}
#endif

/* ARGSUSED */
int
set_termchrs(int f GCC_UNUSED, int n GCC_UNUSED)
{
    int s, j;
    static TBUFF *name;
    int c;

    /* get the table-entry */
    tb_scopy(&name, "");
    if ((s = kbd_reply("Terminal setting: ", &name, chr_eol,
		       ' ', 0, chr_complete)) == TRUE
	&& (j = chr_lookup(tb_values(name))) >= 0) {
	switch (TermChrs[j].how_to) {
	case 's':
	default:
	    c = key_to_bind((CMDFUNC *) 0);
	    if (c < 0)
		return (FALSE);
	    *(TermChrs[j].value) = c;
	    break;
	}
	update_scratch(TERMINALCHARS_BufName, update_termchrs);
    }
    return s;
}

/* ARGSUSED */
int
show_termchrs(int f GCC_UNUSED, int n GCC_UNUSED)
{
    return liststuff(TERMINALCHARS_BufName, FALSE, makechrslist, 0, (void *) 0);
}
#endif /* OPT_TERMCHRS */

static int
mac_token2kcod(int check)
{
    static TBUFF *tok;
    char *value;
    int c;

    if ((value = mac_unquotedarg(&tok)) == 0) {
	c = -1;
    } else {
	c = prc2kcod(value);

	if (c < 0 && check)
	    mlforce("[Illegal key-sequence \"%s\"]", value);
    }

    return c;
}

/*
 * Prompt-for and return the key-code to bind.
 */
static int
key_to_bind(const CMDFUNC * kcmd)
{
    char outseq[NLINE];		/* output buffer for keystroke sequence */
    int c;

    mlprompt("...to keyboard sequence (type it exactly): ");

    /* if running a command line, get a token rather than keystrokes */
    if (clexec) {
	c = mac_token2kcod(FALSE);
    } else {
	/* perhaps we only want a single key, not a sequence */
	/*      (see more comments below) */
	if (isSpecialCmd(kcmd)) {
	    c = keystroke();
	} else {
	    c = kbd_seq();
	}
    }

    if (c >= 0) {
	/* change it to something we can print as well */
	outseq[0] = EOS;
	if (vl_msgs)
	    kbd_puts(kcod2prc(c, outseq));
	hst_append_s(outseq, FALSE, TRUE);
    } else {
	mlforce("[Not a proper key-sequence]");
    }
    return c;
}

static int
free_KBIND(KBIND ** oldp, KBIND * newp)
{
    *oldp = newp->k_link;

    beginDisplay();
    free(newp);
    endofDisplay();

    return TRUE;
}

static int
unbindchar(BINDINGS * bs, int c)
{
    KBIND *kbp;			/* pointer into the command table */
    KBIND *skbp;		/* saved pointer into the command table */

    /* if it's a simple character, it will be in the normal[] array */
    if (is8Bits(c)) {
	if (bs->kb_normal[CharOf(c)]) {
	    bs->kb_normal[CharOf(c)] = 0;
	    return TRUE;
	}
	return FALSE;
    }

    /* check first entry in kb_extra table */
    kbp = skbp = bs->kb_extra;
    if (kbp->k_code == c) {
	return free_KBIND(&(bs->kb_extra), kbp);
    }

    /* check kb_extra codes */
    while (kbp != bs->kb_special) {
	if (kbp->k_code == c) {
	    /* relink previous */
	    return free_KBIND(&(skbp->k_link), kbp);
	}

	skbp = kbp;
	kbp = kbp->k_link;
    }

    /* nope, check special codes */
    for (skbp = 0; kbp->k_cmd; kbp++) {
	if (!skbp && kbp->k_code == c)
	    skbp = kbp;
    }

    /* not found */
    if (!skbp)
	return FALSE;

    --kbp;			/* backup to the last legit entry */
    if (skbp != kbp) {
	/* copy the last entry to the current one */
	skbp->k_code = kbp->k_code;
	skbp->k_cmd = kbp->k_cmd;
    }

    /* null out the last one */
    kbp->k_code = 0;
    kbp->k_cmd = 0;

    return TRUE;
}

/*
 * removes a key from the table of bindings
 */
static int
unbind_any_key(BINDINGS * bs)
{
    int c;			/* command key to unbind */
    char outseq[NLINE];		/* output buffer for keystroke sequence */

    /* prompt the user to type in a key to unbind */
    mlprompt("Unbind this key sequence: ");

    /* get the command sequence to unbind */
    if (clexec) {
	if ((c = mac_token2kcod(TRUE)) < 0)
	    return FALSE;
    } else {
	c = kbd_seq();
	if (c < 0) {
	    mlforce("[Not a bindable key-sequence]");
	    return (FALSE);
	}
    }

    if (vl_msgs)
	kbd_puts(kcod2prc(c, outseq));

    if (unbindchar(bs, c) == FALSE) {
	mlforce("[Key not bound]");
	return (FALSE);
    }
    update_scratch(bs->bufname, update_binding_list);
    return (TRUE);
}

/* ARGSUSED */
int
unbindkey(int f GCC_UNUSED, int n GCC_UNUSED)
{
    return unbind_any_key(&dft_bindings);
}

/* ARGSUSED */
int
unbind_i_key(int f GCC_UNUSED, int n GCC_UNUSED)
{
    return unbind_any_key(&ins_bindings);
}

/* ARGSUSED */
int
unbind_c_key(int f GCC_UNUSED, int n GCC_UNUSED)
{
    return unbind_any_key(&cmd_bindings);
}

/* ARGSUSED */
int
unbind_s_key(int f GCC_UNUSED, int n GCC_UNUSED)
{
    return unbind_any_key(&sel_bindings);
}

/*
 * Prefix-keys can be only bound to one value. This procedure tests the
 * argument 'kcmd' to see if it is a prefix key, and if so, unbinds the
 * key, and sets the corresponding global variable to the new value.
 * The calling procedure will then do the binding per se.
 */
static void
reset_prefix(int c, const CMDFUNC * kcmd, BINDINGS * bs)
{
    if (isSpecialCmd(kcmd)) {
	int j;
	/* search for an existing binding for the prefix key */
	if ((j = fnc2kcod(kcmd)) >= 0)
	    (void) unbindchar(bs, j);
	/* reset the appropriate global prefix variable */
	if (kcmd == &f_cntl_a_func)
	    cntl_a = c;
	if (kcmd == &f_cntl_x_func)
	    cntl_x = c;
	if (kcmd == &f_poundc_func)
	    poundc = c;
	if (kcmd == &f_reptc_func)
	    reptc = c;
	if (kcmd == &f_esc_func)
	    esc_c = c;
    }
}

/*
 * Bind a command-function pointer to a given key-code (saving the old
 * value of the function-pointer via an pointer given by the caller).
 */
static int
install_bind(int c, const CMDFUNC * kcmd, BINDINGS * bs)
{
    KBIND *kbp;			/* pointer into a binding table */

    TRACE(("install_bind(%#x, %s(%s), %s)\n",
	   c, TRACE_CMDFUNC(kcmd), TRACE_BINDINGS(bs)));

    if (c < 0)
	return FALSE;		/* not a legal key-code */

    /* if the function is a prefix key, i.e. we're changing the definition
       of a prefix key, then they typed a dummy function name, which
       has been translated into a dummy function pointer */
    reset_prefix(-1, kcod2fnc(bs, c), bs);
    reset_prefix(c, kcmd, bs);

    if (is8Bits(c)) {
	bs->kb_normal[CharOf(c)] = TYPECAST(CMDFUNC, kcmd);
    } else if ((kbp = kcode2kbind(bs, c)) != 0) {	/* change it in place */
	kbp->k_cmd = kcmd;
    } else {

	beginDisplay();
	kbp = typealloc(KBIND);
	endofDisplay();

	if (kbp == 0) {
	    return no_memory("Key-Binding");
	}
	kbp->k_link = bs->kb_extra;
	kbp->k_code = c;	/* add keycode */
	kbp->k_cmd = kcmd;	/* and func pointer */
	bs->kb_extra = kbp;
    }
    update_scratch(bs->bufname, update_binding_list);
    return (TRUE);
}

/* ARGSUSED */
static int
bind_any_key(BINDINGS * bs)
{
    const CMDFUNC *kcmd;
    char cmd[NLINE];
    char *fnp;

    /* prompt the user to type in a key to bind */
    /* and get the function name to bind it to */
    fnp = kbd_engl("Bind function whose full name is: ", cmd, 0);

    if (fnp == NULL || (kcmd = engl2fnc(fnp)) == NULL) {
	return no_such_function(fnp);
    }

    return install_bind(key_to_bind(kcmd), kcmd, bs);
}

/*
 * bindkey:	add a new key to the key binding table
 */

/* ARGSUSED */
int
bindkey(int f GCC_UNUSED, int n GCC_UNUSED)
{
    return bind_any_key(&dft_bindings);
}

/* ARGSUSED */
int
bind_i_key(int f GCC_UNUSED, int n GCC_UNUSED)
{
    return bind_any_key(&ins_bindings);
}

/* ARGSUSED */
int
bind_c_key(int f GCC_UNUSED, int n GCC_UNUSED)
{
    return bind_any_key(&cmd_bindings);
}

/* ARGSUSED */
int
bind_s_key(int f GCC_UNUSED, int n GCC_UNUSED)
{
    return bind_any_key(&sel_bindings);
}

/* describe bindings bring up a fake buffer and list the key bindings
		   into it with view mode			*/

/* remember whether we last did "apropos" or "describe-bindings" */
static char *last_lookup_string;
static CMDFLAGS last_whichcmds;
static int last_whichmode;
static int append_to_binding_list;

/* ARGSUSED */
static int
update_binding_list(BUFFER *bp GCC_UNUSED)
{
    return liststuff(bindings_to_describe->bufname, append_to_binding_list,
		     makebindlist, (int) last_whichcmds, (void *) last_lookup_string);
}

static int
describe_any_bindings(char *lookup, CMDFLAGS whichcmd)
{
    last_lookup_string = lookup;
    last_whichcmds = whichcmd;

    return update_binding_list((BUFFER *) 0);
}

/* ARGSUSED */
int
desbind(int f GCC_UNUSED, int n GCC_UNUSED)
{
    return describe_any_bindings((char *) 0, (CMDFLAGS) 0);
}

/* ARGSUSED */
static int
update_bindkeys_list(BUFFER *bp GCC_UNUSED)
{
    return liststuff(bindings_to_describe->bufname, append_to_binding_list,
		     makebindkeyslist, (int) last_whichcmds, (void *) last_lookup_string);
}

static int
describe_all_bindings(char *lookup, CMDFLAGS whichcmd, int mode)
{
    last_lookup_string = lookup;
    last_whichcmds = whichcmd;
    last_whichmode = mode;

    return update_bindkeys_list((BUFFER *) 0);
}

/* ARGSUSED */
int
desall_bind(int f GCC_UNUSED, int n GCC_UNUSED)
{
    return describe_all_bindings((char *) 0, (CMDFLAGS) 0, (f ? n : -1));
}

static int
describe_all_keys_bindings(BINDINGS * bs, int mode)
{
    int code;
    bindings_to_describe = bs;
    code = describe_all_bindings((char *) 0, (CMDFLAGS) 0, mode);
    bindings_to_describe = &dft_bindings;
    return code;
}

int
desall_i_bind(int f GCC_UNUSED, int n GCC_UNUSED)
{
    return describe_all_keys_bindings(&ins_bindings, (f ? n : -1));
}

int
desall_c_bind(int f GCC_UNUSED, int n GCC_UNUSED)
{
    return describe_all_keys_bindings(&cmd_bindings, (f ? n : -1));
}

int
desall_s_bind(int f GCC_UNUSED, int n GCC_UNUSED)
{
    return describe_all_keys_bindings(&sel_bindings, (f ? n : -1));
}

static int
describe_alternate_bindings(BINDINGS * bs)
{
    int code;
    bindings_to_describe = bs;
    code = describe_any_bindings((char *) 0, (CMDFLAGS) 0);
    bindings_to_describe = &dft_bindings;
    return code;
}

int
des_i_bind(int f GCC_UNUSED, int n GCC_UNUSED)
{
    return describe_alternate_bindings(&ins_bindings);
}

int
des_c_bind(int f GCC_UNUSED, int n GCC_UNUSED)
{
    return describe_alternate_bindings(&cmd_bindings);
}

int
des_s_bind(int f GCC_UNUSED, int n GCC_UNUSED)
{
    return describe_alternate_bindings(&sel_bindings);
}

/* ARGSUSED */
int
desmotions(int f GCC_UNUSED, int n GCC_UNUSED)
{
    return describe_any_bindings((char *) 0, MOTION);
}

/* ARGSUSED */
int
desopers(int f GCC_UNUSED, int n GCC_UNUSED)
{
    return describe_any_bindings((char *) 0, OPER);
}

/* ARGSUSED */
int
desglobals(int f GCC_UNUSED, int n GCC_UNUSED)
{
    return describe_any_bindings((char *) 0, GLOBOK);
}

/* lookup function by substring */
/* ARGSUSED */
int
dessubstr(int f GCC_UNUSED, int n GCC_UNUSED)
{
    int s;
    static char substring[NSTRING];

    s = mlreply("Apropos string: ", substring, (UINT) sizeof(substring));
    if (s != TRUE)
	return (s);

    return describe_any_bindings(substring, (CMDFLAGS) 0);
}

static char described_cmd[NLINE + 1];	/* string to match cmd names to */

/* lookup up function by name */
/* ARGSUSED */
int
desfunc(int f GCC_UNUSED, int n GCC_UNUSED)
{
    int s;
    char *fnp;

    /* force an exact match by ourstrstr() later on from makefuncdesc() */
    described_cmd[0] = '^';

    fnp = kbd_engl("Describe function whose full name is: ",
		   described_cmd + 1, 0);
    if (fnp == NULL || engl2fnc(fnp) == NULL) {
	s = no_such_function(fnp);
    } else {
	append_to_binding_list = TRUE;
	s = describe_any_bindings(described_cmd, (CMDFLAGS) 0);
	append_to_binding_list = FALSE;
    }
    return s;
}

/* FIXME: this table should be generated from cmdtbl, but excluding the
 * mouse and text pseudo-keys.  Note that the table isn't really
 * sorted alphabetically, so it would be hard to generate in a nice way.
 */
static void
make_key_names(int iarg GCC_UNUSED, void *varg GCC_UNUSED)
{
    static const struct {
	int code;
	const char *name;
    } table[] = {
	/* *INDENT-OFF* */
	{ KEY_Up,	   "KEY_Up" },
	{ KEY_Down,	   "KEY_Down" },
	{ KEY_Right,	   "KEY_Right" },
	{ KEY_Left,	   "KEY_Left" },
	{ 0,		   0 },
	{ KEY_Delete,	   "KEY_Delete" },
	{ KEY_End,	   "KEY_End" },
	{ KEY_Find,	   "KEY_Find" },
	{ KEY_Help,	   "KEY_Help" },
	{ KEY_Home,	   "KEY_Home" },
	{ KEY_Insert,	   "KEY_Insert" },
	{ KEY_Menu,	   "KEY_Menu" },
	{ KEY_Next,	   "KEY_Next" },
	{ KEY_Prior,	   "KEY_Prior" },
	{ KEY_Select,	   "KEY_Select" },
	{ KEY_BackTab,	   "KEY_BackTab" },
	{ 0,		   0 },
	{ KEY_F1,	   "KEY_F1" },
	{ KEY_F2,	   "KEY_F2" },
	{ KEY_F3,	   "KEY_F3" },
	{ KEY_F4,	   "KEY_F4" },
	{ KEY_F5,	   "KEY_F5" },
	{ KEY_F6,	   "KEY_F6" },
	{ KEY_F7,	   "KEY_F7" },
	{ KEY_F8,	   "KEY_F8" },
	{ KEY_F9,	   "KEY_F9" },
	{ KEY_F10,	   "KEY_F10" },
	{ KEY_F11,	   "KEY_F11" },
	{ KEY_F12,	   "KEY_F12" },
	{ KEY_F13,	   "KEY_F13" },
	{ KEY_F14,	   "KEY_F14" },
	{ KEY_F15,	   "KEY_F15" },
	{ KEY_F16,	   "KEY_F16" },
	{ KEY_F17,	   "KEY_F17" },
	{ KEY_F18,	   "KEY_F18" },
	{ KEY_F19,	   "KEY_F19" },
	{ KEY_F20,	   "KEY_F20" },
	{ KEY_F21,	   "KEY_F21" },
	{ KEY_F22,	   "KEY_F22" },
	{ KEY_F23,	   "KEY_F23" },
	{ KEY_F24,	   "KEY_F24" },
	{ KEY_F25,	   "KEY_F25" },
	{ KEY_F26,	   "KEY_F26" },
	{ KEY_F27,	   "KEY_F27" },
	{ KEY_F28,	   "KEY_F28" },
	{ KEY_F29,	   "KEY_F29" },
	{ KEY_F30,	   "KEY_F30" },
	{ KEY_F31,	   "KEY_F31" },
	{ KEY_F32,	   "KEY_F32" },
	{ KEY_F33,	   "KEY_F33" },
	{ KEY_F34,	   "KEY_F34" },
	{ KEY_F35,	   "KEY_F35" },
	{ 0,		   0 },
	{ KEY_KP_F1,	   "KEY_KP_F1" },
	{ KEY_KP_F2,	   "KEY_KP_F2" },
	{ KEY_KP_F3,	   "KEY_KP_F3" },
	{ KEY_KP_F4,	   "KEY_KP_F4" },
	/* *INDENT-ON* */

    };
    unsigned n;
    char temp[80];

    bprintf("Coding for function and cursor-keys (your terminal may not support all):\n");
    for (n = 0; n < TABLESIZE(table); n++) {
	bputc('\n');
	if (table[n].code != 0)
	    bprintf("%s\t%s", kcod2prc(table[n].code, temp), table[n].name);
    }
}

int
des_keynames(int f GCC_UNUSED, int n GCC_UNUSED)
{
    return liststuff(KEY_NAMES_BufName, FALSE, make_key_names, 0, (void *) 0);
}

/* lookup up function by key */
/* ARGSUSED */
static int
prompt_describe_key(BINDINGS * bs)
{
    int c;			/* character to describe */
    char outseq[NSTRING];	/* output buffer for command sequence */
    NTAB temp;			/* name table pointer */
    int s;

    /* prompt the user to type us a key to describe */
    mlprompt("Describe the function bound to this key sequence: ");

    /* check to see if we are executing a command line */
    if (clexec) {
	if ((c = mac_token2kcod(TRUE)) < 0)
	    return (FALSE);
    } else {
	c = kbd_seq_nomap();
	if (c < 0) {
	    mlforce("[Not a bindable key-sequence]");
	    return (FALSE);
	}
    }

    (void) kcod2prc(c, outseq);
    hst_append_s(outseq, FALSE, TRUE);	/* cannot replay this, but can see it */

    /* find the function bound to the key */
    if (!fnc2ntab(&temp, kcod2fnc(bs, c))) {
	mlwrite("Key sequence '%s' is not bound to anything.",
		outseq);
	return TRUE;
    }

    /* describe it */
    described_cmd[0] = '^';
    (void) vl_strncpy(described_cmd + 1, temp.n_name, sizeof(described_cmd));
    append_to_binding_list = TRUE;
    s = describe_any_bindings(described_cmd, (CMDFLAGS) 0);
    append_to_binding_list = FALSE;

    mlwrite("Key sequence '%s' is bound to function \"%s\"",
	    outseq, temp.n_name);

    return s;
}

int
deskey(int f GCC_UNUSED, int n GCC_UNUSED)
{
    return prompt_describe_key(&dft_bindings);
}

int
des_i_key(int f GCC_UNUSED, int n GCC_UNUSED)
{
    return prompt_describe_key(&ins_bindings);
}

int
des_c_key(int f GCC_UNUSED, int n GCC_UNUSED)
{
    return prompt_describe_key(&cmd_bindings);
}

int
des_s_key(int f GCC_UNUSED, int n GCC_UNUSED)
{
    return prompt_describe_key(&sel_bindings);
}

/* returns a name in double-quotes */
static char *
quoted(char *dst, const char *src)
{
    char *result = 0;
    if (dst != 0) {
	result = strcat(strcat(strcpy(dst, "\""), src), "\"");
    } else {
	char temp[NLINE];
	bputsn_xcolor(quoted(temp, src), -1, XCOLOR_STRING);
    }
    return result;
}

/* returns the number of columns used by the given string */
static unsigned
converted_len(char *buffer)
{
    unsigned len = 0, c;
    while ((c = CharOf(*buffer++)) != EOS) {
	if (c == '\t')
	    len |= 7;
	len++;
    }
    return len;
}

static void
quote_and_pad(char *dst, const char *src)
{
    quoted(dst, src);
    if (dst != 0) {
	if (converted_len(dst) >= 32)
	    strcat(dst, "\t");
	else
	    while (converted_len(dst) < 32)
		strcat(dst, "\t");
    } else {
	do {
	    bputc('\t');
	} while (getccol(FALSE) < 32);
    }
}

#if OPT_MENUS || OPT_NAMEBST
/* force the buffer to a tab-stop if needed */
static char *
to_tabstop(char *buffer)
{
    size_t len = strlen(buffer);
    unsigned cpos = converted_len(buffer);
    if (cpos & 7 || (len != 0 && !isBlank(buffer[len - 1])))
	(void) strcat(buffer, "\t");
    return skip_string(buffer);
}

/* convert a key binding, padding to the next multiple of 8 columns */
static void
convert_kcode(int c, char *buffer)
{
    if (buffer != 0) {
	(void) kcod2prc(c, to_tabstop(buffer));
    } else {
	char temp[NLINE];
	if (llength(DOT.l) > 0
	    && !isBlank(lvalue(DOT.l)[llength(DOT.l) - 1])) {
	    bputc('\t');
	}
	(void) kcod2prc(c, temp);
	bputsn_xcolor(temp, -1, XCOLOR_STRING);
    }
}

static void
convert_cmdfunc(BINDINGS * bs, const CMDFUNC * cmd, char *outseq)
{
    int i;
    KBIND *kbp;

    /* look in the simple ascii binding table first */
    for (i = 0; i < N_chars; i++)
	if (bs->kb_normal[i] == cmd)
	    convert_kcode(i, outseq);

    /* then look in the multi-key table */
#if OPT_REBIND
    for (kbp = bs->kb_extra; kbp != bs->kb_special; kbp = kbp->k_link) {
	if (kbp->k_cmd == cmd)
	    convert_kcode(kbp->k_code, outseq);
    }
#endif
    for (kbp = bs->kb_special; kbp->k_cmd; kbp++)
	if (kbp->k_cmd == cmd)
	    convert_kcode(kbp->k_code, outseq);
}
#endif /* OPT_MENUS || OPT_NAMEBST */

static int
add_newline(void)
{
    int rc = TRUE;
    if (buf_head(curbp) != DOT.l)
	rc = bputc('\n');
    return rc;
}

static int
add_line(const char *text)
{
    int rc = add_newline();
    if (rc)
	rc = bputsn(text, -1);
    return rc;
}

#if OPT_ONLINEHELP
static int
show_onlinehelp(const CMDFUNC * cmd)
{
    char outseq[NLINE];		/* output buffer for text */
    const char *text = cmd->c_help;
    CMDFLAGS flags = cmd->c_flags;

    if (text && *text) {
	if (*text == SQUOTE)
	    text++;
	(void) lsprintf(outseq, "  (%s %s )",
			(cmd->c_flags & MOTION) ? " motion: " :
			(cmd->c_flags & OPER) ? " operator: " : "",
			text);
    } else {
	(void) lsprintf(outseq, "  ( no help for this command )");
    }
    if (!add_line(outseq))
	return FALSE;
#if OPT_PROCEDURES
    if ((cmd->c_flags & CMD_TYPE) == CMD_PROC)
	flags &= ~(UNDO | REDO);
#endif
#if OPT_PERL
    if ((cmd->c_flags & CMD_TYPE) == CMD_PERL)
	flags &= ~(UNDO | REDO);
#endif
    if (flags & (RANGE | UNDO | REDO | GLOBOK)) {
	const char *gaps = "";
	char *next;

	next = lsprintf(outseq, "  ( ");
	if (cmd->c_flags & (UNDO | REDO)) {
	    {
		next = lsprintf(next, "undoable");
		gaps = ", ";
	    }
	}
	if (cmd->c_flags & RANGE) {
	    next = lsprintf(next, "%saccepts range", gaps);
	    gaps = ", ";
	}
	if (cmd->c_flags & GLOBOK) {
	    next = lsprintf(next, "%smay follow global command", gaps);
	}
	(void) lsprintf(next, " )");
	if (!add_line(outseq))
	    return FALSE;
    }
#if OPT_MACRO_ARGS
    if (cmd->c_args != 0) {
	int i;
	for (i = 0; cmd->c_args[i].pi_type != PT_UNKNOWN; i++) {
	    (void) lsprintf(outseq, "  ( $%d = %s )", i + 1,
			    (cmd->c_args[i].pi_text != 0)
			    ? cmd->c_args[i].pi_text
			    : choice_to_name(&fsm_paramtypes_blist,
					     cmd->c_args[i].pi_type));
	    if (!add_line(outseq))
		return FALSE;
	}
    }
#endif
    return TRUE;
}
#endif

#if OPT_NAMEBST
struct bindlist_data {
    UINT mask;			/* oper/motion mask */
    int min;			/* minimum key length */
    char *apropos;		/* key check */
    BINDINGS *bs;
};

static int
btree_walk(BI_NODE * node, int (*func) (BI_NODE *, const void *),
	   const void *data)
{
    if (node) {
	if (btree_walk(BI_LEFT(node), func, data))
	    return 1;

	if (BI_KEY(node))
	    func(node, data);

	if (btree_walk(BI_RIGHT(node), func, data))
	    return 1;
    }

    return 0;
}

static int
clearflag_func(BI_NODE * n, const void *d GCC_UNUSED)
{
    clr_typed_flags(n->value.n_flags, UCHAR, NBST_DONE);
    return 0;
}

#define isShortCmd(s) ((int) strlen(s) <= SHORT_CMD_LEN)

static int
makebind_func(BI_NODE * node, const void *d)
{
    const struct bindlist_data *data = (const struct bindlist_data *) d;
    const CMDFUNC *cmd = node->value.n_cmd;
    int n;

    /* has this been listed? */
    if (node->value.n_flags & NBST_DONE)
	return 0;

    /* are we interested in this type of command? */
    if (data->mask && !(cmd->c_flags & data->mask))
	return 0;

    /* try to avoid alphabetizing by the real short names */
    if (data->min && isShortCmd(BI_KEY(node)))
	return 0;

    /* failed lookup by substring? */
    if (data->apropos && !ourstrstr(BI_KEY(node), data->apropos, TRUE))
	return 0;

    /* add in the command name */
    quote_and_pad(0, BI_KEY(node));
    convert_cmdfunc(data->bs, cmd, 0);

    node->value.n_flags |= NBST_DONE;

    if (cmd->c_alias != 0) {
	const char *top = BI_KEY(node);
	const char *name;
	for (n = 0; (name = cmd->c_alias[n]) != 0; ++n) {
	    if (data->min) {
		if ((isShortCmd(name)
		     || ((strcmp(name, top) > 0)
			 && !isShortCmd(top)))
		    && add_newline()
		    && bputsn("  or\t", -1)) {
		    quoted(0, name);
		}
	    } else {
		if ((isShortCmd(name)
		     && isShortCmd(top)
		     && strcmp(name, top) > 0)
		    && add_newline()
		    && bputsn("  or\t", -1)) {
		    quoted(0, name);
		}
	    }
	}
    }
#if OPT_ONLINEHELP
    if (!show_onlinehelp(cmd))
	return FALSE;
#endif
    /* blank separator */
    if (!add_line(""))
	return 1;

    return 0;
}

/* build a binding list (limited or full) */
/* ARGSUSED */
static void
makebindlist(int whichmask, void *mstring)
{
    BI_TREE *my_bst = bst_current();
    struct bindlist_data data;

    data.mask = (UINT) whichmask;
    data.min = SHORT_CMD_LEN;
    data.apropos = (char *) mstring;
    data.bs = bindings_to_describe;

    /* let us know this is in progress */
    mlwrite("[Building binding list]");

    /* clear the NBST_DONE flag */
    btree_walk(&(my_bst->head), clearflag_func, 0);

    /* create binding list */
    if (btree_walk(&(my_bst->head), makebind_func, &data))
	return;

    /* catch entries with no synonym > SHORT_CMD_LEN */
    data.min = 0;
    if (btree_walk(&(my_bst->head), makebind_func, &data))
	return;

    mlerase();			/* clear the message line */
}

/* build a binding list (limited or full) */
/* ARGSUSED */
static void
makebindkeyslist(int whichmask, void *mstring)
{
    char outseq[NSTRING];	/* output buffer for command sequence */
    NTAB temp;			/* name table pointer */
    int ch;
    int state;

    (void) mstring;

    /* let us know this is in progress */
    mlwrite("[Building binding list]");
    for (state = 0; state < 3; ++state) {
	int modify = 0;
	int found = 0;
	const char *what = "?";
	switch (state) {
	case 0:
	    what = "Normal keys";
	    break;
	case 1:
	    what = "^A-keys";
	    modify = CTLA;
	    break;
	case 2:
	    what = "^X-keys";
	    modify = CTLX;
	    break;
	}
	bprintf("%s-- %s", state ? "\n\n" : "", what);
	for (ch = 0; ch < N_chars; ++ch) {
	    (void) kcod2prc(ch + modify, outseq);
	    if (fnc2ntab(&temp, kcod2fnc(bindings_to_describe, ch + modify))) {
		if (whichmask && !(temp.n_cmd->c_flags & (CMDFLAGS) whichmask))
		    continue;
		bputc('\n');
		bprintf("%d\t%s\t", ch, outseq);
		quoted(0, temp.n_name);
		++found;
	    } else if (last_whichmode > 1) {
		bputc('\n');
		bprintf("%d\t%s", ch, outseq);
	    }
	}
	if (found) {
	    bprintf("\n-- %s total: %d", what, found);
	}
    }
    mlerase();			/* clear the message line */
}
#else /* OPT_NAMEBST */
/* fully describe a function into the current buffer, given a pointer to
 * its name table entry */
static int
makefuncdesc(int j, char *listed)
{
    int i;
    const CMDFUNC *cmd = nametbl[j].n_cmd;
    char outseq[NLINE];		/* output buffer for keystroke sequence */

    /* add in the command name */
    quote_and_pad(outseq, nametbl[j].n_name);

    /* dump the line */
    if (!add_line(outseq))
	return FALSE;

    /* then look for synonyms */
    (void) strcpy(outseq, "  or\t");
    for (i = 0; nametbl[i].n_name != 0; i++) {
	/* if it's the one we're on, skip */
	if (i == j)
	    continue;
	/* if it's already been listed, skip */
	if (listed[i])
	    continue;
	/* if it's not a synonym, skip */
	if (nametbl[i].n_cmd != cmd)
	    continue;
	(void) quoted(outseq + 5, nametbl[i].n_name);
	if (!add_line(outseq))
	    return FALSE;
    }

#if OPT_ONLINEHELP
    if (!show_onlinehelp(cmd))
	return FALSE;
#endif
    /* blank separator */
    if (!add_line(""))
	return FALSE;

    return TRUE;
}

/* build a binding list (limited or full) */
/* ARGSUSED */
static void
makebindlist(int whichmask, void *mstring)
{
    int pass;
    int j;
    int ok = TRUE;		/* reset if out-of-memory, etc. */
    char *listed;

    beginDisplay();
    listed = typecallocn(char, (size_t) nametbl_size);
    endofDisplay();

    if (listed == 0) {
	(void) no_memory(bindings_to_describe->bufname);
	return;
    }

    /* let us know this is in progress */
    mlwrite("[Building binding list]");

    /* build the contents of this window, inserting it line by line */
    for (pass = 0; pass < 2; pass++) {
	for (j = 0; nametbl[j].n_name != 0; j++) {

	    /* if we've already described this one, move on */
	    if (listed[j])
		continue;

	    /* are we interested in this type of command? */
	    if (whichmask && !(nametbl[j].n_cmd->c_flags & whichmask))
		continue;

	    /* try to avoid alphabetizing by the real short names */
	    if (pass == 0 && (int) strlen(nametbl[j].n_name) <= SHORT_CMD_LEN)
		continue;

	    /* if we are executing an apropos command
	       and current string doesn't include the search string */
	    if (mstring
		&& !ourstrstr(nametbl[j].n_name, (char *) mstring, TRUE))
		continue;

	    ok = makefuncdesc(j, listed);
	    if (!ok)
		break;

	    listed[j] = TRUE;	/* mark it as already listed */
	}
    }

    if (ok)
	mlerase();		/* clear the message line */

    beginDisplay();
    free(listed);
    endofDisplay();
}
#endif /* OPT_NAMEBST */

#endif /* OPT_REBIND */

#if OPT_REBIND || OPT_EVAL
/* much like the "standard" strstr, but if the substring starts
	with a '^', we discard it and force an exact match.
	returns 1-based offset of match, or 0.  */
int
ourstrstr(const char *haystack, const char *needle, int anchor)
{
    if (anchor && *needle == '^') {
	return strcmp(needle + 1, haystack) ? 0 : 1;
    } else {
	size_t nl = strlen(needle);
	size_t hl = strlen(haystack);
	const char *hp = haystack;
	while (hl >= nl && *hp) {
	    if (!strncmp(hp, needle, nl))
		return (int) (hp - haystack + 1);
	    hp++;
	    hl--;
	}
	return 0;
    }
}
#endif /* OPT_REBIND || OPT_EVAL */

#if SYS_UNIX
/*
 * Only source a startup file on Unix if it (and the directory in which it
 * resides) happens to be in a directory owned by the current user (or root),
 * and neither is writable by other users.
 */
static int
is_our_file(char *fname, int check_owner)
{
    int status = FALSE;
    struct stat sb;

    if (stat(fname, &sb) == 0) {
	if ((sb.st_mode & 002) != 0) {
	    TPRINTF(("Ignoring world-writable \"%s\"\n", fname));
	} else if ((sb.st_mode & 020) != 0) {
	    TPRINTF(("Ignoring group-writable \"%s\"\n", fname));
	} else if (check_owner
		   && (sb.st_uid != getuid() && sb.st_uid != 0)) {
	    TPRINTF(("\"%s\" is not our %s\n",
		     fname, S_ISDIR(sb.st_mode) ? "directory" : "file"));
	} else {
	    status = TRUE;
	}
    } else {
	TPRINTF(("\"%s\": %s\n", fname, strerror(errno)));
    }
    return status;
}
#endif

static int
check_file_access(char *fname, UINT mode)
{
    int result = ffaccess(fname, mode);

    TRACE((T_CALLED "check_file_access(%s, %#x) = %d\n", fname, mode, result));
#if SYS_UNIX
#define CHK_OWNER (FL_HOME | FL_CDIR)
    if (result) {
	int doit = FALSE;
	int owner;
#ifdef GVAL_CHK_ACCESS
	int check;
#endif

	/*
	 * Suppress ownership check for absolute pathnames.
	 */
	if (is_abs_pathname(fname))
	    mode &= ~CHK_OWNER;

	/*
	 * Check ownership for current- and home-directories.
	 */
	owner = (mode < (CHK_OWNER * 2));

	if (mode & FL_EXECABLE) {
	    doit = TRUE;
	}
#ifdef GVAL_CHK_ACCESS
	else if ((check = global_g_val(GVAL_CHK_ACCESS)) != 0) {
	    /*
	     * The values for check-access mode are single bits.  But we treat
	     * those as an ordered list.  Hence, setting "home" implies we
	     * also check "current", since that is the first item in the list.
	     */
	    if ((mode & FL_ALWAYS) && !((UINT) check & FL_ALWAYS)) {
		doit = FALSE;
	    } else if ((mode
			& ((UINT) check * 2 - 1)
			& ~(FL_EXECABLE | FL_WRITEABLE | FL_READABLE)) != 0) {
		doit = TRUE;
	    }
	}
#endif

	if (doit && !(mode & FL_INSECURE)) {
	    char *dname = (char *) malloc(NFILEN + strlen(fname) + 10);
	    char *leaf;

	    if (dname != 0) {
		leaf = pathleaf(lengthen_path(strcpy(dname, fname)));
		if ((leaf - 1) != dname)
		    *--leaf = EOS;
		if (!is_our_file(dname, owner) || !is_our_file(fname, owner)) {
		    mlforce("[Skipping '%s' (insecure permissions)]", fname);
		    result = ABORT;
		}
		free(dname);
	    }
	}
    }
#endif

    returnCode(result);
}

static char *
locate_fname(char *dir_name, char *fname, UINT mode)
{
    static char fullpath[NFILEN];	/* expanded path */

    if (!isEmpty(dir_name)
	&& check_file_access(pathcat(fullpath, dir_name, fname), mode) == TRUE)
	return (fullpath);

    return 0;
}

static char *
locate_file_in_list(char *list, char *fname, UINT mode)
{
    const char *cp;
    char *sp;
    char dir_name[NFILEN];
    int first = TRUE;

    if ((cp = list) != 0) {
	while ((cp = parse_pathlist(cp, dir_name, &first)) != 0) {
	    if ((sp = locate_fname(dir_name, fname, mode)) != 0)
		return sp;
	}
    }
    return 0;
}

#if OPT_PATHLOOKUP
#if SYS_VMS
static char *
PATH_value(void)
{
    /* On VAX/VMS, the PATH environment variable is only the
     * current-dir.  Fake up an acceptable alternative.
     */

    static TBUFF *myfiles;
    char *tmp;

    if (!tb_length(myfiles)) {
	char mypath[NFILEN];

	(void) vl_strncpy(mypath, NONNULL(prog_arg), sizeof(mypath));
	if ((tmp = vms_pathleaf(mypath)) == mypath) {
	    (void) vl_strncpy(mypath, current_directory(FALSE), sizeof(mypath));
	} else {
	    *tmp = EOS;
	}

	if (!tb_init(&myfiles, EOS)
	    || !tb_sappend(&myfiles, mypath)
	    || !tb_sappend(&myfiles,
			   ",SYS$SYSTEM:,SYS$LIBRARY:")
	    || !tb_append(&myfiles, EOS))
	    return NULL;
    }
    return tb_values(myfiles);
}
#else /* UNIX or MSDOS */
#define PATH_value() getenv("PATH")
#endif
#endif /* OPT_PATHLOOKUP */

/* config files that vile is interested in may live in various places,
 * and which may be constrained to various r/w/x modes.  the files may
 * be
 *  in the current directory,
 *  in the HOME directory,
 *  along a special "path" variable called "VILE_STARTUP_PATH",
 *  they may be in the directory where we found the vile executable itself,
 *  or they may be along the user's PATH.
 * in addition, they may be readable, writeable, or executable.
 */

char *
cfg_locate(char *fname, UINT which)
{
    char *sp;
    UINT mode = (which & (FL_ALWAYS |
			  FL_EXECABLE |
			  FL_WRITEABLE |
			  FL_READABLE |
			  FL_INSECURE));

#define FL_BIT(name) ((which & FL_##name) ? " " #name : "")
    TRACE((T_CALLED "cfg_locate('%s',%s%s%s%s%s%s%s%s%s%s%s)\n", NonNull(fname),
	   FL_BIT(EXECABLE),
	   FL_BIT(WRITEABLE),
	   FL_BIT(READABLE),
	   FL_BIT(CDIR),
	   FL_BIT(HOME),
	   FL_BIT(EXECDIR),
	   FL_BIT(STARTPATH),
	   FL_BIT(PATH),
	   FL_BIT(LIBDIR),
	   FL_BIT(ALWAYS),
	   FL_BIT(INSECURE)));

    /* take care of special cases */
    if (!fname || !fname[0] || isSpace(fname[0]))
	returnString(NULL);
    else if (isShellOrPipe(fname))
	returnString(fname);

    /* look in the current directory */
    if (which & FL_CDIR) {
	if (check_file_access(fname, FL_CDIR | mode) == TRUE) {
	    returnString(fname);
	}
    }

    if ((which & FL_HOME)	/* look in the home directory */
	&&((sp = locate_fname(home_dir(), fname, FL_HOME | mode)) != 0))
	returnString(sp);

    if ((which & FL_EXECDIR)	/* look in vile's bin directory */
	&&((sp = locate_fname(exec_pathname, fname, FL_EXECDIR | mode)) != 0))
	returnString(sp);

    if ((which & FL_STARTPATH)	/* look along "VILE_STARTUP_PATH" */
	&&(sp = locate_file_in_list(startup_path,
				    fname,
				    FL_STARTPATH | mode)) != 0)
	returnString(sp);

    if (which & FL_PATH) {	/* look along "PATH" */
#if OPT_PATHLOOKUP
	if ((sp = locate_file_in_list(PATH_value(),
				      fname,
				      FL_PATH | mode)) != 0)
	    returnString(sp);
#endif /* OPT_PATHLOOKUP */

    }

    if ((which & FL_LIBDIR)	/* look along "VILE_LIBDIR_PATH" */
	&&(sp = locate_file_in_list(libdir_path,
				    fname,
				    FL_LIBDIR | mode)) != 0)
	returnString(sp);

    returnString(NULL);
}

#if OPT_SHOW_WHICH
static int
ask_which_file(char *fname)
{
    static TBUFF *last;

    return mlreply_file("Which file: ", &last,
			FILEC_READ | FILEC_PROMPT, fname);
}

static void
list_one_fname(char *fname, UINT mode)
{
    int tag = check_file_access(fname, mode);

    bprintf("\n%s\t", ((tag == ABORT)
		       ? "?"
		       : ((tag == TRUE)
			  ? "*"
			  : "")));

#if OPT_HYPERTEXT
    if (tag == TRUE) {
	REGION myRegion;
	MARK myDot;
	TBUFF *myBuff = 0;
	TBUFF *myFile = 0;

	memset(&myRegion, 0, sizeof(myRegion));
	myRegion.r_orig = DOT;
	bprintf("%s", fname);
	myRegion.r_end = DOT;

	tb_scopy(&myBuff, "view ");
	path_quote(&myFile, fname);
	bsl_to_sl_inplace(tb_values(myFile));
	tb_sappend0(&myBuff, tb_values(myFile));

	myDot = DOT;
	attributeregion_in_region(&myRegion,
				  rgn_EXACT,
				  VAREV,
				  tb_values(myBuff));
	tb_free(&myBuff);
	tb_free(&myFile);
	DOT = myDot;
    } else
#endif
	bprintf("%s", fname);
}

static void
list_which_fname(char *dir_name, char *fname, UINT mode)
{
    char fullpath[NFILEN];	/* expanded path */

    if (!isEmpty(dir_name)) {
	list_one_fname(SL_TO_BSL(pathcat(fullpath, dir_name, fname)), mode);
    }
}

static void
list_which_file_in_list(char *list, char *fname, UINT mode)
{
    const char *cp;
    char dir_name[NFILEN];
    int first = TRUE;

    if ((cp = list) != 0) {
	while ((cp = parse_pathlist(cp, dir_name, &first)) != 0) {
	    list_which_fname(dir_name, fname, mode);
	}
    }
}

static void
list_which(LIST_ARGS)
{
    UINT uflag = (UINT) flag;
    char *fname = (char *) ptr;
    UINT mode = (uflag & (FL_EXECABLE | FL_WRITEABLE | FL_READABLE));

    /* take care of special cases */
    if (!fname || !fname[0] || isSpace(fname[0]))
	return;
    else if (isShellOrPipe(fname))
	return;

    bprintf("Show which %s-paths are tested for:\n\t%s\n(\"*\" marks found-files)\n",
	    (mode & FL_EXECABLE) ? "executable" : "source",
	    fname);

    /* look in the current directory */
    if (uflag & FL_CDIR) {
	bprintf("\n$cwd");
	list_one_fname(fname, FL_CDIR | mode);
    }

    if (uflag & FL_HOME) {	/* look in the home directory */
	bprintf("\n$HOME");
	list_which_fname(home_dir(), fname, FL_HOME | mode);
    }

    if (uflag & FL_EXECDIR) {	/* look in vile's bin directory */
	bprintf("\n$exec-path");
	list_which_fname(exec_pathname, fname, FL_EXECDIR | mode);
    }

    if (uflag & FL_STARTPATH) {	/* look along "VILE_STARTUP_PATH" */
	bprintf("\n$startup-path");
	list_which_file_in_list(startup_path, fname, FL_STARTPATH | mode);
    }

    if (uflag & FL_PATH) {	/* look along "PATH" */
#if OPT_PATHLOOKUP
	bprintf("\n$PATH");
	list_which_file_in_list(PATH_value(), fname, FL_PATH | mode);
#endif /* OPT_PATHLOOKUP */

    }

    if (uflag & FL_LIBDIR) {	/* look along "VILE_LIBDIR_PATH" */
	bprintf("\n$libdir-path");
	list_which_file_in_list(libdir_path, fname, FL_LIBDIR | mode);
    }
}

static int
show_which_file(char *fname, UINT mode, int f, int n)
{
    char *result;
    if ((result = cfg_locate(fname, mode)) != 0) {
	mlwrite("%s", result);
    }
    if (f)
	liststuff(WHICH_BufName, n > 2, list_which, (int) mode, fname);
    return (result != 0);
}

int
which_source(int f, int n)
{
    int s;
    char fname[NFILEN];

    if ((s = ask_which_file(fname)) == TRUE) {
	s = show_which_file(fname, LOCATE_SOURCE, f, n);
    }
    return s;
}

int
which_exec(int f, int n)
{
    int s;
    char fname[NFILEN];

    if ((s = ask_which_file(fname)) == TRUE) {
	s = show_which_file(fname, LOCATE_EXEC, f, n);
    }
    return s;
}
#endif

/*
 * Translate a keycode to its binding-string.
 * seq[0] gets the length of the result.
 */
char *
kcod2pstr(int c, char *seq, int limit)
{
    seq[0] = (char) kcod2escape_seq(c, &seq[1], (size_t) limit - 1);
    return seq;
}

#if OPT_KEY_MODIFY
static const struct {
    const char *name;
    int code;
} key_modifiers[] = {

    {
	"Alt+", mod_ALT
    },
    {
	"Ctrl+", mod_CTRL
    },
    {
	"Shift+", mod_SHIFT
    },
};
#endif

#define ADD_KCODE(src) \
	if (((size_t) (ptr - base) + (len = strlen(src)) + need + 2) < limit) { \
	    strcpy(ptr, src); \
	    ptr += len; \
	}

/* Translate a 16-bit keycode to a string that will replay into the same
 * code.
 */
int
kcod2escape_seq(int c, char *ptr, size_t limit)
{
    char *base = ptr;
    char temp[20];
    size_t need;

#if OPT_MULTIBYTE
    int ch = (c & ((1 << MaxCBits) - 1));
    const char *s;

    if ((ch >= 256)
	&& (cmd_encoding >= enc_UTF8
	    || (cmd_encoding <= enc_AUTO && okCTYPE2(vl_wide_enc)))
	&& (s = vl_mb_to_utf8(ch)) != 0) {
	vl_strncpy(temp, s, sizeof(temp));
    } else
#endif
    {
	temp[0] = (char) c;
	temp[1] = EOS;
    }
    need = strlen(temp);

    if (base != 0 && limit > (4 + need)) {
	if ((UINT) c & CTLA)
	    *ptr++ = (char) cntl_a;
	else if ((UINT) c & CTLX)
	    *ptr++ = (char) cntl_x;

#if OPT_KEY_MODIFY
	if ((UINT) c & mod_KEY) {
	    size_t len;
	    unsigned n;
	    for (n = 0; n < TABLESIZE(key_modifiers); ++n) {
		if (c & key_modifiers[n].code) {
		    ADD_KCODE(key_modifiers[n].name);
		}
	    }
#if SYS_WINNT
#define W32INSERT "Insert"
#define W32DELETE "Delete"
	    c &= mod_NOMOD;
	    if (c == KEY_Insert) {
		ADD_KCODE(W32INSERT);
		c = EOS;
	    } else if (c == KEY_Delete) {
		ADD_KCODE(W32DELETE);
		c = EOS;
	    }
#endif
	}
#endif
	if ((UINT) c & SPEC)
	    *ptr++ = (char) poundc;
	strcpy(ptr, temp);
	ptr += need;
    }
    return (int) (ptr - base);
}

/* translates a binding string into printable form */
#if OPT_REBIND
static char *
bytes2prc(char *dst, char *src, int n)
{
    char *base = dst;
    int c;
    const char *tmp;

    for (; n != 0; dst++, src++, n--) {

	c = *src;

	tmp = 0;

	if (c & HIGHBIT) {
	    *dst++ = 'M';
	    *dst++ = '-';
	    c &= ~HIGHBIT;
	}
	if (c == ' ') {
	    tmp = "";
	} else if (isCntrl(c)) {
	    *dst++ = '^';
	    *dst = (char) tocntrl(c);
	} else {
	    *dst = (char) c;
	}

	if (tmp != 0) {
	    while ((*dst++ = *tmp++) != EOS) {
		;
	    }
	    dst -= 2;		/* point back to last nonnull */
	}

	if (n > 1) {
	    *++dst = '-';
	}
    }
    *dst = EOS;
    return base;
}

/* translate a 10-bit keycode to its printable name (like "M-j")  */
char *
kcod2prc(int c, char *seq)
{
    char temp[NSTRING];
    int length;

    length = kcod2pstr(c, temp, (int) sizeof(temp))[0];
#if OPT_KEY_MODIFY
    if (((UINT) c & mod_KEY) != 0 && (length != 0)) {
	(void) strcpy(seq, temp + 1);
	if (length < (int) (1 + strlen(temp + 1) + (size_t) (CharOf(c) == 0))) {
	    (void) bytes2prc(seq + length - 1, temp + length, 1);
	}
    } else
#endif
	(void) bytes2prc(seq, temp + 1, length);
    TRACE2(("kcod2prc(%#x) ->%s\n", c, seq));
    return seq;
}
#endif

static int
cmdfunc2keycode(BINDINGS * bs, const CMDFUNC * f)
{
    KBIND *kbp;
    int c;

    for (c = 0; c < N_chars; c++)
	if (f == bs->kb_normal[c])
	    return c;

#if OPT_REBIND
    for (kbp = bs->kb_extra; kbp != bs->kb_special; kbp = kbp->k_link) {
	if (kbp->k_cmd == f)
	    return kbp->k_code;
    }
#endif
    for (kbp = bs->kb_special; kbp->k_cmd != 0; kbp++) {
	if (kbp->k_cmd == f)
	    return kbp->k_code;
    }

    return -1;			/* none found */
}

/* kcod2fnc:  translate a 10-bit keycode to a function pointer */
/*	(look a key binding up in the binding table)		*/
const CMDFUNC *
kcod2fnc(const BINDINGS * bs, int c)
{
    const CMDFUNC *result = 0;

    if (bs != 0) {
	if (!is8Bits(c)) {
	    KBIND *kp = kcode2kbind(bs, c);
	    result = (kp != 0) ? kp->k_cmd : 0;
	} else {
	    result = bs->kb_normal[CharOf(c)];
	}
    }
    return result;
}

/* fnc2kcod: translate a function pointer to a keycode */
int
fnc2kcod(const CMDFUNC * f)
{
    return cmdfunc2keycode(&dft_bindings, f);
}

/* fnc2kins: translate a function pointer to an insert binding keycode */
int
fnc2kins(const CMDFUNC * f)
{
    return cmdfunc2keycode(&ins_bindings, f);
}

/* fnc2pstr: translate a function pointer to a pascal-string that a user
	could enter.  returns a pointer to a static array */
#if DISP_X11
char *
fnc2pstr(const CMDFUNC * f)
{
    int c;
    static char seq[40];

    c = fnc2kcod(f);

    if (c == -1)
	return NULL;

    return kcod2pstr(c, seq, (int) sizeof(seq));
}
#endif

#if OPT_EVAL || OPT_REBIND

#if OPT_NAMEBST
/*
 * Search for a matching CMDFUNC pointer, return the corresponding name.  We
 * use this rather than extracting from the buffer name, since it may be
 * ambiguous if the macro's name is longer than NBUFN-2.
 */
static int
match_cmdfunc(BI_NODE * node, const void *d)
{
    NTAB *result = (NTAB *) TYPECAST(void *, d);

    if (node->value.n_cmd == result->n_cmd) {
	result->n_name = (char *) TYPECAST(void *, node->value.bi_key);
	return 1;
    }
    return 0;
}
#endif

/*
 * Fill-in an NTAB with the data for the command.
 */
static int
fnc2ntab(NTAB * result, const CMDFUNC * cfp)
{
    int found = FALSE;

    if (cfp != NULL) {
#if OPT_NAMEBST
	result->n_name = 0;
	result->n_cmd = cfp;
	btree_walk(&(bst_current()->head), match_cmdfunc, result);
	found = (result->n_name != 0);
#else
	switch (cfp->c_flags & CMD_TYPE) {
	    const NTAB *nptr;

	case CMD_FUNC:		/* normal CmdFunc */
	    for (nptr = nametbl; nptr->n_cmd; nptr++) {
		if (nptr->n_cmd == cfp) {
		    /* if it's a long name, return it */
		    if ((int) strlen(nptr->n_name) > SHORT_CMD_LEN) {
			found = TRUE;
			*result = *nptr;
			break;
		    }
		    /* remember the first short name, in case there's
		       no long name */
		    if (!result) {
			*result = *nptr;
			found = SORTOFTRUE;
		    }
		}
	    }
	    break;

#if OPT_PROCEDURES
	case CMD_PROC:		/* named procedure */
	    result->n_name = CMD_U_BUFF(cfp)->b_bname;	/* not very good */
	    result->n_cmd = cfp;
	    found = TRUE;
	    break;
#endif

#if OPT_PERL
	case CMD_PERL:		/* perl subroutine */
	    result->n_name = "Perl subroutine";		/* FIXME - what name? */
	    result->n_cmd = cfp;
	    found = TRUE;
	    break;
#endif
	}
#endif /* OPT_NAMEBST */

	TRACE(("fnc2ntab(%s)\n", found ? result->n_name : ""));
    }
    return found;
}

/* fnc2engl: translate a function pointer to the english name for
		that function.  prefer long names to short ones.
*/
const char *
fnc2engl(const CMDFUNC * cfp)
{
    NTAB temp;
    return fnc2ntab(&temp, cfp) ? temp.n_name : 0;
}

#endif

/* engl2fnc: match name to a function in the names table
	translate english name to function pointer
		 return any match or NULL if none
 */
const CMDFUNC *
engl2fnc(const char *fname)
{
#if OPT_NAMEBST
    BI_NODE *n = btree_pmatch(BI_RIGHT(&(bst_current()->head)), TRUE, fname);

    if (n != NULL)
	return n->value.n_cmd;
#else
    /* this runs 10 times faster for 'nametbl[]' */
    int lo, hi, cur;
    int r;
    size_t len = strlen(fname);

    if (len != 0) {

	/* scan through the table, returning any match */
	lo = 0;
	hi = nametbl_size - 2;	/* don't want last entry -- it's NULL */

	while (lo <= hi) {
	    cur = (lo + hi) >> 1;
	    if ((r = strncmp(fname, nametbl[cur].n_name, len)) == 0) {
		/* Now find earliest matching entry */
		while (cur > lo
		       && strncmp(fname, nametbl[cur - 1].n_name, len) == 0)
		    cur--;
		return nametbl[cur].n_cmd;

	    } else if (r > 0) {
		lo = cur + 1;
	    } else {
		hi = cur - 1;
	    }
	}
    }
#endif /* OPT_NAMEBST */
    return NULL;
}

/*
 * This parser allows too many combinations; we will check for illegal
 * combinations after getting all of the information.  Still, it will not check
 * for odd things such as
 *	#-^X-a
 * since it is treated the same as
 *	^X-#-a
 */
#if OPT_EVAL || OPT_REBIND
static const char *
decode_prefix(const char *kk, UINT * prefix)
{
    UCHAR ch;
    int found;

    do {
	UINT bits = 0;
	size_t len = strlen(kk);

	if (len > 1) {
	    ch = (UCHAR) (kk[0]);
	    if (ch == cntl_a)
		bits = CTLA;
	    else if (ch == cntl_x)
		bits = CTLX;
	    else if (ch == poundc)
		bits = SPEC;
	    if (bits != 0) {
		kk++;
		if (len > 2 && *kk == '-')
		    kk++;
	    }
	}

	if (bits == 0 && len > 3 && *(kk + 2) == '-') {
	    if (*kk == '^') {
		ch = (UCHAR) (kk[1]);
		if (isCntrl(cntl_a) && ch == (UCHAR) toalpha(cntl_a))
		    bits = CTLA;
		if (isCntrl(cntl_x) && ch == (UCHAR) toalpha(cntl_x))
		    bits = CTLX;
		if (isCntrl(poundc) && ch == (UCHAR) toalpha(poundc))
		    bits = SPEC;
	    } else if (!strncmp(kk, "FN", (size_t) 2)) {
		bits = SPEC;
	    }
	    if (bits != 0)
		kk += 3;
	}

	found = FALSE;
	if (bits != 0) {
	    found = TRUE;
	    *prefix |= bits;
	}
    } while (found);
    return kk;
}

/* prc2kcod: translate printable code to 10 bit keycode */
static int
prc2kcod(const char *kk)
{
    UINT kcod;			/* code to return */
    UINT pref = 0;		/* key prefixes */

    kk = decode_prefix(kk, &pref);
    if ((pref & CTLA) && (pref & CTLX))
	return -1;

#if OPT_KEY_MODIFY
    {
	int found = FALSE;
	UINT last, len, n;
	char *s;
	char temp[NSTRING];

	while ((s = strchr(kk, '+')) != 0) {
	    if ((len = (UINT) (s - kk) + 1) >= sizeof(temp))
		break;
	    if (s == kk || s[1] == '\n' || s[1] == '\0')
		break;
	    mklower(vl_strncpy(temp, kk, (size_t) len + 1));
	    if (isLower(temp[0]))
		temp[0] = (char) toUpper(temp[0]);
	    for (n = 0; n < TABLESIZE(key_modifiers); ++n) {
		if (!strncmp(key_modifiers[n].name, temp, (size_t) len)) {
		    found = TRUE;
		    pref |= ((UINT) key_modifiers[n].code | mod_KEY);
		    break;
		}
	    }
	    kk += len;
	}
	/*
	 * SPEC would be set after a modifier, e.g.,
	 *      control+#6
	 *      control+FN-6
	 * but it would be too confusing to allow
	 *      control+^A-x
	 *      FN-control+6
	 */
	if (found) {
	    last = pref;
	    pref = 0;
	    kk = decode_prefix(kk, &pref);
	    if ((pref & (CTLA | CTLX)) != 0
		|| (last & pref & SPEC) != 0)
		return -1;
	    pref |= last;
	}
    }
#endif

    if (strlen(kk) > 2 && !strncmp(kk, "M-", (size_t) 2)) {
	pref |= HIGHBIT;
	kk += 2;
    }

    if (*kk == '^' && kk[1] != EOS) {	/* control character */
	kcod = (UCHAR) kk[1];
	if (isLower(kcod))
	    kcod = (UINT) toUpper(kcod);
	kcod = tocntrl(kcod);
	kk += 2;
    } else {			/* any single char, control or not */
	kcod = (UCHAR) (*kk++);
    }

    if (*kk != EOS)		/* we should have eaten the whole thing */
	return -1;

    return (int) (pref | kcod);
}
#endif

#if OPT_EVAL
/* translate printable code (like "M-r") to english command name */
const char *
prc2engl(const char *kk)
{
    const char *englname;
    int kcod;

    kcod = prc2kcod(kk);
    if (kcod < 0)
	return error_val;

    englname = fnc2engl(DefaultKeyBinding(kcod));
    if (englname == NULL)
	englname = error_val;

    return englname;
}
#endif

/*
 * Get an english command name from the user.  If 'prompt' is a null pointer,
 * we will splice calls.
 */
char *
kbd_engl(const char *prompt, char *buffer, UINT which)
{
    char *result = NULL;
    if (kbd_engl_stat(prompt, buffer, which, 0) == TRUE)
	result = buffer;
    return result;
}

/* sound the alarm! */
#if OPT_TRACE
void
trace_alarm(const char *file, int line)
#else
void
kbd_alarm(void)
#endif
{
    TRACE(("BEEP (%s @%d)\n", file, line));
    TPRINTF(("BEEP\n"));

    if (!no_errs
	&& !clhide
	&& !quiet
	&& global_g_val(GMDERRORBELLS)) {
	term.beep();
	term.flush();
    }
    warnings++;
}

void
kbd_start(KBD_DATA * data)
{
    beginDisplay();

#if OPT_MULTIBYTE
    make_local_b_val(bminip, VAL_FILE_ENCODING);
    if (cmd_encoding == enc_AUTO) {
	set_b_val(bminip, VAL_FILE_ENCODING, b_val(curbp, VAL_FILE_ENCODING));
    } else {
	set_b_val(bminip, VAL_FILE_ENCODING, cmd_encoding);
    }
#endif

    data->save_bp = curbp;
    data->save_wp = curwp;
    data->save_mk = MK;

    curbp = bminip;
    curwp = wminip;
    MK = DOT;
}

void
kbd_finish(KBD_DATA * data)
{
    curbp = data->save_bp;
    curwp = data->save_wp;
    MK = data->save_mk;

    endofDisplay();
}

/* put a character to the keyboard-prompt */
int
kbd_putc(int c)
{
    KBD_DATA save;
    int status;

    kbd_start(&save);
    if ((kbd_expand <= 0) && isreturn(c)) {
	status = kbd_erase_to_end(0);
    } else {
	if ((kbd_expand < 0) && (c == '\t')) {
	    status = lins_bytes(1, ' ');
	} else {
	    status = lins_bytes(1, c);
	}
#ifdef VILE_DEBUG
	TRACE(("mini:%2d:%s\n", llength(DOT.l), lp_visible(DOT.l)));
#endif
    }
    kbd_finish(&save);

    return status;
}

/* put a string to the keyboard-prompt */
static void
kbd_puts(const char *s)
{
    while (*s)
	kbd_putc(*s++);
}

/* erase a character from the display by wiping it out */
void
kbd_erase(void)
{
    if (vl_echo && !clhide) {
	KBD_DATA save;

	kbd_start(&save);
	if (DOT.o > 0) {
	    backchar_to_bol(TRUE, 1);
	    ldel_chars((B_COUNT) 1, FALSE);
	}
#ifdef VILE_DEBUG
	TRACE(("MINI:%2d:%s\n", llength(DOT.l), lp_visible(DOT.l)));
#endif
	kbd_finish(&save);
    }
}

int
kbd_erase_to_end(int column)
{
    if (vl_echo && !clhide) {
	KBD_DATA save;

	kbd_start(&save);
	if (llength(DOT.l) > 0) {
	    DOT.o = column;
	    if (llength(DOT.l) > DOT.o)
		ldel_bytes((B_COUNT) (llength(DOT.l) - DOT.o), FALSE);
	    TRACE(("NULL:%2d:%s\n", llength(DOT.l), lp_visible(DOT.l)));
	}
	kbd_finish(&save);
    }

    return TRUE;
}

int
cs_strcmp(
	     int case_insensitive,
	     const char *s1,
	     const char *s2)
{
    if (case_insensitive)
	return stricmp(s1, s2);
    return strcmp(s1, s2);
}

int
cs_strncmp(
	      int case_insensitive,
	      const char *s1,
	      const char *s2,
	      size_t n)
{
    if (case_insensitive)
	return strnicmp(s1, s2, n);
    return strncmp(s1, s2, n);
}

/* definitions for name-completion */
#define	NEXT_DATA(p)	((p)+size_entry)
#define	PREV_DATA(p)	((p)-size_entry)

#define	THIS_NAME(p)	(*TYPECAST(const char *const,p))
#define	NEXT_NAME(p)	THIS_NAME(NEXT_DATA(p))

/*
 * Scan down until we no longer match the current input, or reach the end of
 * the symbol table.
 */
/*ARGSUSED*/
static const char *
skip_partial(
		int case_insensitive,
		char *buf,
		size_t len,
		const char *table,
		size_t size_entry)
{
    const char *next = NEXT_DATA(table);
    const char *sp;

    while ((sp = THIS_NAME(next)) != 0) {
	if (StrNcmp(buf, sp, len) != 0)
	    break;
	next = NEXT_DATA(next);
    }
    return next;
}

/*
 * Shows a partial-match.  This is invoked in the symbol table at a partial
 * match, and the user wants to know what characters could be typed next.
 * If there is more than one possibility, they are shown in square-brackets.
 * If there is only one possibility, it is shown in curly-braces.
 */
static void
show_partial(
		int case_insensitive,
		char *buf,
		size_t len,
		const char *table,
		size_t size_entry)
{
    const char *next = skip_partial(case_insensitive, buf, len, table, size_entry);
    const char *last = PREV_DATA(next);
    int c;

    if (THIS_NAME(table)[len] == THIS_NAME(last)[len]) {
	kbd_putc('{');
	while ((c = THIS_NAME(table)[len]) != 0) {
	    if (c == THIS_NAME(last)[len]) {
		kbd_putc(c);
		len++;
	    } else
		break;
	}
	kbd_putc('}');
    }
    if (next != NEXT_DATA(table)) {
	c = TESTC;		/* shouldn't be in the table! */
	kbd_putc('[');
	while (table != next) {
	    const char *sp = THIS_NAME(table);
	    if (c != sp[len]) {
		c = sp[len];
		kbd_putc(c ? c : '$');
	    }
	    table = NEXT_DATA(table);
	}
	kbd_putc(']');
    }
    kbd_flush();
}

#if OPT_POPUPCHOICE
/*
 * makecmpllist is called from liststuff to display the possible completions.
 */
struct compl_rec {
    char *buf;
    size_t len;
    const char *table;
    size_t size_entry;
};

#ifdef lint
#define c2ComplRec(c) ((struct compl_rec *)0)
#else
#define c2ComplRec(c) ((struct compl_rec *)c)
#endif

/*ARGSUSED*/
static void
makecmpllist(int case_insensitive, void *cinfop)
{
    char *buf = c2ComplRec(cinfop)->buf;
    size_t len = c2ComplRec(cinfop)->len;
    const char *first = c2ComplRec(cinfop)->table;
    size_t size_entry = c2ComplRec(cinfop)->size_entry;
    const char *last = skip_partial(case_insensitive, buf, len, first, size_entry);
    const char *p;
    size_t maxlen;
    size_t slashcol;
    int cmpllen;
    int cmplcols;
    int cmplrows;
    int nentries;
    int i, j;

    for (p = NEXT_DATA(first), maxlen = strlen(THIS_NAME(first));
	 p != last;
	 p = NEXT_DATA(p)) {
	size_t l = strlen(THIS_NAME(p));
	if (l > maxlen)
	    maxlen = l;
    }

    slashcol = (size_t) (pathleaf(buf) - buf);
    if (slashcol != 0) {
	char b[NLINE];
	(void) strncpy(b, buf, slashcol);
	(void) strncpy(&b[slashcol], &(THIS_NAME(first))[slashcol],
		       (len - slashcol));
	b[slashcol + (len - slashcol)] = EOS;
	bprintf("Completions prefixed by %s:\n", b);
    }

    cmplcols = term.cols / (int) (maxlen - slashcol + 1);

    if (cmplcols == 0)
	cmplcols = 1;

    nentries = (int) ((size_t) (last - first) / size_entry);
    cmplrows = nentries / cmplcols;
    cmpllen = term.cols / cmplcols;
    if (cmplrows * cmplcols < nentries)
	cmplrows++;

    for (i = 0; i < cmplrows; i++) {
	for (j = 0; j < cmplcols; j++) {
	    int idx = cmplrows * j + i;
	    if (idx < nentries) {
		const char *s = (THIS_NAME(first
					   + ((size_t) idx * size_entry))
				 + slashcol);
		if (j == cmplcols - 1)
		    bprintf("%s\n", s);
		else
		    bprintf("%*s", cmpllen, s);
	    } else {
		bprintf("\n");
		break;
	    }
	}
    }
}

/*
 * Pop up a window and show the possible completions.
 */
static void
show_completions(
		    int case_insensitive,
		    char *buf,
		    size_t len,
		    const char *table,
		    size_t size_entry)
{
    struct compl_rec cinfo;
    BUFFER *bp;
    int alreadypopped = 0;

    /*
     * Find out if completions buffer exists; so we can take the time to
     * shrink/grow the window to the latest size.
     */
    if ((bp = find_b_name(COMPLETIONS_BufName)) != NULL) {
	alreadypopped = (bp->b_nwnd != 0);
    }

    cinfo.buf = buf;
    cinfo.len = len;
    cinfo.table = table;
    cinfo.size_entry = size_entry;
    liststuff(COMPLETIONS_BufName, FALSE, makecmpllist, case_insensitive,
	      (void *) &cinfo);

    if (alreadypopped)
	shrinkwrap();

    (void) update(TRUE);
}

/*
 * Scroll the completions window wrapping around back to the beginning
 * of the buffer once it has been completely scrolled.  If the completions
 * buffer is missing for some reason, we will call show_completions to pop
 * it (back) up.
 */
static void
scroll_completions(
		      int case_insensitive,
		      char *buf,
		      size_t len,
		      const char *table,
		      size_t size_entry)
{
    BUFFER *bp;

    if ((bp = find_b_name(COMPLETIONS_BufName)) == NULL)
	show_completions(case_insensitive, buf, len, table, size_entry);
    else {
	LINE *lp;
	swbuffer(bp);
	(void) gotoeos(FALSE, 1);
	lp = DOT.l;
	(void) forwhpage(FALSE, 1);
	if (lp == DOT.l)
	    (void) gotobob(FALSE, 0);
	(void) update(TRUE);
    }
}

void
popdown_completions(const char *old_bname, WINDOW *old_wp)
{
    BUFFER *bp;
    if ((bp = find_b_name(COMPLETIONS_BufName)) != NULL) {
	zotwp(bp);
	if (strcmp(old_bname, curbp->b_bname)) {
	    if (!strcmp(old_wp->w_bufp->b_bname, old_bname)) {
		set_curwp(old_wp);
	    } else if ((bp = find_b_name(old_bname)) != NULL) {
		swbuffer(bp);
	    }
	}
    }
}
#endif /* OPT_POPUPCHOICE */

/*
 * Attempt to partial-complete the string, char at a time
 */
static size_t
fill_partial(
		int case_insensitive,
		char *buf,
		size_t pos,
		const char *first,
		const char *last,
		size_t size_entry)
{
    const char *p;
    size_t n = pos;
    const char *this_name = THIS_NAME(first);

    TRACE(("fill_partial(%d:%.*s) first=%s, last=%s\n",
	   (int) pos, (int) pos,
	   TRACE_NULL(buf),
	   TRACE_NULL(THIS_NAME(first)),
	   TRACE_NULL(THIS_NAME(last))));

    assert(buf != 0);
#if 0				/* case insensitive reply correction doesn't work reliably yet */
    if (!clexec && case_insensitive) {
	int spos = pos;

	while (spos > 0 && buf[spos - 1] != SLASHC) {
	    kbd_erase();
	    spos--;
	}
	while (spos < pos) {
	    kbd_putc(this_name[spos]);
	    spos++;
	}
    }
#endif

    if (first == last
	|| (first = NEXT_DATA(first)) == last) {
	TRACE(("...empty list\n"));
	return n;
    }

    for_ever {
	buf[n] = this_name[n];	/* add the next char in */
	buf[n + 1] = EOS;
	TRACE(("...added(%d:%c)\n", (int) n, buf[n]));

	/* scan through the candidates */
	for (p = first; p != last; p = NEXT_DATA(p)) {
	    if (StrNcmp(&THIS_NAME(p)[n], &buf[n], (size_t) 1) != 0) {
		buf[n] = EOS;
		if (n == pos
#if OPT_POPUPCHOICE
# if OPT_ENUM_MODES
		    && !global_g_val(GVAL_POPUP_CHOICES)
# else
		    && !global_g_val(GMDPOPUP_CHOICES)
# endif
#endif
		    )
		    kbd_alarm();
		kbd_flush();	/* force out alarm or partial completion */
		TRACE(("...fill_partial %d\n", (int) n));
		return n;
	    }
	}

	if (!clexec)
	    kbd_putc(buf[n]);	/* add the character */
	n++;
    }
}

static int testcol;		/* records the column when TESTC is decoded */
#if OPT_POPUPCHOICE
/*
 * cmplcol is used to record the column number (on the message line) after
 * name completion.  Its value is used to decide whether or not to display
 * a completion list if the name completion character (tab) is pressed
 * twice in succession.  Once the completion list has been displayed, its
 * value will be changed to the additive inverse of the column number in
 * order to determine whether to scroll if tab is pressed yet again.  We
 * assume that 0 will never be a valid column number.  So long as we always
 * display some sort of prompt prior to reading from the message line, this
 * is a good assumption.
 */
static int cmplcol = 0;
#endif

/*
 * Initializes the name-completion logic
 */
void
kbd_init(void)
{
    testcol = -1;
}

/*
 * Returns the current length of the minibuffer
 */
int
kbd_length(void)
{
    if (wminip != 0
	&& wminip->w_dot.l != 0
	&& llength(wminip->w_dot.l) > 0)
	return llength(wminip->w_dot.l);
    return 0;
}

/*
 * Erases the display that was shown in response to TESTC
 */
void
kbd_unquery(void)
{
    beginDisplay();
#if OPT_POPUPCHOICE
    if (cmplcol != kbd_length() && -cmplcol != kbd_length())
	cmplcol = 0;
#endif
    if (testcol >= 0) {
	while (kbd_length() > testcol)
	    kbd_erase();
	kbd_flush();
	testcol = -1;
    }
    endofDisplay();
}

/*
 * This is invoked to find the closest name to complete from the current buffer
 * contents.
 */
int
kbd_complete(DONE_ARGS, const char *table, size_t size_entry)
{
    int case_insensitive = (flags & KBD_CASELESS) != 0;
    size_t cpos = *pos;
    const char *nbp;		/* first ptr to entry in name binding table */
    int status = FALSE;
#if OPT_POPUPCHOICE
# if OPT_ENUM_MODES
    int gvalpopup_choices = global_g_val(GVAL_POPUP_CHOICES);
# else
    int gvalpopup_choices = global_g_val(GMDPOPUP_CHOICES);
# endif
#endif

    kbd_init();			/* nothing to erase */
    buf[cpos] = EOS;		/* terminate it for us */
    nbp = table;		/* scan for matches */

    if (nbp == 0)
	return FALSE;

    while (THIS_NAME(nbp) != NULL) {
	if (StrNcmp(buf, THIS_NAME(nbp), strlen(buf)) == 0) {
	    testcol = kbd_length();
	    /* a possible match! exact? no more than one? */
#if OPT_POPUPCHOICE
	    if (!clexec && c == NAMEC && cmplcol == -kbd_length()) {
		scroll_completions(case_insensitive, buf, cpos, nbp, size_entry);
		return FALSE;
	    }
#endif
	    if (c == TESTC) {
		show_partial(case_insensitive, buf, cpos, nbp, size_entry);
	    } else if (Strcmp(buf, THIS_NAME(nbp)) == 0 ||	/* exact? */
		       NEXT_NAME(nbp) == NULL ||
		       StrNcmp(buf, NEXT_NAME(nbp), strlen(buf)) != 0) {
		/* exact or only one like it.  print it */
		if (!clexec) {
#if 0				/* case insensitive reply correction doesn't work reliably yet */
		    if (case_insensitive) {
			int spos = cpos;

			while (spos > 0 && buf[spos - 1] != SLASHC) {
			    kbd_erase();
			    spos--;
			}
			kbd_puts(THIS_NAME(nbp) + spos);
		    } else
#endif
			kbd_puts(THIS_NAME(nbp) + cpos);
		    kbd_flush();
		    testcol = kbd_length();
		}
		if (c != NAMEC)	/* put it back */
		    unkeystroke(c);
		/* return complete name */
		(void) strncpy0(buf, THIS_NAME(nbp),
				(size_t) (NLINE - 1));
		*pos = strlen(buf);
#if OPT_POPUPCHOICE
		if (gvalpopup_choices != POPUP_CHOICES_OFF
		    && !clexec && (c == NAMEC))
		    status = FALSE;
		else
#endif
		    status = TRUE;
	    } else {
		/* try for a partial match against the list */
		*pos = fill_partial(case_insensitive, buf, cpos, nbp,
				    skip_partial(case_insensitive, buf,
						 cpos, nbp, size_entry),
				    size_entry);
		testcol = kbd_length();
	    }
#if OPT_POPUPCHOICE
# if OPT_ENUM_MODES
	    if (!clexec
		&& gvalpopup_choices != POPUP_CHOICES_OFF
		&& c == NAMEC
		&& *pos == cpos) {
		if (gvalpopup_choices == POPUP_CHOICES_IMMED
		    || cmplcol == kbd_length()) {
		    show_completions(case_insensitive, buf, cpos, nbp, size_entry);
		    cmplcol = -kbd_length();
		} else
		    cmplcol = kbd_length();
	    } else
		cmplcol = 0;
# else
	    if (!clexec && gvalpopup_choices
		&& c == NAMEC && *pos == cpos) {
		show_completions(case_insensitive, buf, cpos, nbp, size_entry);
		cmplcol = -kbd_length();
	    } else
		cmplcol = 0;
# endif
#endif
	    return status;
	}
	nbp = NEXT_DATA(nbp);
    }

#if OPT_POPUPCHOICE
    cmplcol = 0;
#endif
    buf[*pos = cpos] = EOS;
    if ((flags & (KBD_MAYBEC | KBD_MAYBEC2)) != 0) {
	status = (cpos != 0);
    } else {
	if (clexec) {
#if OPT_MODELINE
	    if (in_modeline < 2)
#endif
		mlwarn("[No match for '%s']", buf);
	} else {
	    kbd_alarm();
	}
	status = FALSE;
    }
    return status;
}

/*
 * Test a buffer to see if it looks like a shift-command, which may have
 * repeated characters (but they must all be the same).
 */
static int
is_shift_cmd(const char *buffer, size_t cpos)
{
    if (buffer != 0) {
	int c = *buffer;
	if (isRepeatable(c)) {
	    while (--cpos != 0)
		if (*(++buffer) != c)
		    return FALSE;
	    return TRUE;
	}
    }
    return FALSE;
}

/*
 * The following mess causes the command to terminate if:
 *
 *	we've got the eolchar
 *		-or-
 *	we're in the first few chars and we're switching from punctuation
 *	(i.e., delimiters) to non-punctuation (i.e., characters that are part
 *	of command-names), or vice-versa.  oh yeah -- '-' isn't punctuation
 *	today, and '!' isn't either, in one direction, at any rate.
 *	All this allows things like:
 *		: e#
 *		: e!%
 *		: !ls
 *		: q!
 *		: up-line
 *	to work properly.
 *
 *	If we pass this "if" with c != NAMEC, then c is ungotten below,
 *	so it can be picked up by the commands argument getter later.
 */

#define ismostpunct(c) (isPunct(c) && (c) != '-' && (c) != '_')

int
eol_command(EOL_ARGS)
{
    int result = FALSE;

    if (is_shift_cmd(buffer, cpos) && (c == *buffer)) {
	/*
	 * Handle special case of repeated-character implying repeat-count
	 */
	result = TRUE;
    } else if ((cpos != 0) && isShellOrPipe(buffer)) {
	/*
	 * Shell-commands aren't complete until the line is complete.
	 */
	result = isreturn(c);
    } else if (c == eolchar) {
	result = TRUE;
    } else if (cpos != 0 && cpos < 3
	       && ((!ismostpunct(c)
		    && ismostpunct(buffer[cpos - 1]))
		   || ((c != '!' && ismostpunct(c))
		       && (buffer[cpos - 1] == '!'
			   || !ismostpunct(buffer[cpos - 1]))
		   )
	       )) {
	result = TRUE;
    }
    return result;
}

/*
 * This procedure is invoked from 'kbd_string()' to setup the command-name
 * completion and query displays.
 */
int
cmd_complete(DONE_ARGS)
{
    int status;
    if (buf != 0 && pos != 0) {
#if OPT_HISTORY
	/*
	 * If the user scrolled back in 'edithistory()', the text may be a
	 * repeated-shift command, which won't match the command-table (e.g.,
	 * ">>>").
	 */
	if ((*pos > 1) && is_shift_cmd(buf, *pos)) {
	    size_t len = 1;
	    char tmp[NLINE];
	    tmp[0] = *buf;
	    tmp[1] = EOS;
	    status = cmd_complete(0, c, tmp, &len);
	} else
#endif
	if ((*pos != 0) && isShellOrPipe(buf)) {
#if COMPLETE_FILES
	    status = shell_complete(PASS_DONE_ARGS);
#else
	    status = isreturn(c);
	    if (c != NAMEC)
		unkeystroke(c);
#endif
	} else {
	    status = kbd_complete_bst(PASS_DONE_ARGS);
	}
    } else {
	status = ABORT;
    }
    return status;
}

int
kbd_engl_stat(const char *prompt, char *buffer, UINT which, int stated)
{
    KBD_OPTIONS kbd_flags = KBD_EXPCMD | KBD_NULLOK | ((NAMEC != ' ') ? 0 : KBD_MAYBEC);
    int code;
    static TBUFF *temp;
    size_t len = NLINE;

    which_current = which;

    tb_scopy(&temp, "");
    init_filec(FILECOMPLETION_BufName);
    kbd_flags |= (KBD_OPTIONS) stated;
    code = kbd_reply(
			prompt,	/* no-prompt => splice */
			&temp,	/* in/out buffer */
			eol_command,
			' ',	/* eolchar */
			kbd_flags,	/* allow blank-return */
			cmd_complete);
    if (len > tb_length(temp))
	len = tb_length(temp);
    strncpy0(buffer, tb_values(temp), len);

    which_current = 0;
    return code;
}

#if OPT_NAMEBST
int
insert_namebst(const char *name, const CMDFUNC * cmd, int ro, UINT which)
{
    int result;

    TRACE2((T_CALLED "insert_namebst(%s,%s)\n", name, ro ? "ro" : "rw"));
    if (name != 0) {
	BI_TREE *my_bst = bst_pointer(which);
	BI_DATA temp, *p;

	if ((p = btree_search(my_bst, name)) != 0) {
	    if ((p->n_flags & NBST_READONLY)) {
		if (btree_insert(&redefns, p) == 0) {
		    returnCode(FALSE);
		} else {
		    if (!btree_delete(my_bst, name)) {
			returnCode(FALSE);
		    }
		}
		mlwrite("[Redefining builtin '%s']", name);
	    } else {
		if (!delete_namebst(name, TRUE, TRUE, which)) {
		    returnCode(FALSE);
		}
	    }
	}

	temp.bi_key = name;
	temp.n_cmd = cmd;
	temp.n_flags = (UCHAR) (ro ? NBST_READONLY : 0);

	result = (btree_insert(my_bst, &temp) != 0);
    } else {
	result = FALSE;
    }
    return2Code(result);
}

static void
remove_cmdfunc_ref(BINDINGS * bs, const CMDFUNC * cmd)
{
#if OPT_REBIND
    int i;
    int redo;
    KBIND *kbp;

    /* remove ascii bindings */
    for (i = 0; i < N_chars; i++)
	if (bs->kb_normal[i] == cmd)
	    bs->kb_normal[i] = 0;

    /* then look in the multi-key table */
    do {
	redo = FALSE;
	for (kbp = bs->kb_extra; kbp != bs->kb_special; kbp = kbp->k_link)
	    if (kbp->k_cmd == cmd) {
		unbindchar(bs, kbp->k_code);
		redo = TRUE;
		break;
	    }
    } while (redo);

    do {
	redo = FALSE;
	for (kbp = bs->kb_special; kbp->k_cmd; kbp++)
	    if (kbp->k_cmd == cmd) {
		unbindchar(bs, kbp->k_code);
		redo = TRUE;
		break;
	    }
    } while (redo);
#endif
}

/*
 * Lookup a name in the binary-search tree, remove it if found
 */
int
delete_namebst(const char *name, int release, int redefining, UINT which)
{
    BI_TREE *my_bst = bst_pointer(which);
    BI_DATA *p = btree_search(my_bst, name);
    int code = TRUE;

    TRACE((T_CALLED "delete_namebst(%s,%d) %p\n", name, release, (void *) p));
    /* not a named procedure */
    if ((p = btree_search(my_bst, name)) != 0) {

	/* we may have to free some stuff */
	if (p && release) {
	    remove_cmdfunc_ref(&dft_bindings, p->n_cmd);
	    remove_cmdfunc_ref(&ins_bindings, p->n_cmd);
	    remove_cmdfunc_ref(&cmd_bindings, p->n_cmd);

	    /* free stuff */
#if OPT_PERL
	    if (p->n_cmd->c_flags & CMD_PERL)
		perl_free_sub(CMD_U_PERL(p->n_cmd));
#endif

	    if (!(p->n_flags & NBST_READONLY)) {
		beginDisplay();
		free(TYPECAST(char, p->n_cmd->c_help));
		free(TYPECAST(char, p->n_cmd));
		endofDisplay();
	    }
	    p->n_cmd = 0;	/* ...so old_namebst won't free this too */
	}

	if ((code = btree_delete(my_bst, name)) == TRUE) {
	    if (!redefining) {
		if ((p = btree_search(&redefns, name)) != 0) {
		    mlwrite("[Restoring builtin '%s']", name);
		    code = (btree_insert(my_bst, p) != 0);
		    (void) btree_delete(&redefns, p->bi_key);
		}
	    }
	}
    }
    returnCode(code);
}

/*
 * If we're renaming a procedure to another "procedure" name (i.e., bracketed),
 * rename it in the name-completion table.  Otherwise, simply remove it from the
 * name-completions.
 */
int
rename_namebst(const char *oldname, const char *newname, UINT which)
{
    BI_DATA *prior;
    char name[NBUFN];

    /* not a named procedure */
    if ((prior = btree_search(bst_pointer(which), oldname)) == 0)
	return TRUE;

    /* remove the entry if the new name is not a procedure (bracketed) */
    if (!is_scratchname(newname))
	return delete_namebst(oldname, TRUE, FALSE, which);

    /* add the new name */
    strip_brackets(name, newname);
    if ((insert_namebst(name,
			prior->n_cmd,
			prior->n_flags & NBST_READONLY,
			which)) != TRUE)
	return FALSE;

    /* delete the old (but don't free the data) */
    return delete_namebst(oldname, FALSE, FALSE, which);
}

int
search_namebst(const char *name, UINT which)
{
    return (btree_search(bst_pointer(which), name) != 0);
}

/*
 * Build the initial name binary search tree.  Since the nametbl is sorted we
 * do this in a binary-search manner to get a balanced tree.
 */
void
build_namebst(const NTAB * nptr, int lo, int hi, UINT which)
{
    for (; lo < hi; lo++) {
	if (!insert_namebst(nptr[lo].n_name, nptr[lo].n_cmd, TRUE, which))
	    tidy_exit(BADEXIT);
    }
}

/*
 * This is invoked to find the closest name to complete from the current buffer
 * contents.
 */
static int
kbd_complete_bst(unsigned flags,
		 int c,		/* TESTC, NAMEC or isreturn() */
		 char *buf,
		 size_t *pos)
{
    size_t cpos = *pos;
    int status = FALSE;
    const char **nptr;

    (void) flags;

    kbd_init();			/* nothing to erase */
    buf[cpos] = EOS;		/* terminate it for us */

    if ((nptr = btree_parray(bst_current(), buf, cpos)) != 0) {
	status = kbd_complete(0, c, buf, pos, (const char *) nptr,
			      sizeof(*nptr));
	beginDisplay();
	free(TYPECAST(char, nptr));
	endofDisplay();
    } else
	kbd_alarm();

    return status;
}
#endif /* OPT_NAMEBST */

#if OPT_MENUS
/* FIXME: reuse logic from makefuncdesc() */
char *
give_accelerator(char *bname)
{
    size_t i;
    int n;
    const CMDFUNC *cmd;
    static char outseq[NLINE];

    if ((n = blist_match(&blist_nametbl, bname)) >= 0) {
	cmd = nametbl[n].n_cmd;

	outseq[0] = '\0';
	convert_cmdfunc(&dft_bindings, cmd, outseq);

	/* Replace \t by ' ' */
	for (i = 0; i < strlen(outseq); i++) {
	    if (outseq[i] == '\t')
		outseq[i] = ' ';
	}

	return outseq;
    }

    return NULL;
}
#endif /* OPT_MENUS */

#if SYS_WINNT
/*
 * At least one user wants the ability to swap ALT+Insert and CTRL+Insert
 * (mappings that copy info to the clipboard).
 *
 * If [win]vile ever gives end users the ability to map commands using
 * ALT, CTRL, and SHIFT prefixes, then swapcbrdkeys() will likely be
 * removed.
 */
int
swapcbrdkeys(int f GCC_UNUSED, int n GCC_UNUSED)
{
    const CMDFUNC *cmd;
    int rc = FALSE;

    if ((cmd = engl2fnc("copy-unnamed-reg-to-clipboard")) != NULL)
	if (install_bind(mod_KEY | KEY_Insert | mod_CTRL, cmd, &dft_bindings))
	    if ((cmd = engl2fnc("copy-to-clipboard-til")) != NULL)
		if (install_bind(mod_KEY | KEY_Insert | mod_ALT, cmd, &dft_bindings))
		    rc = TRUE;

    if (!rc)
	mlforce("[swap failed]");
    return (rc);
}
#endif

#if NO_LEAKS

#if OPT_REBIND
static void
free_all_bindings(BINDINGS * bs)
{
    while (bs->kb_extra != bs->kb_special) {
	KBIND *kbp = bs->kb_extra;
	bs->kb_extra = kbp->k_link;
	free((char *) kbp);
    }
}

static void
free_ext_bindings(BINDINGS * bs)
{
    free_all_bindings(bs);
    FreeAndNull(bs->kb_special);
}
#endif
void
bind_leaks(void)
{
    btree_printf(&namebst);
#if OPT_REBIND
    free_all_bindings(&dft_bindings);
    free_ext_bindings(&ins_bindings);
    free_ext_bindings(&cmd_bindings);
    free_ext_bindings(&sel_bindings);
#endif
#if OPT_NAMEBST
    btree_freeup(&redefns);
    btree_freeup(&namebst);
    btree_freeup(&glbsbst);
#endif
}
#endif /* NO_LEAKS */
vile-9.8v/blist.c000066400000000000000000000104511415556424100140100ustar00rootroot00000000000000/*
 * $Id: blist.c,v 1.17 2018/10/21 19:37:24 tom Exp $
 * Copyright 2007-2013,2018 by Thomas E. Dickey
 *
 * Provide binary-search lookup of arrays of sorted structs.  The beginning of
 * each struct is a pointer to a string, which is the key by which the structs
 * are sorted.  The last entry in the array contains a struct whose key is
 * null.  That makes it simple to initialize the itemCount value when the
 * array contents are determined by ifdef's.
 */

#include	
#include	

#define	ILLEGAL_NUM	-1
#define ItemOf(data,inx) *(const char * const*)\
	((const void *)((const char *)(data->theList) \
		       + ((size_t) (inx) * (size_t) data->itemSize)))

#define ItemToInx(data, item) \
	((UINT) ((const char *) item - (const char *) (data->theList)) \
	  / data->itemSize)

typedef struct {
    const char *name;
} ToFind;

#ifdef DEBUG_ME
static long total_calls;
static long total_compares;
static long total_linear;
static long total_limits;

#define COUNTER(which,n) which += n
#else
#define COUNTER(which,n)
#endif

/*
 * Returns the number of items in the BLIST, saving the number in the struct
 * for later use.
 */
int
blist_count(BLIST * data)
{
    if (data->itemCount < 0) {
	int n;
	for (n = 0; ItemOf(data, n) != 0; ++n) {
	    ;
	}
	data->itemCount = n;
    }
    return data->itemCount;
}

static int
exact_match(const void *keyobj, const void *arraymember)
{
    COUNTER(total_compares, 1);
    return strcmp(*(const char *const *) keyobj, (*(const char *const *) arraymember));
}

/*
 * Exact matches can use bsearch.
 */
int
blist_match(BLIST * data, const char *name)
{
    int rc = -1;
    int last = blist_count(data);
    void *check;
    ToFind dummy;

    dummy.name = name;
    check = bsearch(&dummy,
		    data->theList,
		    (size_t) last,
		    (size_t) data->itemSize,
		    exact_match);
    if (check != 0) {
	rc = (int) ItemToInx(data, check);
    }
    COUNTER(total_linear, rc + 1);
    COUNTER(total_limits, last);
    COUNTER(total_calls, 1);
    return rc;
}

/*
 * Given what may be part of the name (length in 'len'), look for a match.
 * If the result is ambiguous, do not match unless the given name exactly
 * matches one item.
 */
int
blist_pmatch(BLIST * data, const char *name, int len)
{
    int actual = (int) strlen(name);
    int rc = -1;
    int hi, lo, x0, x1, cmp;
    int last = blist_count(data);
    const char *item;
    const char *test;

    if (len < 0 || len > actual)
	len = actual;

    x1 = -1;
    hi = last - 1;
    lo = 0;
    do {
	x0 = x1;
	x1 = lo + (hi - lo) / 2;
	if (x0 == x1) {
	    if (++x1 > hi)
		break;
	}
	item = ItemOf(data, x1);
	cmp = strncmp(item, name, (size_t) len);
	if (cmp < 0) {
	    lo = (x1 == lo) ? (x1 + 1) : x1;
	} else if (cmp > 0) {
	    hi = (x1 == hi) ? (x1 - 1) : x1;
	} else {
	    rc = x1;

	    /*
	     * Check for an exact match...
	     */
	    COUNTER(total_compares, 1);
	    if (strcmp(item, name)) {
		if (x1 > lo) {
		    ToFind dummy;

		    dummy.name = name;
		    test = (const char *) bsearch(&dummy,
						  &ItemOf(data, lo),
						  (size_t) x1 + 1 - (size_t) lo,
						  (size_t) data->itemSize,
						  exact_match);
		    if (test) {
			rc = (int) ItemToInx(data, test);
			break;
		    }
		}
	    }

	    /*
	     * Now - if we have not found an exact match, check for ambiguity.
	     */
	    if (rc >= 0) {
		if (len > (int) strlen(item)) {
		    rc = -1;
		} else if (x1 < last - 1) {
		    COUNTER(total_compares, 2);
		    if (strcmp(item, name)
			&& !strncmp(ItemOf(data, (size_t) x1 + 1), name,
				    (size_t) len)) {
			rc = -1;
		    }
		}
	    }
	    break;
	}
    } while (hi >= lo);
    COUNTER(total_linear, rc + 2);
    COUNTER(total_limits, last);
    COUNTER(total_calls, 1);
    return rc;
}

/*
 * Reset the count because we have a new or reallocated list.
 */
void
blist_reset(BLIST * data, const void *newList)
{
    data->itemCount = -1;
    data->theList = newList;
}

void
blist_summary(void)
{
#ifdef DEBUG_ME
    if (total_calls) {
	printf("\r\nBLIST:\n");
	printf("   calls %ld, average table size %.1f\n",
	       total_calls,
	       (1.0 * total_limits) / total_calls);
	printf("   compares %6ld (%.1f%%)\n",
	       total_compares,
	       (100.0 * total_compares) / total_limits);
	printf("   linear   %6ld (%.1f%%)\n\n",
	       total_linear,
	       (100.0 * total_linear) / total_limits);
    }
#endif
}
vile-9.8v/blist.h000066400000000000000000000011441415556424100140140ustar00rootroot00000000000000/*
 * $Id: blist.h,v 1.4 2007/08/13 22:59:08 tom Exp $
 *
 * Interface for blist.c
 */

#ifndef BLIST_H
#define BLIST_H 1

typedef struct BLIST {
	const void *theList;
	unsigned itemSize;
	int itemCount;
} BLIST;

#define init_blist(list) { list, sizeof(list[0]), -1 }

#ifdef __cplusplus
extern "C" {
#endif

extern int blist_count (BLIST *data);
extern int blist_match (BLIST *data, const char *name);
extern int blist_pmatch (BLIST *data, const char *name, int len);
extern void blist_reset (BLIST *data, const void *list);
extern void blist_summary (void);

#ifdef __cplusplus
}
#endif

#endif /* BLIST_H */
vile-9.8v/borland.c000066400000000000000000000334121415556424100143160ustar00rootroot00000000000000/*
 * Uses Borland console i/o routines.
 * (Created for OS/2 by Charles Moschel 29-MAR-94.)
 * (modified to be more generic, not os/2 specific, pgf, april '94)
 *
 * Supported monitor cards include
 *	CGA, MONO, EGA, VGA.
 *
 * Note: Visual flashes are not yet supported.
 *
 *
 * $Id: borland.c,v 1.43 2020/01/17 23:12:22 tom Exp $
 *
 */

#include        "estruct.h"
#include        "edef.h"

#if SYS_OS2
#define INCL_VIO
#define INCL_NOPMAPI
#include 
#undef OPT_COLOR
#endif /* SYS_OS2 */

#if !DISP_BORLAND
#error misconfigured:  DISP_BORLAND should be defined if using borland.c
#endif

#define NROW	50		/* Max Screen size.             */
#define NCOL    80		/* Edit if you want to.         */
#define	SPACE	32		/* space character              */

/* We assume that most users have a color display.  */

#include 

#if 0				//def GVAL_VIDEO
#define REVERSED (global_g_val(GVAL_VIDEO) & VAREV)
static void
set_reverse(void)
{
    //if (REVERSED)
    //begin_reverse();
}

#else
#define REVERSED 0
#define set_reverse()		/* nothing */
#endif

static void borflush(void);

static int cfcolor = -1;	/* current foreground color */
static int cbcolor = -1;	/* current background color */
/* ansi to ibm color translation table */
static const char *initpalettestr = "0 4 2 6 1 5 3 7 8 12 10 14 9 13 11 15";
/* black, red, green, yellow, blue, magenta, cyan, white   */

static int scinit(int);

static char linebuf[128];
static int bufpos = 0;
/* *INDENT-OFF* */
static struct {
    char  *seq;
    int   code;
} keyseqs[] = {
    /* Arrow keys */
    {"\0\110",     KEY_Up},
    {"\0\120",     KEY_Down},
    {"\0\115",     KEY_Right},
    {"\0\113",     KEY_Left},
#if 0
    {"\0\110",     KEY_S_Up},	/* shift (unchanged) */
    {"\0\120",     KEY_S_Down},
    {"\0\115",     KEY_S_Right},
    {"\0\113",     KEY_S_Left},
    {"\0\215",     KEY_C_Up},	/* control */
    {"\0\221",     KEY_C_Down},
    {"\0\164",     KEY_C_Right},
    {"\0\163",     KEY_C_Left},
    {"\0\230",     KEY_A_Up},	/* left-alt */
    {"\0\240",     KEY_A_Down},
    {"\0\235",     KEY_A_Right},
    {"\0\233",     KEY_A_Left},
#endif
    /* page scroll */
    {"\0\121",     KEY_Next},
    {"\0\111",     KEY_Prior},
    {"\0\107",     KEY_Home},
    {"\0\117",     KEY_End},
#if 0
    {"\0\121",     KEY_S_Next},	/* shift (unchanged) */
    {"\0\111",     KEY_S_Prior},
    {"\0\107",     KEY_S_Home},
    {"\0\117",     KEY_S_End},
    {"\0\166",     KEY_C_Next},	/* control */
    {"\0\204",     KEY_C_Prior},
    {"\0\167",     KEY_C_Home},
    {"\0\165",     KEY_C_End},
    {"\0\241",     KEY_A_Next},	/* left-alt */
    {"\0\231",     KEY_A_Prior},
    {"\0\227",     KEY_A_Home},
    {"\0\237",     KEY_A_End},
#endif
    /* editing */
    {"\0\122",     KEY_Insert},
    {"\0\123",     KEY_Delete},
#if 0
    {"\0\122",     KEY_S_Insert},	/* shift (unchanged) */
    {"\0\123",     KEY_S_Delete},
    {"\0\222",     KEY_C_Insert},	/* control */
    {"\0\223",     KEY_C_Delete},
    {"\0\242",     KEY_A_Insert},	/* left-alt */
    {"\0\243",     KEY_A_Delete},
#endif
    /* function keys */
    {"\0;",        KEY_F1},
    {"\0<",        KEY_F2},
    {"\0=",        KEY_F3},
    {"\0>",        KEY_F4},
    {"\0?",        KEY_F5},
    {"\0@",        KEY_F6},
    {"\0A",        KEY_F7},
    {"\0B",        KEY_F8},
    {"\0C",        KEY_F9},
    {"\0D",        KEY_F10},
    {"\0\205",     KEY_F11},
    {"\0\206",     KEY_F12},

    /* shift + F1-F12 */
    {"\0T",        KEY_F13},
    {"\0U",        KEY_F14},
    {"\0V",        KEY_F15},
    {"\0W",        KEY_F16},
    {"\0X",        KEY_F17},
    {"\0Y",        KEY_F18},
    {"\0Z",        KEY_F19},
    {"\0[",        KEY_F20},
    {"\0\\",       KEY_F21},
    {"\0]",        KEY_F22},
    {"\0\207",     KEY_F23},
    {"\0\210",     KEY_F24},

    /* control + F1-F12 */
    {"\0^",        KEY_F25},
    {"\0_",        KEY_F26},
    {"\0`",        KEY_F27},
    {"\0a",        KEY_F28},
    {"\0b",        KEY_F29},
    {"\0c",        KEY_F30},
    {"\0d",        KEY_F31},
    {"\0e",        KEY_F32},
    {"\0f",        KEY_F33},
    {"\0g",        KEY_F34},
    {"\0\211",     KEY_F35},
    {"\0\212",     KEY_F36},

    /* left-alt + F1-F12 */
    {"\0h",        KEY_F37},
    {"\0i",        KEY_F38},
    {"\0j",        KEY_F39},
    {"\0k",        KEY_F40},
    {"\0l",        KEY_F41},
    {"\0m",        KEY_F42},
    {"\0n",        KEY_F43},
    {"\0o",        KEY_F44},
    {"\0p",        KEY_F45},
    {"\0q",        KEY_F46},
    {"\0\213",     KEY_F47},
    {"\0\214",     KEY_F48},

    {"\0\017",     KEY_BackTab },
};
/* *INDENT-ON* */

static int ibmtype;

static int borlastchar = -1;
static int bortttypahead(void);
static int borttgetc(void);

#if OPT_ICURSOR
static void
boricursor(int cmode)
{
    switch (cmode) {
    case -1:
	_setcursortype(_NOCURSOR);
	break;
    case 0:
	_setcursortype(_NORMALCURSOR);
	break;
    case 1:
	_setcursortype(_SOLIDCURSOR);
	break;
    }
}
#endif

#if OPT_COLOR
static void
borfcol(int color)		/* set the current output color */
{
    if (color < 0)
	color = C_WHITE;
    cfcolor = ctrans[color];
    textcolor(cfcolor & 15);
}

static void
borbcol(int color)		/* set the current background color */
{
    if (color < 0)
	color = C_BLACK;
    cbcolor = ctrans[color];
    textbackground(cbcolor & 7);
}

static void
borspal(const char *thePalette)	/* reset the palette registers */
{
    borflush();
    set_ctrans(thePalette);
}

static void
setup_colors(void)
{
    borfcol(gfcolor);
    borbcol(gbcolor);
}

static void
reset_colors(void)
{
    borfcol(7 /* not necessarily C_WHITE */ );
    borbcol(C_BLACK);
}

#else
#define setup_colors()		/* nothing */
#define reset_colors()		/* nothing */
#endif

static void
borflush(void)
{
    if (bufpos) {
	linebuf[bufpos] = '\0';
	cputs(linebuf);
	bufpos = 0;
    }
}

static void
bormove(int row, int col)
{
    borflush();
    gotoxy(col + 1, row + 1);
}

/* erase to the end of the line */
static void
boreeol(void)
{
    borflush();
    clreol();			/* pointer to the destination line */
}

/* put a character at the current position in the current colors */
static void
borputc(int ch)
{
    linebuf[bufpos++] = ch;
}

static void
boreeop(void)
{
    int x, y, i;
    struct text_info t;

    borflush();
    x = wherex();
    y = wherey();
    gettextinfo(&t);
    clreol();
    for (i = x + 1; i <= t.screenheight; i++) {
	gotoxy(1, i);
	clreol();
    }
    gotoxy(x, y);
}

#if OPT_VIDEO_ATTRS
static void
bor_attr(UINT attr)		/* change video attributes */
{
    static UINT last;
    UINT next;
    int colored = FALSE;

    if (attr != last) {
	last = attr;
	borflush();

	attr = VATTRIB(attr);
#if 0				//def GVAL_VIDEO
	if (REVERSED) {
	    if (attr & VASEL)
		attr ^= VASEL;
	    else
		attr ^= VAREV;
	}
#endif
	if (attr & VASPCOL) {
	    colored = TRUE;
	    attr = VCOLORATTR((VCOLORNUM(attr) & (ncolors - 1)));
	} else {
	    if (attr & VACOLOR) {
		attr &= (VCOLORATTR(ncolors - 1) | ~VACOLOR);
		colored = TRUE;
	    }
	    attr &= ~(VAML | VAMLFOC);
	}

	next = ctrans[VCOLORNUM(attr)];
	if (attr & (VASEL | VAREV)) {
	    textcolor((colored ? next : cbcolor) & 15);
	    textbackground(cfcolor & 7);
	} else {
	    textcolor((colored ? next : cfcolor) & 15);
	    textbackground(cbcolor & 7);
	}
    }
}
#else
static void
bor_rev(UINT reverse)		/* change reverse video state */
{
    borflush();
    if (reverse) {
	textbackground(cfcolor & 7);
	textcolor(cbcolor & 15);
    } else {
	textbackground(cbcolor & 7);
	textcolor(cfcolor & 15);
    }
}
#endif

static int
borcres(const char *res)	/* change screen resolution */
{
    char *dst;
    register int i;		/* index */
    int status = FALSE;

    strcpy(current_res_name, res);
    borflush();
    /* find the default configuration */
    if (!strcmp(res, "?")) {
	status = scinit(-1);
    } else {			/* specify a number */
	if ((i = (int) strtol(res, &dst, 0)) >= 0 && !*dst) {
	    /* only allow valid row selections */
	    /* Are these all valid under dos?  */
	    if (i == 2)
		status = scinit(25);
	    if (i == 4)
		status = scinit(43);
	    if (i == 5)
		status = scinit(50);
	    if (i == 6)
		status = scinit(60);

	    if (i > 6 && i < 28)
		status = scinit(25);

	    if (i >= 28 && i < 43)
		status = scinit(28);

	    if (i >= 43 && i < 50)
		status = scinit(43);

	    if (i >= 50 && i < 60)
		status = scinit(50);

	    if (i >= 60)
		status = scinit(60);

	}
    }
    sgarbf = TRUE;
    return status;
}

static void
borbeep(void)
{
    putch('\a');
}

static void
boropen(void)
{
    static int already_open;

    int i;

#if OPT_LOCALE
    vl_open_mbterm();
#endif

    if (!already_open) {
	already_open = TRUE;

	set_palette(initpalettestr);
	setup_colors();

	if (!borcres(current_res_name))
	    (void) scinit(-1);
	ttopen();
	for (i = TABLESIZE(keyseqs) - 1; i >= 0; i--)
	    addtosysmap(keyseqs[i].seq, 2, keyseqs[i].code);
    }
}

static void
borclose(void)
{
    int current_type = ibmtype;

    borflush();
#if OPT_ICURSOR
    _setcursortype(_NORMALCURSOR);
#endif
    ibmtype = current_type;	/* ...so subsequent term.open restores us */

    reset_colors();
    kbd_erase_to_end(0);
    kbd_flush();
#if OPT_LOCALE
    vl_close_mbterm();
#endif
}

static void
borkopen(void)			/* open the keyboard */
{
    setup_colors();
    term.curmove(term.rows - 1, 0);	/* cf: dumbterm.c */
    term.eeol();

    /* ms_install(); */
}

static void
borkclose(void)			/* close the keyboard */
{
    /* ms_deinstall(); */

    reset_colors();
    term.curmove(term.rows - 1, 0);	/* cf: dumbterm.c */
    term.eeol();
}

static
int
borttgetc(void)
{
    return (borlastchar = ttgetc());
}

/* bortttypahead:  Check to see if any characters are already in the
 * keyboard buffer.In Borland C OS/2 1.5, kbhit doesn't return non-zero for
 * the 2nd part of an extended character, but 1st part is still 0 so use
 * that as indicator as well (why it's saved in borttgetc).
 */
static int
bortttypahead(void)
{

    return (kbhit() != 0 || borlastchar == 0);

}

#if SYS_OS2			/* all modes are available under OS/2 */
static int
scinit(int rows)		/* initialize the screen head pointers */
{

    /* and set up the various parameters as needed */

    if (rows == -1) {
	struct text_info ti;
	gettextinfo(&ti);
	rows = ti.screenheight;
    }

    switch (rows) {

	/* these are enum's, and thus cannot easily be checked, ie. #ifdef C80X21 */
    case 21:			/* color C80X21 */
	textmode(C80X21);
	newscreensize(21, term.cols);
	(void) strcpy(screen_desc, "C80X21");
	break;

    default:
    case 25:			/* Color graphics adapter */
	textmode(C80);
	newscreensize(25, term.cols);
	(void) strcpy(screen_desc, "C80");
	break;

    case 28:			/* Enhanced graphics adapter */
	textmode(C80X28);
	newscreensize(28, term.cols);
	(void) strcpy(screen_desc, "C80X28");
	break;

    case 43:			/* Enhanced graphics adapter */
	textmode(C80X43);
	newscreensize(43, term.cols);
	(void) strcpy(screen_desc, "C80X43");
	break;

    case 50:			/* VGA adapter */
	textmode(C80X50);
	newscreensize(50, term.cols);
	(void) strcpy(screen_desc, "C80X50");
	break;

    case 60:			/* Enhanced graphics adapter */
	textmode(C80X60);
	newscreensize(60, term.cols);
	(void) strcpy(screen_desc, "C80X60");
	break;

    }

    ibmtype = rows;

    return (TRUE);
}

#else /* SYS_OS2 */

static int
scinit(int rows)		/* initialize the screen head pointers */
{

    /* and set up the various parameters as needed */

    struct text_info ti;
    int oldrows;

    gettextinfo(&ti);
    oldrows = ti.screenheight;
    if (rows == -1)
	rows = oldrows;

    switch (rows) {

	/* DOS has only BW40, C40, BW80, C80, MONO, and C4350 */

    default:
    case 25:			/* Color graphics adapter */
	if (oldrows != 25)
	    textmode(C80);
	newscreensize(25, term.cols);
	(void) strcpy(screen_desc, "C80");
	break;

    case 43:
    case 50:
    case 60:
	if (rows != oldrows)
	    textmode(C4350);
	gettextinfo(&ti);
	rows = ti.screenheight;
	newscreensize(rows, term.cols);
	sprintf(screen_desc, "C80X%d", rows);
	break;

    }

    ibmtype = rows;

    return (TRUE);
}

#endif /* SYS_OS2 */

/*
 * Move 'n' lines starting at 'from' to 'to'
 *
 * OPT_PRETTIER_SCROLL is prettier but slower -- it scrolls a line at a time
 *	instead of all at once.
 */

/* move howmany lines starting at from to to */
static void
borscroll(int from, int to, int n)
{
    int i;
    struct text_info t;

    borflush();
    if (to == from)
	return;
#if OPT_PRETTIER_SCROLL
    if (absol(from - to) > 1) {
	borscroll(from, (from < to) ? to - 1 : to + 1, n);
	if (from < to)
	    from = to - 1;
	else
	    from = to + 1;
    }
#endif
    gettextinfo(&t);
    if (to < from) {
	window(1, to + 1, t.screenwidth, from + n);
	gotoxy(1, 1);
	for (i = from - to; i > 0; i--)
	    delline();
	gotoxy(1, n + 1);
	for (i = from - to; i > 0; i--)
	    insline();
    } else {
	window(1, from + 1, t.screenwidth, to + n);
	gotoxy(1, n + 1);
	for (i = to - from; i > 0; i--)
	    delline();
	gotoxy(1, 1);
	for (i = to - from; i > 0; i--)
	    insline();
    }
    window(1, 1, t.screenwidth, t.screenheight);
}

/*--------------------------------------------------------------------------*/
/*
 * Standard terminal interface dispatch table. Most of the fields point into
 * "termio" code.
 */
TERM term =
{
    NROW,
    NROW,
    NCOL,
    NCOL,
    dumb_set_encoding,
    dumb_get_encoding,
    boropen,
    borclose,
    borkopen,
    borkclose,
    ttclean,
    ttunclean,
    nullterm_openup,
    borttgetc,
    borputc,
    bortttypahead,
    borflush,
    bormove,
    boreeol,
    boreeop,
    borbeep,
#if OPT_VIDEO_ATTRS
    bor_attr,
#else
    bor_rev,
#endif
    borcres,
#if OPT_COLOR
    borfcol,
    borbcol,
    borspal,
#else
    nullterm_setfore,
    nullterm_setback,
    nullterm_setpal,
#endif
    nullterm_setccol,
    borscroll,
    nullterm_pflush,
#if OPT_ICURSOR
    boricursor,
#else
    nullterm_icursor,
#endif
    nullterm_settitle,
    nullterm_watchfd,
    nullterm_unwatchfd,
    nullterm_cursorvis,
    nullterm_mopen,
    nullterm_mclose,
    nullterm_mevent,
};
vile-9.8v/btree.c000066400000000000000000000467751415556424100140160ustar00rootroot00000000000000/*
 * $Id: btree.c,v 1.54 2013/02/21 09:53:42 tom Exp $
 * Copyright 1997-2010,2013 by Thomas E. Dickey
 *
 * Maintains a balanced binary tree (aka AVL tree) of unspecified nodes.  The
 * algorithm is taken from "The Art of Computer Programming -- Volume 3 --
 * Sorting and Searching", by Donald Knuth.  Knuth presents the insertion and
 * search algorithms in assembly language for MIX, and gives an overview of the
 * deletion algorithm for the "interested reader".
 *
 * See 6.2.2 for deletion, as well as notes in 6.2.3 for rebalancing.
 */

#ifdef HAVE_CONFIG_H
#include 
#endif

#include 
#include 
#include 
#include 

#if !defined(DEBUG_BTREE) && !defined(NDEBUG)
#define NDEBUG
#endif

#if defined(DEBUG_BTREE)
#if defined(OPT_TRACE) || defined(DOALLOC)
#include "trace.h"
#endif

#ifdef USE_DBMALLOC
#include 
#endif

#ifdef USE_DMALLOC
#include 
#endif

#define castalloc(cast,nbytes) (cast *)malloc((size_t) nbytes)
#define	for_ever for(;;)
#define beginDisplay()		/* nothing */
#define endofDisplay()		/* nothing */

#define	NonNull(s)	((s == 0) ? "" : s)

#include 

#else
#include "estruct.h"
#include "edef.h"
#endif

#include 

#include "btree.h"

			/* definitions to make this simple, like Knuth */
#define	LLINK(p)	BI_LEFT(p)
#define	RLINK(p)	BI_RIGHT(p)
#define	KEY(p)		BI_KEY(p)
#define	B(p)		(p)->balance

#define COMPARE(a,b)	btree_strcmp(a,b)

#define	LINK(a,p)	(p)->links[(a)>0]

#ifdef DEBUG_BTREE
# ifndef TRACE
#  if DEBUG_BTREE > 1
#   define TRACE(p)	printf p ; fflush(stdout)
#  endif
# endif
#elif 1
# undef TRACE
# undef OPT_TRACE
# define OPT_TRACE 0
# define DEBUG_BTREE -1
#else
# define DEBUG_BTREE -1
#endif

#if DEBUG_BTREE > 1
#define TRACE_TREE(s,p)	TRACE((s)); btree_printf(p)
#endif

#if DEBUG_BTREE > 2
#define TRACE_SUBTREE(s,h,p)	TRACE((s)); dump_nodes(h,p,0)
#endif

#ifndef TRACE
#define TRACE(p)		/*nothing */
#endif

#ifndef TRACE_TREE
#define TRACE_TREE(s,p)		/*nothing */
#endif

#ifndef TRACE_SUBTREE
#define TRACE_SUBTREE(s,h,p)	/*nothing */
#endif

#if DEBUG_BTREE >= 0
static int btree_verify(BI_TREE * funcs, BI_NODE * p);
static void dump_nodes(BI_TREE * funcs, BI_NODE * p, int level);
#endif

/*
 * FIXME - this should compare unsigned chars to be completely consistent.
 */
static int
btree_strcmp(const char *a, const char *b)
{
    int cmp = strcmp(a, b);
    if (cmp < 0)
	cmp = -1;
    else if (cmp > 0)
	cmp = 1;
    return cmp;
}

BI_DATA *
btree_insert(BI_TREE * funcs, BI_DATA * data)
{
    /* (A1:Initialize) */

    BI_NODE *t = &(funcs->head);	/* 't' => to the father of 's'  */
    BI_NODE *s = RLINK(t);	/* 's' => to rebalancing point  */
    BI_NODE *p = RLINK(t);	/* 'p' => down the tree         */
    BI_NODE *q;
    BI_NODE *r;

    int a;
    BI_DATA *value = 0;

    TRACE(("btree_insert(%p,%s)\n", funcs, data->bi_key));
    if (p == 0) {
	if ((p = (*funcs->allocat) (data)) == 0)
	    return 0;

	RLINK(t) = p;
	funcs->depth += 1;
	funcs->count += 1;
	return &(p->value);
    }
    /* (A2:Compare) */
    while ((a = COMPARE(data->bi_key, KEY(p))) != 0) {
	/* (A3,A4: move left/right accordingly) */
	if ((q = LINK(a, p)) != 0) {
	    value = &(p->value);
	    if (B(q)) {
		t = p;
		s = q;
	    }
	    p = q;
	    /* ...continue comparing */
	} else {
	    /* (A5:Insert) */
	    if ((q = (*funcs->allocat) (data)) == 0)
		return 0;

	    LINK(a, p) = q;
	    funcs->count += 1;
	    value = &(q->value);

	    /* (A6:Adjust balance factors) */
	    /*
	     * Now the balance factors on nodes between 's' and 'q'
	     * need to be changed from zero to +/- 1.
	     */
	    if (COMPARE(data->bi_key, KEY(s)) < 0)
		r = p = LLINK(s);
	    else
		r = p = RLINK(s);

	    while (p != q) {
		if ((a = COMPARE(data->bi_key, KEY(p))) != 0) {
		    B(p) = (a < 0) ? -1 : 1;
		    p = LINK(a, p);
		}
	    }

	    /* (A7:Balancing act) */
	    a = (COMPARE(data->bi_key, KEY(s)) < 0) ? -1 : 1;

	    if (B(s) == 0) {
		/* ...the tree has grown higher */
		B(s) = a;
		funcs->depth += 1;
	    } else if (B(s) == -a) {
		/* ...the tree has gotten more balanced */
		B(s) = 0;
	    } else {		/* (B(s) == a) */
		assert(B(s) == a);
		/* ...the tree has gotten out of balance */
		TRACE(("...must rebalance\n"));
		if (B(r) == a) {
		    TRACE(("(A8:Single rotation)\n"));
		    p = r;
		    LINK(a, s) = LINK(-a, r);
		    LINK(-a, r) = s;

		    B(s) = B(r) = 0;
		} else {	/* (B(r) == -a) */
		    assert(B(r) == -a);
		    TRACE(("(A9: Double rotation)\n"));
		    p = LINK(-a, r);
		    assert(p != 0);
		    if (p == 0) {
			TRACE(("(BUG: null pointer)\n"));
			break;
		    }
		    LINK(-a, r) = LINK(a, p);
		    LINK(a, p) = r;
		    LINK(a, s) = LINK(-a, p);
		    LINK(-a, p) = s;

		    TRACE(("r=%s\n", KEY(r)));
		    TRACE(("s=%s\n", KEY(s)));
		    TRACE(("B(%s) = %d vs a = %d\n",
			   KEY(p), B(p), a));

		    if (B(p) == a) {
			B(s) = -a;
			B(r) = 0;
		    } else if (B(p) == 0) {
			B(s) = 0;
			B(r) = 0;
		    } else {	/* if (B(p) == -a) */
			B(s) = 0;
			B(r) = a;
		    }

		    B(p) = 0;
		}
		/* A10:Finishing touch */
		t->links[(s == RLINK(t))] = p;
	    }
	    break;
	}
    }
    return (value);
}

#define MAXSTK 100

typedef struct {
    BI_NODE *ptr;
    int dir;
} STACKDATA;

static BI_NODE *
single_rotation(BI_NODE * item, int dir)
{
    BI_NODE *temp = item->links[!dir];

    item->links[!dir] = temp->links[dir];
    temp->links[dir] = item;

    return temp;
}

static BI_NODE *
double_rotation(BI_NODE * item, int dir)
{
    BI_NODE *temp = item->links[!dir]->links[dir];

    item->links[!dir]->links[dir] = temp->links[!dir];
    temp->links[!dir] = item->links[!dir];
    item->links[!dir] = temp;

    temp = item->links[!dir];
    item->links[!dir] = temp->links[dir];
    temp->links[dir] = item;

    return temp;
}

static void
readjust_balance(BI_NODE * item, int dir, int balance)
{
    BI_NODE *next = item->links[dir];
    BI_NODE *last = next->links[!dir];

    if (last->balance == 0) {
	item->balance = next->balance = 0;
    } else if (last->balance == balance) {
	item->balance = -balance;
	next->balance = 0;
    } else {
	/* last->balance == -balance */
	item->balance = 0;
	next->balance = balance;
    }

    last->balance = 0;
}

static BI_NODE *
remove_balance(BI_NODE * item, int dir, int *done)
{
    BI_NODE *next = item->links[!dir];
    int balance = (dir == 0) ? -1 : 1;

    if (next->balance == -balance) {
	item->balance = next->balance = 0;
	item = single_rotation(item, dir);
    } else if (next->balance == balance) {
	readjust_balance(item, !dir, -balance);
	item = double_rotation(item, dir);
    } else {
	/* next->balance == 0 */
	item->balance = -balance;
	next->balance = balance;
	item = single_rotation(item, dir);
	*done = 1;
    }

    return item;
}

int
btree_delete(BI_TREE * funcs, const char *data)
{
    TRACE(("btree_delete(%p,%s)\n", funcs, NonNull(data)));

    if (funcs->count != 0) {
	STACKDATA stack[MAXSTK + 1];
	BI_NODE *item;
	int top = 0;
	int done = 0;

	/* (A1:Initialize) */
	item = &(funcs->head);
	if (item == 0
	    || (item = LINK(1, item)) == 0) {
	    TRACE(("...not found @%d\n", __LINE__));
	    return 0;
	}

	for (;;) {
	    /* (A2:Compare) */
	    if (item == NULL || KEY(item) == 0) {
		TRACE(("...not found @%d\n", __LINE__));
		return 0;
	    } else {
		if (COMPARE(KEY(item), data) == 0) {
		    break;
		}
	    }

	    /* Push direction and node onto stack */
	    assert(top < (MAXSTK - 1));
	    if (top >= MAXSTK) {
		TRACE(("(BUG: stack overflow)\n"));
		return 0;
	    }
	    stack[top].dir = (COMPARE(KEY(item), data) < 0);
	    stack[top].ptr = item;
	    ++top;

	    /* (A3,A4: move left/right accordingly) */
	    item = item->links[stack[top - 1].dir];
	}

	/* D1: Is RLINK null? */
	/* D1.5: Is LLINK null? */
	if (item->links[0] == NULL || item->links[1] == NULL) {
	    /* Which child is not null? */
	    int dir = item->links[0] == NULL;

	    /* Fix parent */
	    if (top != 0)
		stack[top - 1].ptr->links[stack[top - 1].dir] = item->links[dir];
	    else
		LINK(1, &(funcs->head)) = item->links[dir];

	    TRACE(("...freed %p @%d\n", BI_KEY(item), __LINE__));
	    (*funcs->dealloc) (item);
	    funcs->count -= 1;
	} else {
	    /* D2: Find the inorder successor */
	    BI_NODE *child = item->links[1];

	    /* Save the path */
	    assert(top < (MAXSTK - 1));
	    if (top >= (MAXSTK - 1)) {
		TRACE(("(BUG: stack overflow)\n"));
		return 0;
	    }
	    stack[top].dir = 1;
	    stack[top].ptr = item;
	    ++top;

	    /* D3: Find null LLINK */
	    while (child->links[0] != NULL) {
		stack[top].dir = 0;
		stack[top].ptr = child;
		++top;
		child = child->links[0];
	    }

	    /* Swap data */
	    (*funcs->exchang) (item, child);
	    /* Unlink successor and adjust parent */
	    stack[top - 1].ptr->links[stack[top - 1].ptr == item] =
		child->links[1];

	    /* D4: Free the node */
	    TRACE(("...freed %p @%d\n", BI_KEY(child), __LINE__));
	    (*funcs->dealloc) (child);
	    funcs->count -= 1;
	}

	/* Walk back up the stack */
	while (--top >= 0 && !done) {
	    /* Update balance factors */
	    stack[top].ptr->balance += (stack[top].dir != 0) ? -1 : +1;

	    /* Terminate, or rebalance as necessary */
	    if (abs(stack[top].ptr->balance) == 1) {
		break;
	    } else if (abs(stack[top].ptr->balance) > 1) {
		stack[top].ptr = remove_balance(stack[top].ptr,
						stack[top].dir, &done);

		/* Fix parent */
		if (top != 0) {
		    stack[top - 1].ptr->links[stack[top - 1].dir] =
			stack[top].ptr;
		} else {
		    LINK(1, &(funcs->head)) = stack[0].ptr;
		}
	    }
	}
    }

    TRACE(("...found @%d\n", __LINE__));
    return 1;
}

BI_DATA *
btree_search(BI_TREE * funcs, const char *data)
{
    /* (A1:Initialize) */

    BI_NODE *t = &(funcs->head);	/* 't' => to the father of 's'  */
    BI_NODE *p = RLINK(t);	/* 'p' => down the tree         */
    BI_NODE *q;

    int a;

    if (p == 0) {
	return 0;
    }
    /* (A2:Compare) */
    while ((a = COMPARE(data, KEY(p))) != 0) {
	/* (A3,A4: move left/right accordingly) */
	if ((q = LINK(a, p)) != 0) {
	    p = q;
	    /* ...continue comparing */
	} else {
	    break;
	}
    }
    return a ? 0 : &(p->value);
}

/******************************************************************************/

#ifndef BTREE_VERIFY
#define BTREE_VERIFY 1
#endif

#ifndef BTREE_DRIVER
#define BTREE_DRIVER 1
#endif

#if DEBUG_BTREE >= BTREE_VERIFY
static int
btree_count(BI_NODE * p)
{
    int count = 0;
    if (p != 0) {
	count = 1;
	count += btree_count(LLINK(p));
	count += btree_count(RLINK(p));
    }
    return count;
}
#endif

#if DEBUG_BTREE >= BTREE_VERIFY
static int
btree_depth(BI_NODE * p)
{
    int depth = 0;
    if (p != 0) {
	int l, r;
	assert(LLINK(p) != p);
	assert(RLINK(p) != p);
	l = btree_depth(LLINK(p));
	r = btree_depth(RLINK(p));
	depth = 1;
	if (l > r)
	    depth += l;
	else
	    depth += r;
    }
    return depth;
}
#endif

static void
dump_nodes(BI_TREE * funcs, BI_NODE * p, int level)
{
    if (p) {
	dump_nodes(funcs, LLINK(p), level + 1);
	(*funcs->display) (p, level);
#if DEBUG_BTREE > 1
	if (LLINK(p) != 0
	    && COMPARE(KEY(LLINK(p)), KEY(p)) > 0)
	    TRACE((" OOPS:L"));
	if (RLINK(p) != 0
	    && COMPARE(KEY(RLINK(p)), KEY(p)) < 0)
	    TRACE((" OOPS:R"));
	TRACE((" %d", btree_depth(p)));
#endif
#if DEBUG_BTREE >= BTREE_DRIVER
	printf("\n");
#endif
	dump_nodes(funcs, RLINK(p), level + 1);
    }
}

/*
 * Invoke display function for each node
 */
void
btree_printf(BI_TREE * funcs)
{
    TRACE(("TREE, depth %d, count %d\n", funcs->depth, funcs->count));
    dump_nodes(funcs, RLINK(&(funcs->head)), 0);
}

/******************************************************************************/

/*
 * Find the the matching entry given a name in the tree.  Match according to
 * the 'mode' parameter:
 *
 *	If it's FALSE then only the first len characters must match and this
 *	will return the parent of the subtree that contains these entries (so
 *	that an inorder walk can find the other matches).
 *
 *	Use TRUE to force this to return the first of the ordered list of
 *	partial matches; we need this behavior for interactive name completion.
 */
BI_NODE *
btree_pmatch(BI_NODE * n, const int mode, const char *name)
{
    BI_NODE *m = 0;
    size_t len = strlen(name);

    while (n != 0) {
	int cmp;

	cmp = strncmp(name, BI_KEY(n), len);

	if (cmp == 0) {
	    if (mode
		&& (m = btree_pmatch(BI_LEFT(n), mode, name)) != 0)
		n = m;
	    return n;
	} else if (cmp < 0) {
	    n = BI_LEFT(n);
	} else {
	    n = BI_RIGHT(n);
	}
    }
    return 0;
}

/*
 * Find the size of the binary-subtree with the matching name.
 */
static int
btree_pcount(BI_NODE * node, char *matchname, size_t len)
{
    int left = 0;
    int right = 0;
    int me = 0;

    if (BI_LEFT(node) != 0) {
	left = btree_pcount(BI_LEFT(node), matchname, len);
    }

    if ((len == 0)
	|| (strncmp(BI_KEY(node), matchname, len) == 0))
	me = 1;

    if (BI_RIGHT(node) != 0) {
	right = btree_pcount(BI_RIGHT(node), matchname, len);
    }

    return me + left + right;
}

static void
build_parray(BI_NODE * head, char *matchname, size_t len, const char **nptr, int *i)
{
    if (BI_LEFT(head) != 0) {
	build_parray(BI_LEFT(head), matchname, len, nptr, i);
    }

    if ((len == 0)
	|| (strncmp(BI_KEY(head), matchname, len) == 0)) {
	nptr[*i] = BI_KEY(head);
	(*i)++;
    }

    if (BI_RIGHT(head) != 0) {
	build_parray(BI_RIGHT(head), matchname, len, nptr, i);
    }
}

/*
 * Build an array of the keys that partially-match the given name to at least
 * the given length 'len'.
 */
const char **
btree_parray(BI_TREE * tree, char *name, size_t len)
{
    BI_NODE *top;
    const char **nptr = 0;
    top = btree_pmatch(BI_RIGHT(&(tree->head)), 0, name);

    if (top != 0) {
	int i = 0;
	size_t cnt = (size_t) btree_pcount(top, name, len);
	beginDisplay();
	nptr = castalloc(const char *, sizeof(const char *) * (cnt + 1));
	endofDisplay();
	if (nptr != 0) {
	    build_parray(top, name, len, nptr, &i);
	    nptr[i] = 0;
	}
    }
    return nptr;
}

int
btree_freeup(BI_TREE * funcs)
{
    TRACE(("Deleting all nodes...\n"));
    TRACE_TREE("INITIAL-", funcs);
    while (RLINK(&(funcs->head))) {
	TRACE(("Try to delete '%s'\n", KEY(RLINK(&(funcs->head)))));
	if (!btree_delete(funcs, KEY(RLINK(&(funcs->head))))) {
	    TRACE(("Try-delete failed\n"));
	    return 0;
	}
#if DEBUG_BTREE >= 0
	TRACE_TREE("AFTER-DELETE, ", funcs);
	if (!btree_verify(funcs, RLINK(&(funcs->head)))) {
	    TRACE(("Try-verify failed\n"));
	    return 0;
	}
#endif
    }
    return 1;
}

/******************************************************************************/

#if DEBUG_BTREE >= 0

static int
btree_verify(BI_TREE * funcs, BI_NODE * p)
{
#if DEBUG_BTREE >= BTREE_VERIFY
    int ok = 1;

    if (p != 0) {
	int root = (p == &(funcs->head));
	BI_NODE *l = root ? 0 : LLINK(p);
	BI_NODE *r = RLINK(p);
	int balance = 0;
	int compare = 0;

	if (p == RLINK(&(funcs->head))) {
	    int count = btree_count(p);
	    if (count != funcs->count) {
		ok = 0;
		TRACE(("OOPS: Counted %d vs %d in header\n",
		       count, funcs->count));
	    }
	}
	/* verify the balance factor */
	if ((balance = btree_depth(r) - btree_depth(l)) != 0) {
	    if (balance > 0) {
		if (balance > 1) {
		    ok = 0;
		    TRACE(("OOPS: '%s' is unbalanced: %d\n", KEY(p), balance));
		}
		balance = 1;
	    } else {
		if (balance < -1) {
		    ok = 0;
		    TRACE(("OOPS: '%s' is unbalanced: %d\n", KEY(p), balance));
		}
		balance = -1;
	    }
	}
	if (B(p) != balance) {
	    ok = 0;
	    TRACE(("OOPS: Balance '%s' have %d vs %d\n",
		   KEY(p), B(p), balance));
	}

	/* verify that the nodes are in correct order */
	compare = COMPARE(
			     (l != 0) ? KEY(l) : "",
			     (r != 0) ? KEY(r) : "\377");
	if (compare >= 0) {
	    ok = 0;
	    TRACE(("OOPS: Compare %s, have %d vs -1\n",
		   KEY(p), compare));
	}

	/* recur as needed */
	ok &= btree_verify(funcs, l);
	ok &= btree_verify(funcs, r);
    }
    return ok;
#else
    return 1;
#endif
}

#if DEBUG_BTREE >= BTREE_DRIVER

/******************************************************************************/
#undef typecalloc
#define typecalloc(cast) (cast *)calloc(sizeof(cast), (size_t) 1)

static BI_NODE *
new_node(BI_DATA * data)
{
    BI_NODE *result = typecalloc(BI_NODE);
    result->value = *data;
    result->value.bi_key = strdup(data->bi_key);	/* DEBUG-only */
    return result;
}

static void
old_node(BI_NODE * node)
{
    beginDisplay();
    free(BI_KEY(node));
    free(node);
    endofDisplay();
}

static void
dpy_node(BI_NODE * a, int level)
{
    while (level-- > 0)
	printf(". ");
    printf("%s (%d)", KEY(a), B(a));
    fflush(stdout);
}

static void
xcg_node(BI_NODE * a, BI_NODE * b)
{
    BI_DATA value = a->value;
    a->value = b->value;
    b->value = value;
}

static BI_TREE text_tree =
{
    new_node,
    old_node,
    dpy_node,
    xcg_node,
    0,
    0,
    {
	{0, 0}, 0,
	{0, 0}
    }
};

/******************************************************************************/

#define MAX_VEC 10000

static void
test_btree(FILE *fp)
{
    BI_DATA temp;
    BI_NODE *top;
    int n, m;
    int done = 0;
    char buffer[BUFSIZ];
    int vector[MAX_VEC];
    const char **list;

    memset(&temp, 0, sizeof(temp));

    while (!done && fgets(buffer, sizeof(buffer), fp) != 0) {
	char *t = buffer;
	char *s = t + strlen(t);

	if (s != buffer && *--s == '\n')
	    *s = 0;

	if (isalpha(*buffer))
	    printf("%s\n", buffer);

	switch (*t++) {
	case '[':
	case ']':
	case '!':
	case '#':
	case '*':
	    break;
	default:
	    printf("Commands are f(ind) i(nsert), d(elete), l(ist), p(rint), r(andom)\n");
	    break;
	case 'f':
	    n = (btree_search(&text_tree, t) != 0);
	    printf("** find(%s) %d\n", t, n);
	    break;
	case 'i':
	    temp.bi_key = t;
	    n = (btree_insert(&text_tree, &temp) != 0);
	    printf("** insert(%s) %d\n", t, n);
	    break;
	case 'd':
	    n = btree_delete(&text_tree, t);
	    printf("** delete(%s) %d\n", t, n);
	    break;
	case 'l':
	    if ((list = btree_parray(&text_tree, t, strlen(t))) != 0) {
		printf("** list(%s)\n", t);
		for (n = 0; list[n] != 0; n++)
		    printf("[%d] '%s'\n", n, list[n]);
		free((char *) list);
	    } else
		printf("** list(%s) fail\n", t);
	    break;
	case 'L':
	    if ((top = btree_pmatch(RLINK(&text_tree.head), 1, t)) != 0)
		printf("** List(%s) -> '%s'\n", t, KEY(top));
	    else
		printf("** List(%s) fail\n", t);
	    break;
	case 'p':
	    btree_printf(&text_tree);
	    break;
	case 'r':
	    srand((unsigned) time(NULL));
	    for (n = 0; n < MAX_VEC; n++) {
		vector[n] = rand();
		sprintf(buffer, "%d", vector[n]);
		temp.bi_key = buffer;
		(void) btree_insert(&text_tree, &temp);
		printf("** inserted(%s)\n", buffer);
	    }
	    for (m = 0; m < 2; m++)
		for (n = 0; n < MAX_VEC; n++) {
		    unsigned delete = rand() & 1;
		    char *name = delete ? "delete" : "insert";
		    int ok;

		    sprintf(buffer, "%d", vector[n]);
		    printf("** random %s (%s)\n", name, buffer);
		    temp.bi_key = buffer;
		    if (delete)
			ok = btree_delete(&text_tree, buffer);
		    else
			ok = btree_insert(&text_tree, &temp) != 0;
		    if (!btree_verify(&text_tree, RLINK(&(text_tree.head)))) {
			printf("OOPS: Random %s-verify '%s' failed\n", name, buffer);
			btree_printf(&text_tree);
			return;
		    }
		    printf("** result: %d\n", ok);
		}
	    break;
	case 'q':
	    done = 1;
	    break;
	}
	btree_verify(&text_tree, RLINK(&(text_tree.head)));
    }
}

int
main(int argc, char *argv[])
{
    if (argc > 1) {
	int n;

	for (n = 1; n < argc; ++n) {
	    FILE *fp = fopen(argv[n], "r");
	    if (fp != 0) {
		printf("** read commands from \"%s\"\n", argv[n]);
		test_btree(fp);
		fclose(fp);
	    } else {
		perror(argv[n]);
	    }
	}
    } else {
	printf("** read commands from \n");
	test_btree(stdin);
    }

    btree_freeup(&text_tree);

    return 0;
}
#endif /* DEBUG_BTREE >= BTREE_DRIVER */

#endif /* DEBUG_BTREE */
vile-9.8v/btree.h000066400000000000000000000023761415556424100140100ustar00rootroot00000000000000/*
 * $Id: btree.h,v 1.6 2010/05/18 22:59:38 tom Exp $
 *
 * Interface for btree.c
 */
#ifndef BTREE_H
#define BTREE_H 1

#ifndef BI_DATA
#define BI_DATA struct _bi_data
 	BI_DATA {
	char	*bi_key;	/* the key */
	void	*data;		/* ...associated data */
	};
#endif

#define BI_NODE struct _bi_node
	BI_NODE	{
	BI_NODE	*links[2];
	int	 balance;	/* holds 0, -1, +1 */
	BI_DATA  value;
	};

#define BI_TREE struct _bi_tree
	BI_TREE	{
	BI_NODE*(*allocat) (BI_DATA *a);
	void	(*dealloc) (BI_NODE *a);
	void	(*display) (BI_NODE *a, int level);
	void	(*exchang) (BI_NODE *a, BI_NODE *b);
	int	depth;
	int	count;
	BI_NODE	head;		/* root data, on end to ease initialization */
	};

#define	BI_KEY(p)	(p)->value.bi_key
#define	BI_LEFT(p)	(p)->links[0]
#define	BI_RIGHT(p)	(p)->links[1]

#ifdef __cplusplus
extern "C" {
#endif

extern	int	 btree_delete(BI_TREE *tree, const char *data);
extern	int	 btree_freeup(BI_TREE *tree);
extern	BI_DATA *btree_insert(BI_TREE *tree, BI_DATA *data);
extern	const char **btree_parray(BI_TREE *tree, char *name, size_t len);
extern	BI_NODE *btree_pmatch(BI_NODE *n, const int mode, const char *name);
extern	void	 btree_printf(BI_TREE *tree);
extern	BI_DATA *btree_search(BI_TREE *tree, const char *data);

#ifdef __cplusplus
}
#endif

#endif /* BTREE_H */
vile-9.8v/buffer.c000066400000000000000000002072631415556424100141550ustar00rootroot00000000000000/*
 * Buffer management.
 * Some of the functions are internal,
 * and some are actually attached to user
 * keys. Like everyone else, they set hints
 * for the display system.
 *
 * $Id: buffer.c,v 1.372 2021/11/29 00:17:11 tom Exp $
 */

#include	"estruct.h"
#include	"edef.h"

#define	update_on_chg(bp) (!b_is_temporary(bp) || show_all)

static BUFFER *last_bp;		/* noautobuffer value */
static BUFFER *this_bp;		/* '%' buffer */
static BUFFER *that_bp;		/* '#' buffer */
static int show_all;		/* true iff we show all buffers */
static int updating_list;

static int bfl_num_1st;
static int bfl_num_end;
static int bfl_buf_1st;
static int bfl_buf_end;

/*--------------------------------------------------------------------------*/

int
buffer_in_use(BUFFER *bp)
{
    if (bp->b_inuse) {
	mlforce("[Buffer '%s' is in use]", bp->b_bname);
	return TRUE;
    }
    return FALSE;
}

int
buffer_is_visible(BUFFER *bp)
{
    if (bp->b_nwnd != 0) {	/* Error if on screen.  */
	mlforce("[Buffer '%s' is being displayed]", bp->b_bname);
	return TRUE;
    }
    return FALSE;
}

int
buffer_is_solo(BUFFER *bp)
{
    if ((curbp == bp) && (find_alt() == 0)) {
	mlforce("[Can't kill buffer '%s']", bp->b_bname);
	return TRUE;
    }
    return FALSE;
}

/*
 * Returns the buffer-list pointer, if it exists.
 */
static BUFFER *
find_BufferList(void)
{
    return find_b_name(BUFFERLIST_BufName);
}

/*
 * Look for a buffer-pointer in the list, to see if it has been delinked yet.
 */
BUFFER *
find_bp(BUFFER *bp1)
{
    if (bp1 != NULL) {
	BUFFER *bp;
	for_each_buffer(bp) {
	    if (bp == bp1)
		return bp;
	}
    }
    return 0;
}

/*
 * Returns the total number of buffers in the list.
 */
static int
countBuffers(void)
{
    BUFFER *bp;
    int count = 0;
    for_each_buffer(bp)
	count++;
    return count;
}

/*
 * Returns the n'th buffer created
 */
static BUFFER *
find_nth_created(int n)
{
    BUFFER *bp;

    for_each_buffer(bp) {
	if (bp->b_created == n)
	    return bp;
    }
    return 0;
}

/*
 * Returns the n'th buffer used
 */
static BUFFER *
find_nth_used(int n)
{
    BUFFER *bp;

    for_each_buffer(bp) {
	if (bp->b_last_used == n)
	    return bp;
    }
    return 0;
}

/*
 * Returns the buffer with the largest value of 'b_last_used'.
 */
static BUFFER *
find_latest(void)
{
    BUFFER *bp, *maxbp = 0;

    for_each_buffer(bp) {
	if (maxbp == 0)
	    maxbp = bp;
	else if (maxbp->b_last_used < bp->b_last_used)
	    maxbp = bp;
    }
    return maxbp;
}

/*
 * Check if the given string contains only pathname-characters.
 */
static int
is_pathchars(const char *fname)
{
    int result = TRUE;
    int empty = TRUE;
    while (*fname != EOS) {
	if (!ispath(CharOf(*fname)))
	    break;
	empty = FALSE;
	++fname;
    }
    return result && !empty;
}

/*
 * Look for a filename in the buffer-list
 */
BUFFER *
find_b_file(const char *fname)
{
    BUFFER *bp;
    char nfname[NFILEN];

    if (is_pathchars(fname)) {
	(void) lengthen_path(vl_strncpy(nfname, fname, sizeof(nfname)));
	for_each_buffer(bp) {
	    if (same_fname(nfname, bp, FALSE))
		return bp;
	}
    }
    return 0;
}

/*
 * Look for a specific buffer number
 */
BUFFER *
find_b_hist(int number)
{
    BUFFER *bp;

    if (number >= 0) {
	for_each_buffer(bp) {
	    if (!b_is_temporary(bp) && (number-- <= 0))
		break;
	}
    } else
	bp = 0;
    return bp;
}

/*
 * Look for a buffer-number (i.e., one from the buffer-list display)
 */
static BUFFER *
find_b_number(const char *number)
{
    int c = 0;
    while (isDigit(*number))
	c = (c * 10) + (*number++ - '0');
    if (!*number)
	return find_b_hist(c);
    return 0;
}

/*
 * Find buffer, given (possibly) filename, buffer name or buffer number.
 */
static BUFFER *
find_buffer(const char *name)
{
    BUFFER *bp;

    if ((bp = find_b_name(name)) == 0	/* Try buffer */
	&& (bp = find_b_file(name)) == 0	/* ...then filename */
	&& (bp = find_b_number(name)) == 0) {	/* ...then number */
	return 0;
    }

    return bp;
}

/*
 * Find buffer, given (possibly) filename, buffer name or buffer number,
 * warning if we do not find it.
 */
BUFFER *
find_any_buffer(const char *name)
{
    BUFFER *bp;

    if ((bp = find_buffer(name)) == 0)
	mlforce("[No such buffer] %s", name);

    return bp;
}

/*
 * Delete all instances of window pointer for a given buffer pointer
 */
int
zotwp(BUFFER *bp)
{
    WINDOW *wp;
    BUFFER *nbp;
    BUFFER *obp = 0;
    WINDOW dummy;
    int s = FALSE;

    TRACE((T_CALLED "zotwp(%s)\n", bp ? bp->b_bname : "null"));

    if (bp != 0) {

	/*
	 * Locate buffer to switch to after deleting windows.  It can't be
	 * the same as the buffer which is being deleted and if it's an
	 * invisible or scratch buffer, it must have been already visible.
	 * From the set of allowable buffers, choose the most recently
	 * used.
	 */
	for_each_buffer(nbp) {
	    if (nbp != bp && (!b_is_temporary(nbp) || nbp->b_nwnd != 0)) {
		if (obp == 0)
		    obp = nbp;
		else if (obp->b_last_used < nbp->b_last_used)
		    obp = nbp;
	    }
	}

	/* Delete window instances... */
	for_each_window(wp) {
	    if (wp->w_bufp == bp && valid_window(wheadp->w_wndp)) {
		dummy.w_wndp = wp->w_wndp;
		s = delwp(wp);
		wp = &dummy;
	    }
	}
	if (valid_buffer(obp))
	    s = swbuffer(obp);

    }
    returnCode(s);
}

/*
 * Mark a buffer's created member to 0 (unused), adjusting the other buffers
 * so that there are no gaps.
 */
static void
MarkDeleted(BUFFER *bp)
{
    int created = bp->b_created;

    if (created) {
	bp->b_created = 0;
	for_each_buffer(bp) {
	    if (bp->b_created > created)
		bp->b_created -= 1;
	}
    }
}

/*
 * Mark a buffer's last-used member to 0 (unused), adjusting the other buffers
 * so that there are no gaps.
 */
static void
MarkUnused(BUFFER *bp)
{
    int used = bp->b_last_used;

    if (used) {
	bp->b_last_used = 0;
	for_each_buffer(bp) {
	    if (bp->b_last_used > used)
		bp->b_last_used -= 1;
	}
    }
}

/*
 * After 'bclear()', frees remaining storage for a buffer.
 */
static void
FreeBuffer(BUFFER *bp)
{
    int done = FALSE;
    WINDOW *wp;

    beginDisplay();

    if (bp->b_fname != out_of_mem)
	FreeIfNeeded(bp->b_fname);

#if !WINMARK
    if (is_header_line(MK, bp)) {
	MK.l = 0;
	MK.o = 0;
    }
#endif
    lfree(buf_head(bp), bp);	/* Release header line. */
    if (delink_bp(bp) || is_delinked_bp(bp)) {
	if (curbp == bp)
	    curbp = NULL;

#if OPT_HILITEMATCH
	clobber_save_curbp(bp);
#endif
#if OPT_MULTIBYTE
	FreeIfNeeded(bp->decode_utf_buf);
#endif
#if OPT_PERL || OPT_TCL || OPT_PLUGIN
	api_free_private(bp->b_api_private);
#endif
	done = TRUE;
    }

    for_each_window(wp) {
	if (wp->w_bufp == bp) {
	    wp->w_bufp = 0;
	}
    }
    if (done)
	free((char *) bp);	/* Release buffer block */

    endofDisplay();
}

/*
 * Adjust buffer-list's last-used member to account for a new buffer.
 */
static void
TrackAlternate(BUFFER *newbp)
{
    BUFFER *bp;

    if (!updating_list) {
	MarkUnused(newbp);
	if (valid_buffer(bp = find_latest())) {
	    newbp->b_last_used = (bp->b_last_used + 1);
	} else {		/* shouldn't happen... */
	    newbp->b_last_used = 1;
	}
    }
}

/* c is an index (counting only visible/nonscratch) into buffer list */
char *
hist_lookup(int c)
{
    BUFFER *bp = find_b_hist(c);

    return valid_buffer(bp) ? bp->b_bname : 0;
}

/*
 * Run the $buffer-hook procedure, if it is defined.  Note that we must not do
 * this if curwp->w_bufp != curbp, since that would break the use of DOT and MK
 * throughout the program when performing editing operations.
 */
#if OPT_HOOKS
static void
run_buffer_hook(void)
{
    if (!reading_msg_line
	&& valid_buffer(curbp)
	&& valid_window(curwp)
	&& curwp->w_bufp == curbp) {
	run_a_hook(&bufhook);
    }
}
#else
#define run_buffer_hook()	/*EMPTY */
#endif

#define HIST_SHOW 9

/*
 * Display the names of the buffers along with their index numbers on the
 * minibuffer line.  This is normally done in response to "_", i.e.,
 * "historical-buffer".
 *
 * Returns the index of the "#" buffer in the list, so that we can use this in
 * histbuff0() to select "#" when "_" is repeated (toggled).
 */
static int
hist_show(int lo_limit, int hi_limit, int cycle)
{
    int i;
    int first = -1;
    char line[(HIST_SHOW + 1) * (NBUFN + 10)];
    BUFFER *abp = (BUFFER *) 0;

    TRACE((T_CALLED "hist_show(%d..%d) %d\n", lo_limit, hi_limit, cycle));

    if (!global_g_val(GMDABUFF)) {
	abp = find_alt();
    }

    (void) strcpy(line, "");
    for (i = lo_limit; i <= hi_limit; ++i) {
	int j = ((i - lo_limit) + cycle) % (hi_limit + 1 - lo_limit) + lo_limit;
	BUFFER *bp = find_b_hist(j);

	if (bp != 0 && bp != curbp) {
	    if (first < 0)
		first = j;
	    if (!global_g_val(GMDABUFF)) {
		if (abp && abp == bp)
		    first = j;
	    }
	    (void) lsprintf(line + strlen(line), "  %d%s%s %s",
			    j,
			    b_is_changed(bp) ? "*" : "",
			    (abp && abp == bp) ? "#" : "",
			    bp->b_bname);
	}
    }
    if (first >= 0) {
	mlforce("%s", line);
    }
    returnCode(first);
}

static int
valid_history_index(int hist)
{
    BUFFER *bp;
    return ((bp = find_b_hist(hist)) != 0 && bp != curbp);
}

/*
 * Given a buffer, returns any corresponding WINDOW pointer
 */
WINDOW *
bp2any_wp(BUFFER *bp)
{
    WINDOW *wp;
    for_each_visible_window(wp) {
	if (wp->w_bufp == bp)
	    break;
    }
    /*
     * Check for special case where we're running scripts before the screen is
     * initialized, and want to ensure we do not put buffers into wminip.
     */
    if (wp == 0 && !is_vtinit() && wnullp != 0 && wnullp->w_bufp == bp)
	wp = wnullp;
    return wp;
}

/*
 * Worker function for histbuff() and histbuff_to_current_window().
 */
static int
histbuff0(int f, int n, int this_window)
{
    int thiskey, c;
    BUFFER *bp = 0;
    int cycle = 0;
    int first;
    char *bufn;

    if (f == FALSE) {
	int hi_limit = HIST_SHOW;
	int lo_limit = 1;

	/* verify that we have a list which we can display */
	while (!valid_history_index(hi_limit) && hi_limit > 1) {
	    --hi_limit;
	}
	if (valid_history_index(0))
	    lo_limit = 0;
	if (lo_limit > hi_limit)
	    return FALSE;

	thiskey = lastkey;
	do {
	    if ((first = hist_show(lo_limit, hi_limit, cycle)) < 0)
		return FALSE;
	    c = keystroke();
	    mlerase();
	    if (c == KEY_Tab) {
		if (++cycle >= hi_limit)
		    cycle = 0;
		c = -1;
	    } else if (isBackTab((UINT) c)) {
		if (--cycle < 0)
		    cycle = hi_limit - 1;
		c = -1;
	    } else if (c == thiskey) {
		c = first;
	    } else if (isDigit(c)) {
		c = c - '0';
	    } else {
		if (!isreturn(c))
		    unkeystroke(c);
		return FALSE;
	    }
	} while (c < 0);
    } else {
	c = n;
    }

    if (c >= 0) {
	if ((bufn = hist_lookup(c)) == NULL) {
	    mlwarn("[No such buffer.]");
	    return FALSE;
	}
	/* first assume it is a buffer name, then a file name */
	if ((bp = find_b_name(bufn)) == NULL)
	    return getfile(bufn, TRUE);

    } else if (bp == 0) {
	mlwarn("[No alternate buffer]");
	return FALSE;
    }

    return swbuffer_lfl(bp, TRUE, this_window);
}

/*
 * Lets the user select a given buffer by its number.
 */
int
histbuff(int f, int n)
{
    int rc;

    if (!clexec)
	vile_is_busy = TRUE;	/* kill autocolor */
    rc = histbuff0(f, n, FALSE);
    if (!clexec)
	vile_is_busy = FALSE;
    return (rc);
}

/*
 * Like histbuff, but puts buffer in current window.  (Even if the
 * buffer is already onscreen in a different window.)
 */
int
histbuff_to_current_window(int f, int n)
{
    int rc;

    if (!clexec)
	vile_is_busy = TRUE;	/* kill autocolor */
    rc = histbuff0(f, n, TRUE);
    if (!clexec)
	vile_is_busy = FALSE;
    return (rc);
}

/*
 * Returns the alternate-buffer pointer, if any
 */
BUFFER *
find_alt(void)
{
    BUFFER *bp;

    if (global_g_val(GMDABUFF)) {
	BUFFER *any_bp = 0;
	if ((bp = find_bp(curbp)) == 0)
	    bp = bheadp;
	for (; bp; bp = bp->b_bufp) {
	    if (bp != curbp) {
		/*
		 * If we allow temporary buffers to be selected as the
		 * alternate, we get into the situation where we try
		 * to load the message buffer, which has a NULL filename.
		 * Note that the 'noautobuffer' case, below, never selects
		 * a temporary buffer as the alternate buffer.
		 */
		if (!b_is_temporary(bp))
		    return bp;
	    }
	}
	return any_bp;
    } else {
	BUFFER *last = 0, *next = find_latest();

	for_each_buffer(bp) {
	    if ((bp != next)
		&& !b_is_temporary(bp)) {
		if (last) {
		    if (last->b_last_used < bp->b_last_used)
			last = bp;
		} else
		    last = bp;
	    }
	}
	return last;
    }
}

/* make '#' buffer in noautobuffer-mode, given filename */
void
imply_alt(char *fname, int copy, int lockfl)
{
    static int nested;

    BUFFER *bp;
    LINE *lp;
    BUFFER *savebp;
    char nfname[NFILEN];
    char *stripped;

    TRACE((T_CALLED "imply_alt(fname=%s, copy=%d, lockfl=%d)\n",
	   NONNULL(fname), copy, lockfl));

    if (interrupted()
	|| isEmpty(fname)
	|| nested)
	returnVoid();

    if ((stripped = is_appendname(fname)) != 0)
	fname = stripped;

    /* if fname is a pipe cmd, it can be arbitrarily long */
    vl_strncpy(nfname, fname, sizeof(nfname));
    (void) lengthen_path(nfname);

    if (global_g_val(GMDIMPLYBUFF)
	&& valid_buffer(curbp)
	&& curbp->b_fname != 0
	&& !same_fname(nfname, curbp, FALSE)
	&& !isInternalName(fname)) {
	savebp = curbp;
	if ((bp = find_b_file(nfname)) == 0) {
	    L_NUM top = -1;
	    L_NUM now = -1;

	    if ((bp = make_bp(fname, 0)) == 0) {
		mlforce("[Cannot create buffer]");
	    } else {
		/* fill the buffer */
		b_clr_flags(bp, BFINVS | BFCHG);
		b_set_flags(bp, BFIMPLY);
		bp->b_active = TRUE;
		ch_fname(bp, nfname);
		make_local_b_val(bp, MDNEWLINE);
#if OPT_MULTIBYTE
		COPY_B_VAL(bp, curbp, VAL_BYTEORDER_MARK);
		COPY_B_VAL(bp, curbp, VAL_FILE_ENCODING);
#endif
		if (valid_window(curwp) && curwp->w_bufp == curbp) {
		    top = line_no(curbp, curwp->w_line.l);
		    now = line_no(curbp, DOT.l);
		}

		if (copy) {
		    for_each_line(lp, savebp) {
			if (addline(bp, lvalue(lp), llength(lp)) != TRUE) {
			    mlforce("[Copy-buffer failed]");
			    zotbuf(bp);
			    bp = 0;
			    break;
			}
		    }
		    if (bp != 0) {
			set_b_val(bp, MDNEWLINE, b_val(savebp, MDNEWLINE));
		    }
		} else {
		    if (readin(fname, lockfl, bp, FALSE) != TRUE) {
			zotbuf(bp);
			bp = 0;
		    }
		}
	    }

	    /* setup so that buffer-toggle works as in vi (i.e.,
	     * the top/current lines of the screen are the same).
	     */
	    if (bp != 0) {
		if (now >= 0) {
		    for_each_line(lp, bp) {
			if (--now == 0) {
			    bp->b_dot.l = lp;
			    bp->b_dot.o = curbp->b_dot.o;
			    break;
			}
			if (--top == 0) {
			    bp->b_wline.l = lp;
			}
		    }
		}
	    }
	} else if (copy && !b_is_changed(bp)) {
	    nested++;
	    if (bp->b_active == TRUE) {
		if (bp2readin(bp, TRUE) != TRUE) {
		    zotbuf(bp);
		    bp = 0;
		}
	    }
	    nested--;
	}

	DisableHook(&bufhook);
	if (bp != 0) {
	    make_current(bp);
	    infer_majormode(bp);
	}
	make_current(savebp);
	EnableHook(&bufhook);
    }
    returnVoid();
}

/* switch back to the most recent buffer */
/* ARGSUSED */
int
altbuff(int f GCC_UNUSED, int n GCC_UNUSED)
{
    BUFFER *bp;

    TRACE((T_CALLED "altbuff()\n"));
    if ((bp = find_alt()) == 0) {
	mlwarn("[No alternate filename to substitute for #]");
	returnCode(FALSE);
    } else {
	returnCode(swbuffer(bp));
    }
}

#if OPT_BNAME_CMPL
static int
qs_bname_cmp(const void *a, const void *b)
{
    return strcmp(*(const char *const *) a, (*(const char *const *) b));
}

static void
free_bname_cmpl(char **list)
{
    int n;
    for (n = 0; list[n] != 0; ++n) {
	free(list[n]);
    }
    free((char *) list);
}

static char **
init_bname_cmpl(void)
{
    size_t used = 0;
    size_t count;
    char **list = 0;
    BUFFER *bp;

    if ((count = (size_t) countBuffers()) != 0) {
	beginDisplay();
	if ((list = typeallocn(char *, count + 1)) != 0) {
	    for_each_buffer(bp) {
		list[used] = strmalloc(add_backslashes(bp->b_bname));
		if (list[used] == 0) {
		    free_bname_cmpl(list);
		    list = 0;
		    break;
		}
		++used;
	    }
	}
	if (list != 0) {
	    list[used] = 0;
	    qsort(list, used, sizeof(char *), qs_bname_cmp);
	}
	endofDisplay();
    }
    return list;
}

int
bname_complete(DONE_ARGS)
{
    size_t cpos = *pos;
    int status = FALSE;
    char **nptr;

    kbd_init();			/* nothing to erase */
    buf[cpos] = EOS;		/* terminate it for us */

    if ((nptr = init_bname_cmpl()) != 0) {
	status = kbd_complete(PASS_DONE_ARGS, (const char *) nptr, sizeof(*nptr));
	beginDisplay();
	free_bname_cmpl(nptr);
	endofDisplay();
    }
    return status;
}
#endif

/*
 * Prompt for a buffer name (though we may use a filename - it's not a
 * stringent requirement).
 */
int
ask_for_bname(const char *prompt, char *bufn, size_t len)
{
    int status;

    TRACE((T_CALLED "ask_for_bname\n"));
    if (clexec || isnamedcmd) {
#if OPT_BNAME_CMPL
	status = kbd_string(prompt, bufn, len,
			    '\n', KBD_NORMAL | KBD_MAYBEC, bname_complete);
#else
	status = mlreply(prompt, bufn, len);
#endif
    } else if ((status = screen_to_bname(bufn, len)) != TRUE) {
	mlforce("[Nothing selected]");
    }

    returnCode(status);
}

/*
 * Prompt for a buffer name, ignoring if we cannot find it (creating it then).
 */
#define ASK_FOR_NEW_BNAME(prompt, status, bufn, bp) \
    bufn[0] = EOS; \
    if ((status = ask_for_bname(prompt, bufn, sizeof(bufn))) != TRUE \
	&& (status != SORTOFTRUE)) \
	returnCode(status); \
    if ((bp = find_buffer(bufn)) == 0) { \
	bp = bfind(bufn, 0); \
    }

/*
 * Prompt for a existing-buffer name, warning if we cannot find it.
 */
#define ASK_FOR_OLD_BNAME(prompt, status, bufn, bp) \
    bufn[0] = EOS; \
    if ((status = ask_for_bname(prompt, bufn, sizeof(bufn))) != TRUE \
	&& (status != SORTOFTRUE)) \
	returnCode(status); \
    if ((bp = find_any_buffer(bufn)) == 0) { \
	returnCode(FALSE); \
    }

/*
 * Attach a buffer to a window. The
 * values of dot and mark come from the buffer
 * if the use count is 0. Otherwise, they come
 * from some other window.
 */
/* ARGSUSED */
int
usebuffer(int f GCC_UNUSED, int n GCC_UNUSED)
{
    BUFFER *bp;
    int s;
    char bufn[NBUFN];

    TRACE((T_CALLED "usebuffer()\n"));
    ASK_FOR_OLD_BNAME("Use buffer: ", s, bufn, bp);
    returnCode(swbuffer(bp));
}

/*
 * Just like "select-buffer", but we will create the buffer if it does not
 * exist.
 */
int
edit_buffer(int f GCC_UNUSED, int n GCC_UNUSED)
{
    BUFFER *bp;
    int s;
    char bufn[NBUFN];

    TRACE((T_CALLED "edit_buffer()\n"));
    ASK_FOR_NEW_BNAME("Edit buffer: ", s, bufn, bp);
    returnCode(swbuffer(bp));
}

#if !SMALLER
/*
 * Set the current window to display the given buffer.
 */
int
set_window(int f GCC_UNUSED, int n GCC_UNUSED)
{
    BUFFER *bp;
    int s;
    char bufn[NBUFN];

    TRACE((T_CALLED "set_window()\n"));
    ASK_FOR_OLD_BNAME("Set window to buffer: ", s, bufn, bp);
    returnCode(swbuffer_lfl(bp, TRUE, TRUE));
}

/*
 * Open a window for the given buffer.
 */
int
popup_buffer(int f GCC_UNUSED, int n GCC_UNUSED)
{
    BUFFER *bp;
    int s;
    char bufn[NBUFN];

    TRACE((T_CALLED "popup_buffer()\n"));
    ASK_FOR_OLD_BNAME("Popup buffer: ", s, bufn, bp);
    if (bp->b_nwnd == 0)
	returnCode(popupbuff(bp));
    returnCode(TRUE);
}

/*
 * Close all windows which display the given buffer.
 */
int
popdown_buffer(int f GCC_UNUSED, int n GCC_UNUSED)
{
    BUFFER *bp;
    int s;
    char bufn[NBUFN];

    TRACE((T_CALLED "popdown_buffer()\n"));
    ASK_FOR_OLD_BNAME("Popdown buffer: ", s, bufn, bp);
    returnCode(zotwp(bp));
}
#endif /* !SMALLER */

void
set_last_bp(BUFFER *bp)
{
    last_bp = bp;
}

/* switch back to the first buffer (i.e., ":rewind") */
/* ARGSUSED */
int
firstbuffer(int f GCC_UNUSED, int n GCC_UNUSED)
{
    int s = histbuff(TRUE, 0);
    if (!global_g_val(GMDABUFF))
	set_last_bp(s ? curbp : 0);
    return s;
}

/* switch to the next buffer in the buffer list */
/* ARGSUSED */
int
nextbuffer(int f GCC_UNUSED, int n GCC_UNUSED)
{
    BUFFER *bp;
    BUFFER *stopatbp;
    int result = FALSE;

    TRACE((T_CALLED "nextbuffer()\n"));

    if (global_g_val(GMDABUFF)) {	/* go backward thru buffer-list */
	stopatbp = NULL;
	while (stopatbp != bheadp) {
	    /* get the last buffer in the list */
	    bp = bheadp;
	    while (bp != 0 && bp->b_bufp != stopatbp)
		bp = bp->b_bufp;
	    if (bp == 0)
		break;
	    stopatbp = bp;
	    /* if that one's invisible, keep trying */
	    if (!b_is_invisible(bp))
		break;
	}
	/* we're back to the top -- they were all invisible */
	result = swbuffer(stopatbp);
    } else {			/* go forward thru args-list */
	if (last_bp == 0) {
	    set_last_bp(curbp);
	}
	if ((bp = last_bp) != 0) {
	    for (bp = last_bp->b_bufp; bp; bp = bp->b_bufp) {
		if (b_is_argument(bp)) {
		    break;
		}
	    }
	}
	if (bp != 0) {
	    result = swbuffer(bp);
	} else {
	    mlforce("[No more files to edit]");
	    result = FALSE;
	}
    }
    returnCode(result);
}

#if !SMALLER
/* switch to the previous buffer in the buffer list */
/* ARGSUSED */
int
prevbuffer(int f GCC_UNUSED, int n GCC_UNUSED)
{
    BUFFER *bp;			/* eligible buffer to switch to */
    BUFFER *stopatbp;		/* eligible buffer to switch to */
    int result = FALSE;

    TRACE((T_CALLED "prevbuffer()\n"));

    if (global_g_val(GMDABUFF)) {	/* go forward thru buffer-list */
	if ((bp = curbp) == 0)
	    bp = bheadp;
	stopatbp = bp;
	while (valid_buffer(bp) && (bp = bp->b_bufp) != 0) {
	    /* get the next buffer in the list */
	    /* if that one's invisible, skip it and try again */
	    if (!b_is_invisible(bp)) {
		stopatbp = bp;
		break;
	    }
	}
	/* we're back to the top -- they were all invisible */
	result = swbuffer(stopatbp);
    } else {			/* go backward thru args-list */
	if (curbp == 0) {
	    bp = find_nth_created(1);
	} else {
	    bp = find_nth_created(curbp->b_created - 1);
	}
	if (bp != 0) {
	    result = swbuffer(bp);
	} else {
	    mlforce("[No more files to edit]");
	}
    }
    returnCode(result);
}
#endif /* !SMALLER */

/* bring nbp to the top of the list, where curbp usually lives */
void
make_current(BUFFER *nbp)
{
    BUFFER *bp;
#if OPT_PROCEDURES
    BUFFER *ocurbp;

    ocurbp = curbp;
#endif

    TrackAlternate(nbp);

    if (!updating_list && global_g_val(GMDABUFF)) {
	if (nbp != bheadp) {	/* remove nbp from the list */
	    bp = bheadp;
	    while (valid_buffer(bp) && bp->b_bufp != nbp)
		bp = bp->b_bufp;
	    if (valid_buffer(bp))
		bp->b_bufp = nbp->b_bufp;

	    /* put it at the head */
	    nbp->b_bufp = bheadp;

	    bheadp = nbp;
	}
	curbp = bheadp;
    } else
	curbp = nbp;

#if OPT_PROCEDURES
    if (curbp != ocurbp) {
	run_buffer_hook();
    }
#endif

#if OPT_TITLE
    set_editor_title();
#endif
}

/* make buffer BP current */
int
swbuffer(BUFFER *bp)
{
    TRACE((T_CALLED "swbuffer(bp=%p)\n", (void *) bp));
    returnCode(swbuffer_lfl(bp, TRUE, FALSE));
}

#if OPT_MODELINE
#define VI_NAMES "\\(vi\\|vile\\|"PROGRAM_NAME"\\)"
static struct {
    int mark;
    const char *expr;
    regexp *prog;
} mls_patterns[] = {

    {
	3, "^.*\\s" VI_NAMES ":\\s*se\\(t\\)\\?\\s\\+\\(.*\\):.*$", 0
    },
    {
	2, "^.*\\s" VI_NAMES ":\\s*\\(.*\\)\\s*$", 0
    },
};

static regexp *
mls_regcomp(int n)
{
    regexp *prog = 0;
    if (n >= 0 && n < (int) TABLESIZE(mls_patterns)) {
	prog = mls_patterns[n].prog;
	if (prog == 0) {
	    prog = regcomp(mls_patterns[n].expr,
			   strlen(mls_patterns[n].expr), TRUE);
	    mls_patterns[n].prog = prog;
	}
    }
    return prog;
}

#if NO_LEAKS
static void
mls_regfree(int n)
{
    if (n >= 0) {
	if (n < (int) TABLESIZE(mls_patterns)) {
	    if (mls_patterns[n].prog != 0) {
		free(mls_patterns[n].prog);
		mls_patterns[n].prog = 0;
	    }
	}
    } else {
	for (n = 0; n < (int) TABLESIZE(mls_patterns); ++n)
	    mls_regfree(n);
    }
}
#endif

static int
found_modeline(LINE *lp, int *first, int *last)
{
    int rc = 0;
    unsigned n;
    int limit = llength(lp);

    if (limit > modeline_limit)
	limit = modeline_limit;

    for (n = 0; n < TABLESIZE(mls_patterns); ++n) {
	regexp *prog = mls_regcomp((int) n);
	if (lregexec(prog, lp, 0, limit, FALSE)) {
	    int j = mls_patterns[n].mark;
	    *first = (int) (prog->startp[j] - prog->startp[0]);
	    *last = (int) (prog->endp[j] - prog->startp[0]);

	    /*
	     * Real vi may have modes that we do not want to set.
	     */
	    if (prog->endp[1] - prog->startp[1] == 2
		&& !strncmp(prog->startp[1], "vi", (size_t) 2))
		rc = 2;
	    else
		rc = 1;
	}
    }
    return rc;
}

static void
do_one_modeline(LINE *lp, int vi, int first, int last)
{
    TBUFF *data = 0;

    if (lisreal(lp) && first >= 0 && last > first && last <= llength(lp)) {
	tb_sappend(&data, "setl ");

	/*
	 * Trim trailing blanks, e.g., in case we are processing a "set dos"
	 * in a file containing trailing ^M's.
	 */
	while (last > first && isSpace(lgetc(lp, last - 1)))
	    --last;

	tb_bappend(&data, lvalue(lp) + first, (size_t) last - (size_t) first);
	tb_append(&data, EOS);

	in_modeline = vi;
	TPRINTF(("modeline %s:%s\n",
		 ((vi > 1) ? "vi" : PROGRAM_NAME),
		 tb_values(data)));
	docmd(tb_values(data), TRUE, FALSE, 1);
	in_modeline = FALSE;

	tb_free(&data);
    }
}

void
do_modelines(BUFFER *bp)
{
    WINDOW *wp;

    if (b_val(bp, MDMODELINE) &&
	b_val(bp, VAL_MODELINES) > 0 &&
	(wp = bp2any_wp(bp)) != 0) {
	LINE *lp;
	int once = b_val(bp, VAL_MODELINES);
	int limit = 2 * once;
	int count;
	int rc, first = 0, last = 0;
	BUFFER *save_bp = curbp;
	WINDOW *save_wp = curwp;

	/*
	 * If we're sourcing a file, then curbp is not necessarily the same.
	 * Fix that.
	 */
	curwp = wp;
	curbp = bp;

	bsizes(bp);

	TRACE((T_CALLED "do_modelines(%s) limit %d, size %d\n",
	       bp->b_bname, limit, bp->b_linecount));

	count = 0;
	for (lp = lforw(buf_head(bp)); count < once; lp = lforw(lp)) {
	    --limit;
	    ++count;
	    if ((rc = found_modeline(lp, &first, &last)) != 0) {
		do_one_modeline(lp, rc, first, last);
	    }
	}

	count = 0;
	if (bp->b_linecount < limit) {
	    once = bp->b_linecount - once;
	}
	for (lp = lback(buf_head(bp)); count < once; lp = lback(lp)) {
	    ++count;
	    if ((rc = found_modeline(lp, &first, &last)) != 0) {
		do_one_modeline(lp, rc, first, last);
	    }
	}
	curbp = save_bp;
	curwp = save_wp;
	returnVoid();
    }
}
#endif

static int
suckitin(BUFFER *bp, int copy, int lockfl)
{
    int s = FALSE;

    TRACE((T_CALLED "suckitin(%s, %s)\n", bp->b_bname, copy ? "copy" : "new"));
    if (copy) {
	WINDOW *wp;

	for_each_window(wp) {
	    if (wp->w_bufp == bp && (is_visible_window(wp) || bp->b_active
				     != TRUE))
		copy_traits(&(wp->w_traits), &(bp->b_wtraits));
	}
    }
    curwp->w_flag |= WFMODE | WFHARD;	/* Quite nasty.         */

    if (bp->b_active != TRUE) {	/* buffer not active yet */
	s = bp2readin(bp, lockfl);	/* read and activate it */
    }
#ifdef MDCHK_MODTIME
    else
	s = check_file_changed(bp, bp->b_fname);
#endif
    updatelistbuffers();
    run_buffer_hook();
    returnCode(s);
}

/*
 * Make given buffer 'bp' current'.
 */
int
swbuffer_lfl(BUFFER *bp, int lockfl, int this_window)
{
    int status = TRUE;
    WINDOW *wp;

    TRACE((T_CALLED
	   "swbuffer_lfl(bp=%p, lockfl=%d, this_window=%d) bname='%s'\n",
	   (void *) bp, lockfl, this_window, bp->b_bname));

    if (!bp) {
	mlforce("BUG:  swbuffer passed null bp");
	status = FALSE;
    } else {
	TRACE(("swbuffer(%s) nwnd=%d\n", bp->b_bname, bp->b_nwnd));
	if (curbp == bp
	    && valid_window(curwp)
	    && DOT.l != 0
	    && curwp->w_bufp == bp) {	/* no switching to be done */

	    if (!b_is_reading(bp) &&
		!bp->b_active) {	/* on second thought, yes there is */
		status = suckitin(bp, TRUE, lockfl);
	    }
	} else {
#if !WINMARK
	    /* Whatever else we do, make sure MK isn't bogus when we leave */
	    MK = nullmark;
#endif

	    if (valid_buffer(curbp)) {
		/* if we'll have to take over this window, and it's the last */
		if ((this_window || bp->b_nwnd == 0)
		    && curbp->b_nwnd != 0 && --(curbp->b_nwnd) == 0) {
#if !SMALLER
		    if (!this_window)
#endif
			undispbuff(curbp, curwp);
		} else if (DOT.l != 0 && (this_window || bp->b_nwnd == 0)) {
		    /* Window is still getting taken over so make a
		       copy of the traits for a possible future
		       set-window */
		    copy_traits(&(curbp->b_wtraits), &(curwp->w_traits));
		}
	    }

	    /* don't let make_current() call the hook -- there's
	       more to be done down below */
	    DisableHook(&bufhook);
	    make_current(bp);	/* sets curbp */
	    EnableHook(&bufhook);

	    bp = curbp;		/* if running the bufhook caused an error,
				   we may be in a different buffer than we
				   thought we were going to */
	    if (bp == 0) {
		mlforce("BUG:  make_current set null bp");
		status = FALSE;
	    }
#if !SMALLER
	    else if (this_window) {
		/*
		 * Put buffer in this window even if it's already on the screen
		 */
		LINE *lp;
		int trait_matches;

		if (curwp == 0 || curwp->w_bufp == 0)
		    returnCode(FALSE);
		else if (curwp->w_bufp == bp)
		    returnCode(TRUE);

		if (curwp->w_bufp->b_nwnd == 0) {
		    undispbuff(curwp->w_bufp, curwp);
		} else {
		    copy_traits(&(curwp->w_bufp->b_wtraits),
				&(curwp->w_traits));
		}

		/*
		 * Initialize the window using the saved buffer traits if
		 * possible.  If they don't pass a sanity check, simply
		 * initialize the newest window to be a clone of any other
		 * window on the buffer, or initialize it as we do in
		 * popupbuff().
		 */
		trait_matches = 0;
#if WINMARK
#define TRAIT_MATCHES_NEEDED 5
#else
#define TRAIT_MATCHES_NEEDED 4
#endif
		for_each_line(lp, bp) {
		    if (lp == bp->b_dot.l && llength(lp) > bp->b_dot.o)
			trait_matches++;
#if WINMARK
		    if (lp == bp->b_mark.l && llength(lp) > bp->b_mark.o)
			trait_matches++;
#endif
		    if (lp == bp->b_lastdot.l && llength(lp) > bp->b_lastdot.o)
			trait_matches++;
		    if (lp == bp->b_tentative_lastdot.l && llength(lp) > bp->b_tentative_lastdot.o)
			trait_matches++;
		    if (lp == bp->b_wline.l && llength(lp) > bp->b_wline.o)
			trait_matches++;
		    if (trait_matches == TRAIT_MATCHES_NEEDED)
			break;
		}
		if (trait_matches == TRAIT_MATCHES_NEEDED)
		    copy_traits(&(curwp->w_traits), &(bp->b_wtraits));
		else if ((wp = bp2any_wp(bp)) == 0)
		    init_window(curwp, bp);
		else
		    clone_window(curwp, wp);

		curwp->w_bufp = bp;
		status = suckitin(bp, (bp->b_nwnd++ == 0), lockfl);
	    } else
#endif /* !SMALLER */
		/* get it already on the screen if possible */
	    if (bp->b_nwnd != 0) {
		/* then it's on the screen somewhere */
		if ((wp = bp2any_wp(bp)) == 0)
		    mlforce("BUG: swbuffer: wp still NULL");
		curwp = wp;
		upmode();
#ifdef MDCHK_MODTIME
		(void) check_file_changed(bp, bp->b_fname);
#endif
#if OPT_UPBUFF
		if (bp != find_BufferList())
		    updatelistbuffers();
#endif
		run_buffer_hook();
		status = (find_bp(bp) != 0);
	    } else if (curwp == 0) {
		status = FALSE;	/* we haven't started displaying yet */
	    } else {
		if (!is_vtinit()) {
		    curwp = wnullp;
		}
		/* oh well, suck it into this window */
		curwp->w_bufp = bp;
		status = suckitin(bp, (bp->b_nwnd++ == 0), lockfl);
	    }
	}
#if OPT_TITLE
	set_editor_title();
#endif
    }
    if (status == TRUE)
	set_last_bp(bp);
    returnCode(status);
}

#if VILE_NEEDED
/* check to ensure any buffer that thinks it's displayed _is_ displayed */
void
buf_win_sanity(void)
{
    BUFFER *bp;
    for_each_buffer(bp) {
	if (bp->b_nwnd != 0) {	/* then it's on the screen somewhere */
	    WINDOW *wp = bp2any_wp(bp);
	    if (!wp) {
		dbgwrite("BUG: swbuffer 1: wp is NULL");
	    }
	}
    }
}
#endif

int
eql_bname(BUFFER *bp, const char *name)
{
    return (cs_strcmp(global_g_val(GMDFILENAME_IC), bp->b_bname, name) == 0);
}

void
undispbuff(BUFFER *bp, WINDOW *wp)
{
    /* get rid of it completely if it's a scratch buffer,
       or it's empty and unmodified */
    if (b_is_scratch(bp)) {
	/* Save the location within the help-file */
	if (eql_bname(bp, HELP_BufName))
	    help_at = line_no(bp, wp->w_dot.l);
	(void) zotbuf(bp);
    } else if (global_g_val(GMDABUFF) &&
	       !b_is_argument(bp) &&
	       !b_is_changed(bp) &&
	       is_empty_buf(bp)
	       && !ffexists(bp->b_fname)) {
	(void) zotbuf(bp);
    } else {			/* otherwise just adjust it off the screen */
	copy_traits(&(bp->b_wtraits), &(wp->w_traits));
    }
}

#if !OPT_MAJORMODE
/* return true iff c-mode is active for this buffer */
static int
cmode_active(BUFFER *bp)
{
    if (is_local_b_val(bp, MDCMOD))
	return is_c_mode(bp);
    else
	return (is_c_mode(bp) && has_C_suffix(bp));
}
#endif

/* return the correct tabstop setting for this buffer */
int
tabstop_val(BUFFER *bp)
{
#if OPT_MAJORMODE
    int i = b_val(bp, VAL_TAB);
#else
    int i = b_val(bp, (cmode_active(bp) ? VAL_C_TAB : VAL_TAB));
#endif
    if (i == 0)
	return 1;
    return i;
}

/* return the correct shiftwidth setting for this buffer */
int
shiftwid_val(BUFFER *bp)
{
#if OPT_MAJORMODE
    int i = b_val(bp, VAL_SWIDTH);
#else
    int i = b_val(bp, (cmode_active(bp) ? VAL_C_SWIDTH : VAL_SWIDTH));
#endif
    if (i == 0)
	return 1;
    return i;
}

#if !OPT_MAJORMODE
int
has_C_suffix(BUFFER *bp)
{
    int s;
    s = nregexec(global_g_val_rexp(GVAL_CSUFFIXES)->reg,
		 bp->b_fname, (char *) 0, 0, -1,
		 global_g_val(GMDFILENAME_IC));
    return s;
}
#endif

int
kill_that_buffer(BUFFER *bp)
{
    int s;
    char bufn[NFILEN];

    /* ...for info-message */
    (void) vl_strncpy(bufn, bp->b_bname, sizeof(bufn));
    if (buffer_is_solo(bp)) {
	return FALSE;
    }

    if (bp->b_nwnd != 0) {	/* then it's on the screen somewhere */
	(void) zotwp(bp);
	if (find_bp(bp) == 0) {	/* delwp must have zotted us */
	    return FALSE;
	}
    }
    if ((s = zotbuf(bp)) == TRUE)
	mlwrite("Buffer %s gone", bufn);
    return s;
}

static void
free_buffer_list(char **list)
{
    int n;
    for (n = 0; list[n] != 0; ++n) {
	free(list[n]);
    }
    free(list);
}

/*
 * Make a list of buffer names to process.
 */
static char **
make_buffer_list(char *bufn)
{
    BUFFER *bp;
    int count = 0;
    int limit = countBuffers();
    char **result = typecallocn(char *, (size_t) limit + 1);

    if (result != 0) {
#if OPT_FORBUFFERS_CHOICES
#if OPT_GLOB_RANGE
	/*
	 * If it looks like a scratch buffer, try to find exactly that before
	 * possibly getting confused with range expressions, etc.
	 */
	if (global_g_val(GVAL_FOR_BUFFERS) == FB_MIXED
	    && is_scratchname(bufn)
	    && (bp = find_b_name(bufn)) != 0) {
	    result[count++] = strmalloc(bp->b_bname);
	} else
#endif
	    if (global_g_val(GVAL_FOR_BUFFERS) == FB_MIXED
		|| global_g_val(GVAL_FOR_BUFFERS) == FB_GLOB) {
	    for_each_buffer(bp) {
		if (glob_match_leaf(bp->b_bname, bufn)) {
		    result[count++] = strmalloc(bp->b_bname);
		}
	    }
	} else if (global_g_val(GVAL_FOR_BUFFERS) == FB_REGEX) {
	    regexp *exp;

	    if ((exp = regcomp(bufn, strlen(bufn), TRUE)) != 0) {
		for_each_buffer(bp) {
		    if (nregexec(exp, bp->b_bname, (char *) 0, 0, -1, FALSE)) {
			result[count++] = strmalloc(bp->b_bname);
		    }
		}
		free(exp);
	    }
	}
	if (count == 0) {
	    if ((bp = find_buffer(bufn)) != 0) {	/* Try buffer */
		result[count++] = strmalloc(bp->b_bname);
	    }
	}
#else
	if ((bp = find_buffer(bufn)) != 0) {	/* Try buffer */
	    result[count++] = strmalloc(bp->b_bname);
	}
#endif
	if (count == 0) {
	    free_buffer_list(result);
	    result = 0;
	}
    }
    return result;
}

#if !SMALLER
/*
 * Select a set of buffers with the first parameter, and prompt for a command
 * to execute on each buffer.
 */
int
for_buffers(int f, int n)
{
    BUFFER *bp;
    int s;
    char bufn[NFILEN];
    char command[NSTRING];
    char **list;
    int inlist;
    int updated = 0;

    bufn[0] = EOS;
    if ((s = ask_for_bname("Buffers: ", bufn, sizeof(bufn))) != TRUE)
	return s;

    if ((list = make_buffer_list(bufn)) != 0) {
	*command = EOS;
	/*
	 * Don't do command-completion, since we want to allow range
	 * expressions, e.g.,
	 *      :fb *.h %trim
	 *
	 * FIXME: split-out logic in execute_named_command() to allow proper
	 * parsing to linespec and command-verb.
	 */
	if ((s = kbd_string("Command: ",
			    command,
			    sizeof(command),
			    '\n',
			    KBD_QUOTES,
			    no_completion)) == TRUE) {
	    char *save_execstr = execstr;
	    int save_clexec = clexec;

	    for (inlist = 0; list[inlist] != 0; ++inlist) {
		if ((bp = find_b_name(list[inlist])) != 0
		    && swbuffer(bp)) {
		    char this_command[NSTRING];

		    /*
		     * FIXME: does namedcmd() modify what execstr points to?
		     */
		    execstr = vl_strncpy(this_command, command, sizeof(this_command));
		    clexec = TRUE;

		    if (namedcmd(f, n))
			++updated;
		}
	    }
	    execstr = save_execstr;
	    clexec = save_clexec;
	}
	free_buffer_list(list);
    } else {
	mlforce("[No matching buffers]");
    }

    if (updated) {
	mlforce("[Processed %d buffer%s]", updated, PLURAL(updated));
	s = TRUE;
    }
    return s;
}
#endif /* !SMALLER */

/*
 * Dispose of a buffer, by name.  If this is a screen-command, pick the name up
 * from the screen.  Otherwise, ask for the name.  Look it up (don't get too
 * upset if it isn't there at all!).  Get quite upset if the buffer is being
 * displayed.  Clear the buffer (ask if the buffer has been changed).  Then
 * free the header line and the buffer header.
 *
 * If we are given a repeat-count, try to kill that many buffers.  Killing from
 * names selected from the buffer-list is a special case, because the cursor
 * may be pointing to the buffer-number column.  In that case, we must
 * recompute the buffer-contents.  Otherwise, move the cursor down one line
 * (staying in the same column), so we can pick up the names from successive
 * lines.
 */
int
killbuffer(int f, int n)
{
    BUFFER *bp;
    int s;
    char bufn[NFILEN];
    char **list;
    int inlist;
    int removed = 0;

#if OPT_UPBUFF
    C_NUM save_COL;
    MARK save_DOT;
    MARK save_TOP;

    int animated = (f
		    && (n > 1)
		    && valid_window(curwp)
		    && valid_buffer(curbp)
		    && (curbp == find_BufferList()));
    /*
     * Handle special case if we're pointing in the buffer list to either the
     * column containing current buffer number, or buffer names.  Since we'll
     * remove the line containing that information as the buffer-list is
     * updated, we don't want to move down a line at the same time.
     */
    int special = animated && ((DOT.o >= bfl_num_1st && DOT.o < bfl_num_end) ||
			       (DOT.o >= bfl_buf_1st && DOT.o < bfl_buf_end));

    if (animated && !special) {
	save_COL = getccol(FALSE);
	save_DOT = DOT;
	save_TOP = curwp->w_line;
    } else {
	save_COL = 0;		/* appease gcc */
	save_DOT = nullmark;
	save_TOP = nullmark;
    }
#endif

    n = need_a_count(f, n, 1);

    for_ever {
	bufn[0] = EOS;
	if ((s = ask_for_bname("Kill buffer: ", bufn, sizeof(bufn))) != TRUE)
	    break;

	if ((list = make_buffer_list(bufn)) != 0) {
	    for (inlist = 0; list[inlist] != 0; ++inlist) {
		if ((bp = find_b_name(list[inlist])) != 0
		    && kill_that_buffer(bp)) {
		    ++removed;
		}
	    }
	    free_buffer_list(list);
	}

	if (--n > 0) {
#if OPT_UPBUFF
	    if (special)
		(void) update(TRUE);
	    else
#endif
	    if (!forwline(FALSE, 1))
		break;
	} else
	    break;
    }

    if (removed) {
	mlforce("[Removed %d buffer%s]", removed, PLURAL(removed));
	s = TRUE;
    }
#if OPT_UPBUFF
    if (animated && !special) {
	curgoal = save_COL;
	DOT = save_DOT;
	DOT.o = getgoal(DOT.l);
	curwp->w_line = save_TOP;
	clr_typed_flags(curwp->w_flag, USHORT, WFMOVE);
    }
#endif
    return s;
}

/*
 * Unlink a buffer from the list, adjusting last-used and created counts.
 */
int
delink_bp(BUFFER *bp)
{
    BUFFER *bp1, *bp2;

    bp1 = NULL;			/* Find the header.     */
    bp2 = bheadp;
    while (bp2 != bp) {
	bp1 = bp2;
	bp2 = bp2->b_bufp;
	if (bp2 == 0)
	    return FALSE;
    }
    bp2 = bp2->b_bufp;		/* Next one in chain.   */
    if (bp1 == NULL)		/* Unlink it.               */
	bheadp = bp2;
    else
	bp1->b_bufp = bp2;
    MarkUnused(bp);
    MarkDeleted(bp);
    if (bp == last_bp)
	last_bp = 0;
    return TRUE;
}

char *
strip_brackets(char *dst, const char *src)
{
    size_t len;

    if (*src == SCRTCH_LEFT[0])
	src++;
    (void) strcpy(dst, src);
    if ((len = strlen(dst)) != 0
	&& dst[len - 1] == SCRTCH_RIGHT[0]) {
	dst[--len] = EOS;
    }
    return dst;
}

char *
add_brackets(char *dst, const char *src)
{
    if (dst != 0 && src != 0) {
	size_t len = strlen(src);
	if (len > NBUFN - 3)
	    len = NBUFN - 3;
	dst[0] = SCRTCH_LEFT[0];
	(void) strncpy(&dst[1], src, len);
	(void) strcpy(&dst[len + 1], SCRTCH_RIGHT);
    }
    return dst;
}

/* kill the buffer pointed to by bp */
int
zotbuf(BUFFER *bp)
{
    int status;

    TRACE((T_CALLED "zotbuf(bp=%p)\n", (void *) bp));

    if (find_bp(bp) == 0)	/* delwp may have zotted us, pointer obsolete */
	returnCode(TRUE);

    TRACE(("zotbuf(%s)\n", bp->b_bname));

    if (buffer_in_use(bp))
	returnCode(FALSE);
    if (buffer_is_visible(bp))	/* Error if on screen.      */
	returnCode(FALSE);
    if (is_fake_window(wheadp)) {
	WINDOW *wp;
	WINDOW dummy;
	/* Not on screen, but a fake window might refer to it.  So
	   delete all such fake windows */
	for_each_window(wp) {
	    if (is_fake_window(wp)
		&& wp->w_bufp == bp && valid_window(wheadp->w_wndp)) {
		dummy.w_wndp = wp->w_wndp;
		(void) delwp(wp);
		wp = &dummy;
	    }
	}
    }
#if OPT_LCKFILES
    /* If Buffer is killed and not locked by other then release own lock */
    if (global_g_val(GMDUSEFILELOCK)) {
	if (bp->b_active)
	    if (!b_val(curbp, MDLOCKED) && !b_val(curbp, MDVIEW))
		release_lock(bp->b_fname);
    }
#endif
    /* Blow text away.      */
    if ((status = bclear(bp)) == TRUE) {
#if OPT_NAMEBST
	if (tb_values(bp->b_procname) != 0) {
	    delete_namebst(tb_values(bp->b_procname), TRUE, FALSE, 0);
	    tb_free(&(bp->b_procname));
	}
#endif
	FreeBuffer(bp);
	updatelistbuffers();
    }
    returnCode(status);
}

BUFFER *
zotbuf2(BUFFER *bp)
{
    if (zotbuf(bp))
	bp = 0;
    return bp;
}

/* Rename a buffer given a buffer pointer and new buffer name. */
int
renamebuffer(BUFFER *rbp, char *bufname)
{
    BUFFER *bp;			/* pointer to scan through all buffers */
    char bufn[NBUFN];		/* buffer to hold buffer name */
    WINDOW *wp;

    TRACE((T_CALLED "renamebuffer(%s, %s)\n", rbp->b_bname, bufname));

    if (*mktrimmed(vl_strncpy(bufn, bufname, sizeof(bufn))) == EOS)
	returnCode(ABORT);

    bp = find_b_name(bufn);

    if (bp == curbp)
	returnCode(ABORT);	/* no change */

    if (valid_buffer(bp))
	returnCode(FALSE);	/* name already in use */

#if OPT_NAMEBST
    if (is_scratchname(rbp->b_bname)) {
	char procname[NBUFN];
	(void) strip_brackets(procname, rbp->b_bname);
	if (search_namebst(procname, 0)
	    && rename_namebst(procname, bufn, 0) != TRUE)
	    returnCode(ABORT);
    }
#endif
    set_bname(rbp, bufn);	/* copy buffer name to structure */

    for_each_visible_window(wp) {
	if (wp->w_bufp == rbp)
	    wp->w_flag |= WFMODE;
    }

    returnCode(TRUE);
}

static int
rename_specific_buffer(BUFFER *bp)
{
    static char bufn[NBUFN];	/* buffer to hold buffer name */
    const char *prompt = "New name for buffer: ";
    int status;

    /* prompt for and get the new buffer name */
    do {
	if (mlreply(prompt, bufn, (UINT) sizeof(bufn)) != TRUE)
	    return (FALSE);
	prompt = "That name's been used.  New name: ";
	status = renamebuffer(bp, bufn);
	if (status == ABORT)
	    return (FALSE);
    } while (status == FALSE);

    b_clr_scratch(bp);		/* if renamed, we must want it */
    mlerase();
    updatelistbuffers();
    return (TRUE);
}

/* Rename the current buffer */
/* ARGSUSED */
int
namebuffer(int f GCC_UNUSED, int n GCC_UNUSED)
{
    TRACE((T_CALLED "namebuffer()\n"));
    returnCode(rename_specific_buffer(curbp));
}

/*
 * Rename a buffer, may be the current one.
 */
int
name_a_buffer(int f GCC_UNUSED, int n GCC_UNUSED)
{
    BUFFER *bp;
    int s;
    char bufn[NBUFN];

    TRACE((T_CALLED "name_a_buffer()\n"));
    ASK_FOR_OLD_BNAME("Rename buffer: ", s, bufn, bp);
    returnCode(rename_specific_buffer(bp));
}

/* create or find a window, and stick this buffer in it.  when
	done, we own the window and the buffer, but they are _not_
	necessarily curwp and curbp */
int
popupbuff(BUFFER *bp)
{
    WINDOW *wp;

    TRACE((T_CALLED "popupbuff(%s) nwnd=%d\n", bp->b_bname, bp->b_nwnd));
    if (!valid_buffer(curbp)) {
	curbp = bp;		/* possibly at startup time */
	curwp->w_bufp = curbp;
	++curbp->b_nwnd;
    } else if (bp->b_nwnd == 0) {	/* Not on screen yet. */
	if ((wp = wpopup()) == NULL)
	    return FALSE;
	if (--wp->w_bufp->b_nwnd == 0)
	    undispbuff(wp->w_bufp, wp);
	wp->w_bufp = bp;
	++bp->b_nwnd;
    }

    for_each_window(wp) {
	if (wp->w_bufp == bp) {
	    init_window(wp, bp);
	}
    }
    returnCode(swbuffer(bp));
}

/*
 * Invoked after changing mode 'autobuffer', this relinks the list of buffers
 * sorted according to the mode: by creation or last-used order.
 */
void
sortlistbuffers(void)
{
    BUFFER *bp, *newhead = 0;
    int c;

    if (global_g_val(GMDABUFF)) {
	c = 1;
	while (valid_buffer(bp = find_nth_used(c++))) {
	    bp->b_relink = newhead;
	    newhead = bp;
	}
    } else {
	c = countBuffers();
	while (valid_buffer(bp = find_nth_created(c--))) {
	    bp->b_relink = newhead;
	    newhead = bp;
	}
    }

    for (bp = newhead; bp; bp = bp->b_relink)
	bp->b_bufp = bp->b_relink;
    bheadp = newhead;

    updatelistbuffers();
}

/*
 * List all of the active buffers.  First update the special buffer that holds
 * the list.  Next make sure at least 1 window is displaying the buffer list,
 * splitting the screen if this is what it takes.  Lastly, repaint all of the
 * windows that are displaying the list.  A numeric argument causes it to
 * toggle listing invisible buffers; a subsequent argument forces it to a
 * normal listing.
 */
int
togglelistbuffers(int f, int n)
{
    int status;
    BUFFER *bp;

    /* if it doesn't exist, create it */
    if ((bp = find_BufferList()) == NULL) {
	status = listbuffers(f, n);
	/* if user supplied argument, re-create */
    } else if (f) {
	status = listbuffers(!show_all, n);
    } else {
	/* if it does exist, delete the window, which in turn
	   will kill the BFSCRTCH buffer */
	status = zotwp(bp);
    }

    return status;
}

/*
 * Return the status flags ordered so the most important one for [Buffer List]
 * is first.  We use the whole string in $bflags though.
 */
void
buffer_flags(char *dst, BUFFER *bp)
{
    if (valid_buffer(bp)) {
	if (b_is_directory(bp))
	    *dst++ = ('d');
	if (b_is_scratch(bp))
	    *dst++ = ('s');
	if (!(bp->b_active))
	    *dst++ = ('u');
	if (b_is_implied(bp))
	    *dst++ = ('a');
	if (b_is_invisible(bp))
	    *dst++ = ('i');
	if (b_is_changed(bp))
	    *dst++ = ('m');
    }
    *dst = EOS;
}

/*
 * Track/emit footnotes for 'makebufflist()', showing only the ones we use.
 */
#if !SMALLER
static void
footnote(int c)
{
    /* *INDENT-OFF* */
    static struct {
	const char *name;
	int flag;
    } table[] = {
	{ "automatic",	0 },
	{ "directory",	0 },
	{ "invisible",	0 },
	{ "modified",	0 },
	{ "scratch",	0 },
	{ "unread",	0 },
    };
    /* *INDENT-ON* */

    size_t j, next;

    for (j = next = 0; j < TABLESIZE(table); j++) {
	if (c != 0) {
	    if (table[j].name[0] == c) {
		bputc(c);
		table[j].flag = TRUE;
		break;
	    }
	} else if (table[j].flag) {
	    bprintf("%s '%c'%s %s",
		    next ? "," : "notes:", table[j].name[0],
		    next ? "" : " is", table[j].name);
	    next++;
	    table[j].flag = 0;
	}
    }
    if (next)
	bputc('\n');
}
#define	MakeNote(c)	footnote(c)
#define	ShowNotes()	footnote(0)
#else
#define	MakeNote(c)	bputc(c)
#define	ShowNotes()
#endif /* !SMALLER */

/*
 * This routine rebuilds the text in the buffer that holds the buffer list.  It
 * is called by the list buffers command.  Return TRUE if everything works.
 * Return FALSE if there is an error (if there is no memory).  The variable
 * 'show_all' (set if the command had a repeat-count) indicates whether
 * hidden buffers should be on the list.
 */
/* ARGSUSED */
static void
makebufflist(int unused GCC_UNUSED, void *dummy GCC_UNUSED)
{
    BUFFER *bp;
    LINE *curlp;		/* entry corresponding to buffer-list */
    int nbuf = 0;		/* no. of buffers */
    int this_or_that;
    char temp[NFILEN];

    curlp = 0;
    bfl_num_1st = -1;
    bfl_num_end = -1;
    bfl_buf_1st = -1;
    bfl_buf_end = -1;

    if (this_bp == 0)
	this_bp = curbp;
    if (this_bp == that_bp)
	that_bp = find_alt();

    bprintf("      %7s %*s %s\n", "Size", NBUFN - 1, "Buffer name",
	    "Contents");
    bpadc(' ', 6);
    bpadc('-', 7);
    bputc(' ');
    bpadc('-', NBUFN - 1);
    bputc(' ');
    bpadc('-', term.cols - DOT.o);
    bputc('\n');

    /* output the list of buffers */
    for_each_buffer(bp) {
	/* skip those buffers which don't get updated when changed */
#if OPT_UPBUFF
	if (!update_on_chg(bp)) {
	    continue;
	}
#endif

	/* output status flag (e.g., has the file been read in?) */
	buffer_flags(temp, bp);
	if (*temp != EOS)
	    MakeNote(*temp);
	else
	    bputc(' ');

	this_or_that = (bp == this_bp)
	    ? EXPC_THIS
	    : (bp == that_bp)
	    ? EXPC_THAT
	    : ' ';

	if (b_is_temporary(bp)) {
	    bprintf("   %c ", this_or_that);
	} else {
	    char bufnum[NSTRING];

	    bfl_num_1st = DOT.o;
	    sprintf(bufnum, "%3d", nbuf++);
	    bputsn_xcolor(bufnum, -1, XCOLOR_NUMBER);
	    bfl_num_end = DOT.o;
	    bprintf("%c ", this_or_that);
	}

	(void) bsizes(bp);
	bprintf("%7lu ", bp->b_bytecount);

	bfl_buf_1st = DOT.o;
	bprintf("%.*s ", NBUFN - 1, bp->b_bname);
	bfl_buf_end = DOT.o;
	{
	    char *p;

	    if ((p = bp->b_fname) != 0)
		p = shorten_path(vl_strncpy(temp, p, sizeof(temp)), TRUE);

	    if (p != 0)
		bprintf("%s", p);
	}
	bprintf("\n");
	if (bp == curbp)
	    curlp = lback(lback(buf_head(curbp)));
    }
    ShowNotes();
    bprintf("             %*s %s", NBUFN - 1, "Current dir:",
	    current_directory(FALSE));

    /* show the actual size of the buffer-list */
    if (curlp != 0) {
	(void) bsizes(curbp);
	(void) lsprintf(temp, "%7lu", curbp->b_bytecount);
	(void) memcpy(lvalue(curlp) + 6, temp, strlen(temp));
    }
}

#if OPT_UPBUFF
/*
 * (Re)compute the contents of the buffer-list.  Use the flag 'updating_list'
 * as a semaphore to avoid adjusting the last used/created indices while
 * cycling over the list of buffers.
 */
/*ARGSUSED*/
static int
show_BufferList(BUFFER *bp GCC_UNUSED)
{
    int status;
    if ((status = ((!updating_list++) != 0)) != FALSE) {
	this_bp = curbp;
	that_bp = find_alt();
	status = liststuff(BUFFERLIST_BufName, FALSE,
			   makebufflist, 0, (void *) 0);
    }
    updating_list--;
    return status;
}

/*
 * If the list-buffers window is visible, update it after operations that
 * would modify the list.
 */
void
updatelistbuffers(void)
{
    show_mark_is_set(0);
    update_scratch(BUFFERLIST_BufName, show_BufferList);
}

/* mark a scratch/temporary buffer for update */
void
update_scratch(const char *name, UpBuffFunc func)
{
    BUFFER *bp = find_b_name(name);

    if (valid_buffer(bp)) {
	bp->b_upbuff = func;
	b_set_obsolete(bp);
    }
}
#endif /* OPT_UPBUFF */

/* ARGSUSED */
int
listbuffers(int f GCC_UNUSED, int n GCC_UNUSED)
{
    int status;
#if OPT_UPBUFF

    show_all = f;		/* save this to use in automatic updating */
    if (find_BufferList() != 0) {
	updatelistbuffers();
	return TRUE;
    }
    this_bp = 0;
    that_bp = curbp;
    status = liststuff(BUFFERLIST_BufName, FALSE,
		       makebufflist, 0, (void *) 0);
    b_clr_obsolete(curbp);
#else
    show_all = f;
    this_bp = 0;
    that_bp = curbp;
    status = liststuff(BUFFERLIST_BufName, FALSE,
		       makebufflist, 0, (void *) 0);
#endif
    return status;
}

/*
 * This is ": args"
 */
int
vl_set_args(int f, int n)
{
    BUFFER *bp;

    if (end_named_cmd()) {
	return listbuffers(f, n);
    }
    if (any_changed_buf(&bp) != 0) {
	mlforce("Buffer %s is modified.  Use :args! to override",
		bp->b_bname);
	return FALSE;
    }
    return set_files_to_edit("Set arguments: ", FALSE);
}

/*
 * This is ": args!"
 */
int
vl_set_args2(int f, int n)
{
    if (end_named_cmd()) {
	return listbuffers(f, n);
    }
    return set_files_to_edit("Set arguments: ", FALSE);
}

/*
 * The argument "text" points to a string.  Append this line to the buffer. 
 * Handcraft the EOL on the end.  Return TRUE if it worked and FALSE if you ran
 * out of room.
 */
int
addline(BUFFER *bp, const char *text, int len)
{
    int status = FALSE;

    if (add_line_at(bp, lback(buf_head(bp)), text, len) == TRUE) {
	/* If "." is at the end, move it to new line  */
	if (sameline(bp->b_dot, bp->b_line))
	    bp->b_dot.l = lback(buf_head(bp));
	status = TRUE;
    }

    return status;
}

/*
 * Add a LINE filled with the given text after the specified LINE.
 */
int
add_line_at(BUFFER *bp, LINE *prevp, const char *text, int len)
{
    LINE *newlp;
    LINE *nextp;
    LINE *lp;
    int ntext;
    int result = FALSE;

    if (len < 0) {
	if (text != 0) {
	    result = add_line_at(bp, prevp, text, (int) strlen(text));
	} else {
	    result = add_line_at(bp, prevp, "", 0);
	}
    } else {
	nextp = lforw(prevp);
	ntext = len;
	newlp = lalloc(ntext, bp);
	if (newlp != 0) {

	    lp = newlp;
	    if (ntext > 0)
		(void) memcpy(lvalue(lp), text, (size_t) ntext);

	    /* try to maintain byte/line counts? */
	    if (b_is_counted(bp)) {
		if (nextp == buf_head(bp)) {
		    set_local_b_val(bp, MDNEWLINE, TRUE);
		    bp->b_bytecount += (B_COUNT) (ntext + 1);
		    bp->b_linecount += 1;
#if !SMALLER			/* tradeoff between codesize & data */
		    lp->l_number = bp->b_linecount;
#endif
		} else
		    b_clr_counted(bp);
	    }

	    set_lforw(prevp, newlp);	/* link into the buffer */
	    set_lback(newlp, prevp);
	    set_lback(nextp, newlp);
	    set_lforw(newlp, nextp);

	    result = TRUE;
	}
    }
    return result;
}

/*
 * return lines of a named buffer in sequence, starting at DOT
 */
char *
next_buffer_line(const char *bname)
{
    WINDOW *wp = NULL;
    BUFFER *bp;
    B_COUNT blen;
    static TBUFF *lbuf;

    if ((bp = find_b_name(bname)) == NULL)
	return NULL;

    /* if the buffer is in a window, the buffer DOT
     * is the wrong one to use.  use the first window's DOT.
     */
    if (bp->b_nwnd != 0) {
	for_each_visible_window(wp) {
	    if (wp->w_bufp == bp) {
		bp->b_dot = wp->w_dot;
		break;
	    }
	}
    }

    /* out of text? */
    if (is_header_line(bp->b_dot, bp))
	return NULL;

    /* how much left on the current line? */
    blen = (B_COUNT) llength(bp->b_dot.l);
    if (blen > (B_COUNT) bp->b_dot.o)
	blen -= (B_COUNT) bp->b_dot.o;
    else
	blen = 0;

    tb_init(&lbuf, EOS);
    tb_bappend(&lbuf,
	       lvalue(bp->b_dot.l) + bp->b_dot.o,
	       (size_t) blen);
    tb_append(&lbuf, EOS);

    /* move forward, for next time */
    bp->b_dot.l = lforw(bp->b_dot.l);
    bp->b_dot.o = 0;

    /* again, if it's in a window, put the new DOT back where
     * we got it.
     */
    if (bp->b_nwnd != 0 && wp) {
	wp->w_dot = bp->b_dot;
	wp->w_flag |= WFMOVE;
    }

    return (tb_values(lbuf));
}

/*
 * Look through the list of buffers.  Return TRUE if there are any changed
 * buffers.  Buffers that hold magic internal stuff are not considered; who
 * cares if the list of buffer names is hacked.  Return FALSE if no buffers
 * have been changed.  Return a pointer to the first changed buffer, in case
 * there's only one -- it's useful info then.
 */
int
any_changed_buf(BUFFER **bpp)
{
    BUFFER *bp;
    int cnt = 0;
    if (bpp)
	*bpp = NULL;

    for_each_buffer(bp) {
	if (!b_is_invisible(bp) && b_is_changed(bp)) {
	    if (bpp && !*bpp)
		*bpp = bp;
	    cnt++;
	}
    }
    return (cnt);
}

/* similar to above, for buffers that have not been visited */
int
any_unread_buf(BUFFER **bpp)
{
    BUFFER *bp;
    int cnt = 0;
    if (bpp)
	*bpp = NULL;

    for_each_buffer(bp) {
	if (!b_is_invisible(bp) && !bp->b_active) {
	    if (bpp && !*bpp)
		*bpp = bp;
	    cnt++;
	}
    }
    return (cnt);
}

/*
 * Copies string to a buffer-name, trimming trailing blanks for consistency.
 */
void
set_bname(BUFFER *bp, const char *name)
{
    int j, k;
    char *d;

    (void) strncpy0(bp->b_bname, name, (size_t) NBUFN);

    d = bp->b_bname;
    for (j = 0, k = -1; d[j]; j++) {
	if (!isSpace(d[j]))
	    k = -1;
	else if (k < 0)
	    k = j;
    }
    if (k >= 0)
	d[k] = EOS;
}

/*
 * Look for a buffer-name in the buffer-list.  This assumes that the argument
 * is null-terminated.  If the length is longer than will fit in a b_bname
 * field, then it is probably a filename.
 */
BUFFER *
find_b_name(const char *bname)
{
    BUFFER *bp;
    BUFFER temp;

    set_bname(&temp, bname);	/* make a canonical buffer-name */

    for_each_buffer(bp) {
	if (eql_bname(bp, temp.b_bname))
	    return bp;
    }
    return 0;
}

/*
 * Find a buffer, by name.  Return a pointer to the BUFFER structure associated
 * with it.  If the buffer is not found, create it.  The "bflag" is the
 * settings for the flags in in buffer.
 */
BUFFER *
bfind(const char *bname, UINT bflag)
{
    BUFFER *bp;
    LINE *lp;
    BUFFER *lastb = NULL;	/* buffer to insert after */
    BUFFER *bp2;

    for_each_buffer(bp) {
	if (eql_bname(bp, bname))
	    return (bp);
	lastb = bp;
    }

    TRACE((T_CALLED "bfind(%s, %u)\n", bname, bflag));

    beginDisplay();

    /* set everything to 0's unless we want nonzero */
    if ((bp = typecalloc(BUFFER)) == NULL) {
	(void) no_memory("BUFFER");
    } else {
	/* set this first, to make it simple to trace */
	set_bname(bp, bname);

	lp = lalloc(0, bp);
	if (lp == 0) {
	    FreeAndNull(bp);
	    (void) no_memory("BUFFER head");
	} else {

	    /* and set up the other buffer fields */
	    bp->b_values = global_b_values;
	    bp->b_wtraits.w_vals = global_w_values;
	    bp->b_active = FALSE;
	    bp->b_dot.l = lp;
	    bp->b_dot.o = 0;
	    bp->b_wline = bp->b_dot;
	    bp->b_line = bp->b_dot;
#if WINMARK
	    bp->b_mark = nullmark;
#endif
	    bp->b_lastdot = nullmark;
#if OPT_VIDEO_ATTRS
#endif
#if OPT_CURTOKENS
	    set_buf_fname_expr(bp);
#endif
	    bp->b_flag = bflag;
	    bp->b_acount = (short) b_val(bp, VAL_ASAVECNT);
	    bp->b_fname = NULL;
	    ch_fname(bp, "");
	    fileuid_invalidate(bp);
#if OPT_ENCRYPT
	    if (!b_is_temporary(bp)
		&& cryptkey != 0 && *cryptkey != EOS) {
		(void) vl_strncpy(bp->b_cryptkey, cryptkey, sizeof(bp->b_cryptkey));
		set_local_b_val(bp, MDCRYPT, TRUE);
	    } else
		bp->b_cryptkey[0] = EOS;
#endif
	    bp->b_udstks[0] = bp->b_udstks[1] = 0;
	    bp->b_ulinep = 0;
	    bp->b_udtail = 0;
	    bp->b_udlastsep = 0;

	    b_set_counted(bp);	/* buffer is empty */
	    set_lforw(lp, lp);
	    set_lback(lp, lp);

	    /* append at the end */
	    if (lastb)
		lastb->b_bufp = bp;
	    else
		bheadp = bp;
	    bp->b_bufp = NULL;
	    bp->b_created = countBuffers();

	    for_each_buffer(bp2)
		bp2->b_last_used += 1;
	    bp->b_last_used = 1;

#if OPT_PERL || OPT_TCL
	    bp->b_api_private = 0;
#endif
	    set_record_sep(bp, (RECORD_SEP) global_b_val(VAL_RECORD_SEP));
	}
    }
    endofDisplay();
    returnPtr(bp);
}

/*
 * Given a filename, set up a buffer pointer to correspond
 */
BUFFER *
make_bp(const char *fname, UINT flags)
{
    BUFFER *bp;
    char bname[NBUFN];

    makename(bname, fname);
    unqname(bname);

    if (valid_buffer(bp = bfind(bname, flags)))
	ch_fname(bp, fname);
    return bp;
}

/*
 * Create a buffer to display the output of various utility commands, e.g.,
 * [Output].
 */
BUFFER *
make_ro_bp(const char *bname, UINT flags)
{
    BUFFER *bp;

    if (valid_buffer(bp = bfind(bname, flags))) {
	b_set_invisible(bp);
	b_clr_scratch(bp);	/* make it nonvolatile */
	bp->b_active = TRUE;
	set_rdonly(bp, non_filename(), MDVIEW);
    }
    return bp;
}

/*
 * This routine blows away all of the text in a buffer.  If the buffer is
 * marked as changed then we ask if it is ok to blow it away; this is to save
 * the user the grief of losing text.  The window chain is nearly always wrong
 * if this gets called; the caller must arrange for the updates that are
 * required.  Return TRUE if everything looks good.
 */
int
bclear(BUFFER *bp)
{
    LINE *lp;

    if (!b_is_temporary(bp)	/* Not invisible or scratch */
	&&b_is_changed(bp)) {	/* Something changed    */
	char ques[30 + NBUFN];

	(void) vl_strncat(vl_strncpy(ques,
				     "Discard changes to ",
				     sizeof(ques)),
			  bp->b_bname,
			  sizeof(ques));
	if (mlyesno(ques) != TRUE)
	    return FALSE;
    }
#if OPT_UPBUFF
    if (bp->b_rmbuff != 0)
	(bp->b_rmbuff) (bp);
#endif
    b_clr_changed(bp);		/* Not changed          */

    beginDisplay();
    freeundostacks(bp, TRUE);	/* do this before removing lines */
    FreeAndNull(bp->b_nmmarks);	/* free the named marks */
#if OPT_SELECTIONS
    free_attribs(bp);
#endif

    while ((lp = lforw(buf_head(bp))) != buf_head(bp)) {
	lremove2(bp, lp);
    }

    if (bp->b_ulinep != 0) {
	lfree(bp->b_ulinep, bp);
	bp->b_ulinep = 0;
    }
    FreeAndNull(bp->b_ltext);
    bp->b_ltext_end = NULL;

    FreeAndNull(bp->b_LINEs);
    bp->b_LINEs_end = NULL;

    bp->b_freeLINEs = NULL;

    bp->b_dot = bp->b_line;	/* Fix "."              */
#if WINMARK
    bp->b_mark = nullmark;	/* Invalidate "mark"    */
#endif
    bp->b_lastdot = nullmark;	/* Invalidate "mark"    */

#if COMPLETE_FILES || COMPLETE_DIRS
    FreeAndNull(bp->b_index_list);
    bp->b_index_size = 0;
    bp->b_index_counter = 0;
#endif

    b_set_counted(bp);
    bp->b_bytecount = 0;
    bp->b_linecount = 0;

    free_local_vals(b_valnames, global_b_values.bv, bp->b_values.bv);
    endofDisplay();

    return (TRUE);
}

/*
 * Update the counts for the # of bytes and lines, to use in various display
 * commands.
 */
int
bsizes(BUFFER *bp)
{
    int code = FALSE;

    if (valid_buffer(curbp)
	&& !b_is_counted(bp)) {
	LINE *lp;		/* current line */
	B_COUNT ending = (B_COUNT) len_record_sep(bp);
	B_COUNT numchars = 0;	/* # of chars in file */
	L_NUM numlines = 0;	/* # of lines in file */

	/* count chars and lines */
	for_each_line(lp, bp) {
	    ++numlines;
	    numchars += ((B_COUNT) llength(lp) + ending);
#if !SMALLER			/* tradeoff between codesize & data */
	    lp->l_number = numlines;
#endif
	}
	if (!b_val(bp, MDNEWLINE)) {
	    if (numchars > ending)
		numchars -= ending;
	    else
		numchars = 0;
	}

	bp->b_bytecount = numchars;
	bp->b_linecount = numlines;

	TRACE(("bsizes %s %s %d lines, %lu bytes\n",
	       bp->b_bname,
	       b_val(bp, MDDOS) ? "dos" : "unix",
	       numlines,
	       (unsigned long) numchars));

	b_set_counted(bp);
	code = TRUE;
    }
    return code;
}

/*
 * Mark a buffer 'changed'
 */
void
chg_buff(BUFFER *bp, unsigned flag)
{
    WINDOW *wp;

    if (is_delinked_bp(bp))
	return;

    b_clr_counted(bp);
    b_match_attrs_dirty(bp);
    if (bp->b_nwnd != 1)	/* Ensure hard.             */
	flag |= WFHARD;
    if (!b_is_changed(bp)) {	/* First change, so     */
	flag |= WFMODE;		/* update mode lines.   */
	b_set_changed(bp);
    }
    b_set_recentlychanged(bp);
#if OPT_UPBUFF
    if (update_on_chg(bp))
	updatelistbuffers();
#endif
    for_each_visible_window(wp) {
	if (wp->w_bufp == bp) {
	    wp->w_flag |= (USHORT) flag;
#ifdef WMDLINEWRAP
	    /* The change may affect the line-height displayed
	     * on the screen.  Assume the worst-case.
	     */
	    if ((flag & WFEDIT) && w_val(wp, WMDLINEWRAP))
		wp->w_flag |= WFHARD;
#endif
	}
    }
}

/*
 * Mark a buffer 'unchanged'
 */
void
unchg_buff(BUFFER *bp, unsigned flag)
{
    WINDOW *wp;

    if (b_is_changed(bp)) {
	if (bp->b_nwnd != 1)	/* Ensure hard.             */
	    flag |= WFHARD;
	flag |= WFMODE;		/* update mode lines.   */
	b_clr_changed(bp);
	b_clr_counted(bp);
	b_set_recentlychanged(bp);
	b_match_attrs_dirty(bp);

	for_each_visible_window(wp) {
	    if (wp->w_bufp == bp)
		wp->w_flag |= (USHORT) flag;
	}
#if OPT_UPBUFF
	if (update_on_chg(bp))
	    updatelistbuffers();
#endif
    }
}

/* unmark the current buffers change flag */
/* ARGSUSED */
int
unmark(int f GCC_UNUSED, int n GCC_UNUSED)
{
    unchg_buff(curbp, 0);
    return (TRUE);
}

/* write all _changed_ buffers */
/* if you get the urge to tinker in here, bear in mind that you need
   to test:  :ww, 1:ww, :wwq, 1:wwq, all with 1 buffer, both modified and
   unmodified, with 2 buffers (0, 1, or both modified), and with errors,
   like either buffer not writeable.  oh yes -- you also need to turn
   on "autowrite", and try ^Z and :!cmd.

   by default, we should have scrolling messages, a pressreturn call, and
   a screen update.

   any numeric argument will suppress the pressreturn call, and therefore
   also the scrolling of the messages and screen update.

   if you're leaving (quitting, or suspending to the shell, you want the
   scrolling messages, but no press-return, and no update.

   if there's a failure, you want a pressreturn, and an update, and you
   need to return non-TRUE so you won't try to quit.  we also switch to
   the buffer that failed in that case.
*/
int
writeallchanged(int f, int n)
{
    return writeall(f, n, !f, FALSE, FALSE, FALSE);
}

int
writeallbuffers(int f, int n)
{
    return writeall(f, n, !f, FALSE, FALSE, TRUE);
}

int
writeall(int f, int n, int promptuser, int leaving, int autowriting, int all)
{
    BUFFER *bp;			/* scanning pointer to buffers */
    BUFFER *nbp;
    BUFFER *oldbp;		/* original current buffer */
    int status = TRUE;
    int count = 0;
    int failure = FALSE;
    int dirtymsgline = FALSE;

    TRACE((T_CALLED
	   "writeall(f=%d, n=%d, promptuser=%d, leaving=%d, autowriting=%d, all=%d)\n",
	   f, n, promptuser, leaving, autowriting, all));

    beginDisplay();
    oldbp = curbp;		/* save in case we fail */

    /*
     * We cannot use for_each_buffer() for this loop, because make_current()
     * will temporarily change the order of the linked list of buffers, putting
     * its argument at the beginning of the list unless autobuffer is set false
     * (in other words, there's the possibility of an infinite loop).  We can't
     * temporarily change autobuffer's setting either, since that changes the
     * list order.  Hence the use of 'nbp'.
     */
    for (bp = bheadp; bp != 0; bp = nbp) {
	nbp = bp->b_bufp;
	if (!(bp->b_active))
	    /* we don't have it anyway - ignore */
	    continue;
	if (autowriting && !b_val(bp, MDAUTOWRITE))
	    continue;
	if (b_val(bp, MDREADONLY) && (n != SPECIAL_BANG_ARG))
	    /* ignore read-only buffer */
	    continue;
	if (((all && !is_internalname(bp->b_fname))
	     || b_is_changed(bp))
	    && !b_is_invisible(bp)) {
	    make_current(bp);	/* do this so filesave() works */
	    if (dirtymsgline && (promptuser || leaving)) {
		mlforce("\n");
	    }
	    status = filesave(f, n);
	    dirtymsgline = TRUE;
	    failure = (status != TRUE);
	    if (failure) {
#define SAVE_FAILED_FMT "[Save of %s failed]"

		int outlen;
		char tmp[NFILEN];

		mlforce("\n");
		outlen = ((term.cols - 1) -
			  (int) (sizeof(SAVE_FAILED_FMT) - 3));
		mlforce(SAVE_FAILED_FMT,
			path_trunc(is_internalname(bp->b_fname)
				   ? bp->b_bname
				   : bp->b_fname,
				   outlen,
				   tmp,
				   (int) sizeof(tmp)));
		/* dirtymsgline still TRUE */
		break;
#undef SAVE_FAILED_FMT
	    }
	    count++;
	}
    }
    endofDisplay();

    /* shortcut out */
    if (autowriting && !failure && !count)
	returnCode(TRUE);

    /* do we want a press-return message?  */
    if (failure || ((promptuser && !leaving) && count)) {
	if (dirtymsgline)
	    mlforce("\n");
	dirtymsgline = FALSE;
	pressreturn();
    }

    /* get our old buffer back */
    make_current(oldbp);

    /* and then switch to the failed buffer */
    if (failure && !insertmode /* can happen from ^Z and autowrite */ )
	swbuffer(bp);

    /* if we asked "press-return", then we certainly need an update */
    if (failure || ((promptuser && !leaving) && count)) {
	sgarbf = TRUE;
	(void) update(TRUE);
    } else if (dirtymsgline && (promptuser || leaving)) {
	mlforce("\n");
    }

    /* final message -- appears on the message line after the update,
       or as the last line before the post-quit prompt */
    if (count)
	mlforce("[Wrote %d buffer%s]", count, PLURAL(count));
    else
	mlforce("[No buffers written]");

    if (dirtymsgline)
	sgarbf = TRUE;

    returnCode(status);
}

#if OPT_TITLE
void
set_editor_title(void)
{
    static TBUFF *title;
    const char *format;

    if (auto_set_title) {

	/*
	 * We don't use "%b" for current buffer since the current
	 * window may not correspond, depending on how we're invoked.
	 */
	if (tb_length(title_format) != 0)
	    format = tb_values(title_format);
	else
	    format = global_g_val(GMDSWAPTITLE)
		? "%{$cbufname} - %{$progname}"
		: "%{$progname} - %{$cbufname}";
	special_formatter(&title, format, curwp);
	tb_copy(&request_title, title);
    }
}
#endif

/* For memory-leak testing (only!), releases all buffer storage. */
#if NO_LEAKS
static BUFFER *
zap_buffer(BUFFER *bp)
{
    TRACE(("zap_buffer(%s) %p\n", bp->b_bname, (void *) bp));
    if (bp != 0) {
	b_clr_changed(bp);	/* discard any changes */
	bclear(bp);
	FreeBuffer(bp);
    }
    return 0;
}

void
bp_leaks(void)
{
    BUFFER *bp;

    TRACE((T_CALLED "bp_leaks()\n"));
    bminip = zap_buffer(bminip);
    btempp = zap_buffer(btempp);
    while ((bp = bheadp) != 0) {
	(void) zap_buffer(bp);
    }
#if OPT_MODELINE
    mls_regfree(-1);
#endif
    returnVoid();
}
#endif
vile-9.8v/buglist000066400000000000000000001732121415556424100141300ustar00rootroot00000000000000------------------------
-- vile:txtmode
------------------------
vile bug/enhancement/wish list (mostly wishes ;-)
------------------------
$Id: buglist,v 1.419 2020/01/17 23:24:30 tom Exp $
----------------------
	(E means enhancement, L,M,H are low, medium, high priority)

E	add ":n file"
	    (:n means go to the next file in a series of files.
	    :n file means go to that specific file - one can specify a
	    + before file to indicate the vi command which should be
	    executed when entering the command.)

E	:k, to set a mark, won't work as ":ka" or ":kb".  Must use ":k a"

E	patterns as addresses do not work, e.g. ":/str1/,/str2/d".  They're
	hard to parse the way things are set up right now.  We could accumulate
	the whole commandline, and then parse it, the way real vi does, but we'd
	lose the "prompt and display last response" behavior.

E	should add an option to support file locking, rather than the current
	ifdef stuff.  (this is only useful if we match the GNU locking
	protocol.) And it's not clear that in an NFS'ed environment that
	it's all that easy to get that style of locking right anyway.

E	the scrsearch functions could become region based -- as in "search for
	the next occurrence of the region", which would usually be a word.  And
	the ^A/ version could become "a/ (search for the contents of buffer a),
	if you know what I mean.

E	g should become a region command.  Then it could take ranges, as
	it should, and could also become an operator command.

E	collapse command execution code to as few places as possible.
	Its currently spread through execute(), operator(),
	docmd(), and usekreg().

E	I haven't even come close to testing vile for
	memory-full conditions.  Some malloc() packages give 95%
	warnings -- perhaps something like that should be done for
	safety.

E	marks should perhaps be linked onto lines.  this would make a lot
        of things a lot easier, since a mark would travel with the
        line, instead of having to be moved when the line is
        reallocated etc.  the U line could be treated as a special
        mark.  The "copied" flag needed by undo could be a special
        sort of mark as well.  Implementation of the "tag stack"
	would be aided by this as well.

E	":e" and ":e!" should share the same prompt data, which should be
	editable / history.  They both should default (like vi!) to the
	current buffer.

E	for consistency, 'execute-macro-nn' should be 'execute-macro nn';
	doing this would allow modification to eliminate a fixed number of
	macro-buffers.

--------------

    The ed 'transfer' and 'move' commands don't work.
    (to copy and move text around.  e.g., :'a,'bt$.)

--------------------------------

Though I use it, I'm still not quite satisfied with the qident stuff.  It
needs to be more flexible.  That is, I'd like to make it user defined.
For example
	find-tag $qidentifier
should be expressible as a character class like
	find-tag &anyof "a-zA-Z_0-9:"
in a macro.  Or even more generally, as a regular expression:
	find-tag &scan "[a-zA-Z_][a-zA-Z_0-9:]\\*"
A leading ^ would root the search at the current cursor position.
Absence of a leading ^ would start at the current cursor position but would
scan ahead until it found a match.  That way I can redefine ^] to pick
up the next word even if the cursor is before the start of the word (thus
better mimicking vi's behavior).

[ This can almost be done with the $match variable, e.g.
	7 store-macro
		search-forward "[a-zA-Z_][a-zA-Z_0-9:]*"
		find-tag $match
	~endm

	bind-key execute-macro-7 ^A-g
 - pgf ]
----------------------------------------------------------------------
Also, I encountered the following problem: I am editing foo.tex and
call latex using ^X!latex foo.tex. There is an error, so latex waits for
input -> vile sits waiting and nothing helps. I think this should
be interruptible. I will agree with you that the ^X! command was not
intended for this, but still...

But ok, the real problem is that after I kill latex and
vile comes back to life I can no longer filter parts of text using
!fmt. The text just gets deleted.

----------------------------------------------------------------------

I just grabbed a copy of xvi.  I noted some interesting tidbits while
reading the "differences between vi and xvi" document.  Some of these would
be nice in vile.

     As well as the normal named (conjugate) buffers, and the  default
     one  named @, several extra buffers named :, /, ?  and ! contain
     the last command lines entered for each of the command types.  So
     for  instance,  @: will re-execute the last colon command, or you
     can insert it into your buffer, edit it and  then re-execute  it
     (e.g. with dd@@).

     +    In insert and replace modes, ^A has the same meaning  as  ^@
          in  vi,  except  that it works at any time, not just for the
          first character.  Also, typing ^Bx, where x is the name of a
          conjugate  buffer,  inserts the contents of that buffer into
          the input stream at that point.  The buffer named  <  always
          contains the last thing inserted, so that ^B< is the same as
          ^A.

------------------------
I wish ^X-!  could execute shell commands async'ly, i.e.  I should not have
to wait/do nothing while waiting for the output of compiling.  I should be
able to edit stuff in other buffers or even ^X-^X to edit src codes
while compilation is still going on.

------------
similar to above -- sub-commands run from ^X-! or ":[erw] !cmd" should be
"interactive" to the extent that user's input should be sent to the cmd
at least on a line-by-line basis (i.e. we can't send raw keystrokes -- we
have to do canonical processing.  of course, we should really use pty's, and
reconnect input and capture output.)  some commands like latex prompt for
more input when partway done.

========(VMS-VILE)=============================================================
Unfinished items on vax/vms [tom]

	+ if the current directory has changed, offer to restore it on exit.
	  (Note that if the _device_ portion has changed, the original
	  directory should be restored anyway!).

	+ add key bindings and other support to make the vt100 keypad work for
	  me (e.g., like EDT).

	+ see if I can decode ".dia" files, if so connect it to finderr.c

	+ catch exception/signals, and restore terminal settings.

	+ make write-pipes work (actually, flesh out to use 'npopen' coding
	  scheme, like the MSDOS stuff).

	+ I had a case in which I wanted to read the contents of one file into
	  another; they had the same buffer name; the target buffer got the
	  filename for the source, e.g.,

	  	:e []foo		- read and determined version # ok
		:r [-.temp]foo		- current filename reset to [-.temp]foo
------------------------------------------------------------


it would be nice if vile would fold text...

	This feature appeared in uEmacs version 3.10.23 and you can
use archie/xarchie to file fue.tar.Z (fue - folding-micro-emacs).

[ someone said they were going to fold this in, so to speak.  i'm not
real comfortable with the idea, since the uemacs code causes the LINE
struct to grow _enormously_ ]


-----------

	When I execute a keyboard macro using ^X-& I cannot repeat this
	using the dot command. Instead, the last command in the macro
	is repeated.
    [ this is because '.' doesn't do @ macros either...]

------------------------------


Can you add the '>' character to the list of comment chars for paragraph
reformatting?  I would live to be able to reformat mail quotes (like shown
above).

[ pgf notes: I did this, as chris suggested, but formatregion should use
  the comments regexp to match a comment delimiter at the beginning of
  line, and should insert the comment delimiter of the _second_ line (so
  that boxed C comments work right)in subsequent reformatted lines,
  including leading but not trailing whitespace.  indentlen should be
  counted _after_ the width of such a comment delimiter.  this would make
  paragraphs that are indented way after the delimiter keep their indent.
  commented paragraphs should end when exp->mlen for the comment regexp is
  equal to llength(DOT), i.e.  it's the whole line.  (we'll need to take
  the $ off the end of the comment regexp).  ]

------------------------------
Another enhancement.
How about a history file.  say I have been using vile and
quit and come back in later I can use the history file.

--------------------------

In a xterm window the down arrow (which sends ESC-O-B) works for individual
presses.  If you hold down the key then letter Bs get peppered through out
the file.  It appears that the ESC is occasionally being missed so that the
following OB puts a B in the file.

In my case I'm on a workstation running 4.1.3 and xterm using rlogin to
connect to a 690 server (lightly loaded) running 4.1.3 and running vile
on the 690.

I just ran vile locally and didn't see the problem.
-------------------------------


I found a bug (new with 3.59) on our Pyramid SVR4 (but not Pyramid SVR3,
SunOS 4.1.1, AIX 3.2) where
	xvile tmp &
pops up the xvile window briefly, the window dies, the xterm I started
xvile from says
	[1]  + suspended (tty input)  xvile3.59 tmp
and then after a couple seconds the xterm itself vanishes!  However,
	xvile tmp
works fine, except that the process is in the foreground.
 > The bug on the Pyramid SVR4 machine with xvile & suspending itself,
 > committing suicide, and then blowing away the xterm still exists.
 > For the time being I just remember to run xvile on a different
 > machine.

-------------------------------------------------------------------------

With vim 1.27 you can configure its behaviour regarding backspace using
the 'backspace' variable. From the help file:

backspace (bs)	    number    0     0 standard Vi, 1 delete NL, 2 delete all
i.e. if bs is non-zero, you can backup to the previous line, and if it's
a 2, you can backup past the insertion point.

i don't think this is optimal -- i think you should be able to choose
independently whether you backup past the newline or past the insertion point.

in any case, vile won't let you back up past the newline during an insert.
when _not_ in insert, you can rebind ^H to backward-character.

---------------------------

When you do a :b you should have line completion for the name.

---------------------------

How can I read the status of a shell command when I execute a
shell-command? Although the shell command has a $STATUS=1 the
status of the status variable is TRUE.

---------------------------

you can't use ! as a regular expression delimiter, as in:
	:s!pat!replace!g
because the parser treats ":s!" as if it's ":q!" or ":w!".

-------------------------

width of a region is kept in units of offset, not of columns.
i think this will break rectangular inserts of non-rectangular regions,
where the longest line may not extend to the furthest column, due to
tabs in other lines.

---------------------------

the borland console driver won't display the cursor on blank lines until
after you've refreshed the screen at least once, e.g. with ^L.  must
be something to do with color initialization, or something like that...

---------------------------

running a SunOS4.1.3 binary of vile on Solaris2.3 causes the "interrupted
system call" problem, no doubt due to the differing BSD/SysV signal()
semantics.  [ probable workaround:  ":set noworking" ]

----------------------

Another thing that would be really helpful would be a description of the
$debug variable, and what it does, how it works.

-------------------------------

there should be better support in vile for reading bits of shell output
into a buffer -- ":r !foo" is a little primitive when trying to insert a
single word into a line.

---------------------------------

autoindent skips blank lines when looking for the
indent value.  apparently real vi doesn't?

----------------------

currently can't pop/untag from within macro
[really?  why is this?]

------------------

are there still reentrancy problems in xvile when mousing around during
long-running operations.

----------------------

could the attribute selection logic be used to emulate vi's behavior
of replacing the last char of a change operation to '$'?  (but only for
text which does not span a line)

-------------------------

there should be a way to reference buffer attributes of the currently-
executing macro (or stack of macros).

-------------------------

[ how do i test this? ]
In xvile, when the load is high and the machine stalls for a while
and I key in several keystrokes ahead, it takes the first of those keystrokes
and replaces the later keys by it i.e. when several events simultaneously
arrive, it doesn't do the right thing (process them in order).

-----------------

when motion keys or pasting is used during an insertion, we should
break the insertion into multiple undoable chunks.
-----------------

pasting to a view-only buffer does not generate an error message.
----------------------------

   XVILE BUG:

      - If I click on the "maximize" gadget, it gets _really_ big.
        Like, many times bigger than the screen big; I suspect that
        it is maximizing to a number of *characters* equal to the number
        of *pixels* available or something.  If I click on the same
        gadget (after dragging that part of the window onto the screen),
        which does a normalize, it crashes.
	I am use vile 4.5 and xvile on HP/UX 9.01.
	I use vuewm as my window manager (a motif variant).

      [I would guess that the suspicion of the person reporting the bug
       is correct concerning the behavior of the window manager during
       maximization.  I don't have this problem with fvwm. pgf's changes
       to eliminate the hardcoded maximum width and height will probably
       fix the core dumps.  I'll look into seeing if there is some protocol
       which we're not observing with regard to maximization.  -kev]

----------------------

if you have lines like
	123
	1234
	12
it's impossible to select them as a rectangle, since the middle line is
longest.


----------------


It would be useful to have a search that is constrained to a certain
movement.  For example, I might want to look for the string "foo" over the
next paragraph, not the whole document.  This would really be useful to
programmers who want to look for the instance of a variable or a function
call only within the current scope (or #if).

----------------
xvile:
 Is it possible to have an optional horizontal scrollbars ?
   (just for maniac users)

----------------------------

under DOS, ^P character turns on the printer.   argh.
actually, this only happens if compiled with borland.  it uses getch()
instead of intdos() to get the char.  (see ttgetc())  that's probably
at least part of the answer.
[I also see this with djgpp, which uses borland.c - tom]

---------------
how about a mode that supports autosaving to the backup-file,
instead of to the original file -- useful for system crashes.

-----------------

rectangular operations don't work right if there are control characters
to the left of the rectangle.  (physically they work, but the visual
effect is wrong.  i'm not sure what the right thing to do is.)

-------------------------
double quote characters (and probably other special chars) are interpreted
incorrectly on the lhs of a map command.  for instance:
	map ^K" WBi"^[Ea"^[
will result in
	^K WBi
as the lhs, leaving
	^[Ea"^[
as the rhs.  the workaround is to escape the " in the lhs:
	map ^K\" WBi"^[Ea"^[

(this map surrounds the current word in double quotes)

-----------------------------

Would you please add another hook: modify-hook.  I thought this is useful,
for example, if I attempt to insert, delete (in general, modify) text
in a read-only file, I like it to prompt if the user wants to PVCS-lock it.
A message would look something like this:
	File is read-only, check out?

-----------------------------

contrary to the vile.hlp text, binding to the interrupt{} terminal
character does not fully change intrc and the user's interrupt character.

-----------------------------------------------------------------

DOS:  wildcarding in the top directory:
   c:
   cd \
   vile a*.bat             (will not open autoexec.bat)
does not work, because Watcom's opendir() routine only succeeds on the root
directory if it is specified as '\'.  no other name for it seems to work.
stat won't work on it either.  (we try to open it as ".", not an unreasonable
thing to do.)

sigh.  i hate DOS.

-----------------------------------------------------------------

 Mips RISCos5.0 machines:
    Error: random.c, line 625: 'SIG_BLOCK' undefined, ...
    Error: random.c, line 637: 'SIG_SETMASK' undefined, ...
 [ i thought i could provide fallback definitions of those, but
   the values are different on sunos and linux, and are probably
   different again on Mips RISCos5.0, bless it's broken little heart. ]

-----------------------------------------------------------------
we should consider adding user-customizable menu or button support to
xvile:
    "Right now, you have most of the major functions as strings that can be
    called from the macro language.  Suppose you made icons or something
    for those strings, and then let the user string the icons (or maybe
    have icons trigger macros and have a set of macros for most of the
    basic stuff as a default package) together to form new icons they could
    put in some sort of icon bar.  The windows (boo!  Hiss!) users would go
    nuts!  Also, put some of this into the pull down menus, and people
    would stand to cheer and applaud. "
-----------------------------------------------------------------

I think I found a couple of very minor bugs in vile.

Possible bug #1)
I'm using xvile right now because ^S doesn't seem to work correctly in
regular vile yet (must be an HP 9.05 thing, I'm not sure yet).  I had
thought you turned flow control off in vile, but I want to do more testing
before I call this a bug.

Anyway, do this:

On a page with several lines of text, do this operation on the first one:

:s/^/> /

Now, using the mouse (or 'q'), sweep the next couple of lines.  To make
things interesting, sweep to the end of the second to last line, but
not the last line itself, so the highlighted text looks like this:

xxxxxxxx
xxxxxxxx
xxxxxxxx

instead of

xxxxxxxx
xxxxxxxx
xxxxxxxx
x

Now, do a

^A-&-^S

On my machine, the last line of the highlighted text isn't touched.  I'm
thinking it should be...

-----------------------------------------------------------------

the command ":r !ls" should not require the space.

-----------------------------------------------------------

when using wrapmargin, it is impossible to break
up long lines consisting of a single word.

[vi doesn't do this]

-----------------------------------------------------------
	- the layering of the map code with respect to the record/replay
	  code that implements '.', the keyboard macros, and the '@'
	  command execution is severely broken.  if you have a :map
	  that executes a '@a' command in the middle, the contents
	  of register a are readied for replay, but input continues
	  to come from the :map string until it is ended, and only then
	  so we dip down to the lower level and start getting the result
	  of '@a'.  a similar thing happens with '.' used in a :map, only
	  it seems even worse, since recording isn't started/stopped
	  correctly.
	[this has been fixed for the @a case, but in a sloppy fashion.
	  it should be cleaned up.  -pgf  ]

-----------------------------

Using xvile, if I [oO]pen a
new line or do insert at the beginning of a line, and then paste in
some text using the mouse, xvile inserts an extra blank line. that is,
if I have

foo
bar

and I try to paste in 'hi' under the foo, I get

foo

hi
bar

this only seems to happen in autoindent mode at the very beginning of
the line. it does *not* happen if the preceding line is indented, or
if I type a space before pasting.
----------------

only "reverse" works as a visual-match hilite under DOS.

---------------

a newly entered search string (even an identical one) should turn visual-match
highlighting back on.  this is surprisingly hard, due to the layering of
readpattern() and kbd_reply.

---------------

While we're on the subject of bugs, let me tell you about another one that
I've long noticed when I try to insert such text.  I would like to do
:unsetl ai before pasting in the text (since I normally have auotindent
on).  But that has no effect.  Even :setall shows that autoindent is still
on.  Instead I have to do :setl noai.  Annoying.

[ i agree -- shouldn't "setl nonumber" and "unsetl number" be synonymous? -pgf]
[ I've gotten used to it as a quirk: "unsetl" deletes a flag that shadows the
  global setting.  I wish (however) that there were a nice way to highlight the
  flags that are shadowed -dickey]

---------------

running a shell command from xvile should arguably spawn a new xterm.  it
should certainly do it in a new window.

---------------

vile trims all trailing whitespace when user inserts a space that triggers
wrapmargin, vi trims only the whitespace inserted during the current command.
[ i'm not sure i consider this a bug.  vile plays loose with whitespace
in many such situations.  if you're using wrapmargin, you're probably
not worried about trailing whitespace anyway.  -- pgf ]

--------------------------

This is a report against vile v5.4 built using djgpp.  Vile is running
in raw DOS (not in a Windows DOS box).

This command:
    vile -4
gives me 50 lines (not 43).  The only two screen resolutions that seem
to work are vile -2 and vile -5 .

[ This is a result of the borland screen library.  43 lines are available
under OS/2... ]

---------------------------------
.. you can't use the mouse to select text from the command input line, I often
use this after Ctrl+G to get the filename for a UNIX command elsewhere.

---------------------------------
.. button 1 selection doesn't work it quite the same way as other apps. e.g.
in xterm, double click on a word (don't release button after second click)
and drag along a sentence - first word is selected and so are subsequent
words in the sentence as you drag.  Just the first word is selected in xvile.

---------------------------------

vile 5.5 almost passed my macro test with only small cosmetic problem:

;    !@  --mapto-->  replace "Unixcommand!@" with "Unixcommand" output
map! !@ ^V^M^[bi:r !^[F:"adt@mm@ais^["bd$dd`m@b
;    #@  --mapto-->  replace "@Unixcommand args#@" with "Unixcommand" output
map! #@ ^V^M^[F@s:r !^[F:"adt@mm@ais^["bd$dd`m@b

Both now produce correct results.  But the final status message doesn't
make sense:  Delete operation pending...  when it actually in insert
mode.  Fortunately, there is a workaround, set terse.  it would be nice
if vile can temporary set terse before executing macros and reset back
to original mode afterwards. Sounds easy?

------------------------

there are two conflicting wordwrap mechanisms in vile --
	- the historical wrapwords setting, inherited from
	  microemacs, will wrap words in input mode when you type a
	  space character after you've passed the "fillcol" column.
	- the vi-like "wrapmargin" setting sets the column past which
	  entering more input will cause a line break.

i think we should eliminate the historical mechanism in favor of the vi-ish
one, and i've marked it [deprecated] in vile.hlp.  (as of version 5.6)
vim has a "textwidth" mode, which functions exactly like wrapmargin, except
that it is measured from the left.  this prevents line length from changing
when the screen is resized, a drawback of wrapmargin.  i propose eliminating
fillcol, and introducing textwidth.

--------------------------------------

It would be nice to have a 'smart' shiftwidth, that would jump back
to the indent level of the first previous line with a different
indent level. What I mean is:

aaa aa aa aaa aaa a
    - bb bbb bb bb bb b
      ccc cc cc cc c
      

where  would jump back to the indent level of the minus sign.
I encountered this behaviour with the 'EDIT' program on MS-DOS with
the backspace key. It's really quite convenient, although I am not so
sure it is smart to put both the 'shift-back' and 'backspace' behaviour
under the same key.

------------------------

The 'qsort' function in Watcom 10.0a for MS-DOS is broken (file-completion
hangs, probably due to stack overflow).

OS/2 version built with Watcom 10.0a does not open pipes successfully.  Also it
does not do function keys.

------------------------

when a buffer is out of date wrt its file (i.e. you have been warned but
you answered 'n') it should say something like [out-of-date] on the modeline.
this should be true whether or not "check-modtimes" is on.  in fact, in
retrospect, "check-modtimes" should really be "warn-out-of-date", or
something like that, and we should _always_ check modification times.

---------------------

Not sure if this will be generally useful, but I changed the tags.c
module to use "_qident" instead of "_ident" in the gototag() function.
This allows a user to goto C++ functions when the tag is a C++
class::function reference.

-----------------------------

add a copyright to the binary

------------------
The configure script returns the wrong value for HAVE_SYS_FILIO_H on
OSF/1-Alpha; termio.c doesn't compile with that problem.

also, the configure script returns the wrong value for GETPGRP_HAS_ARG on the
OSF/1-Alpha.

The test in configure compiles ok with "cc" but not with gcc.
ac_compile in configure uses cc as a default. This may be able
to be worked around by setting $CC to gcc before running
configure.


The install program is also much touchier about argument order; the
directory must follow -c argument.

Here's a partial diff which I think shows part of what must be done:

*** makefile.orig       Thu Feb 15 11:56:40 1996
--- makefile    Thu Feb 15 11:56:41 1996
***************
*** 404,410 ****

  # dependency-rules for install/installdirs
  $(bindir)/$(TARGET):       $(TARGET)
!       $(INSTALL_PROGRAM) $(TARGET) $@
  $(bindir)/vile-manfilt:    vile-manfilt
        $(INSTALL_PROGRAM) vile-manfilt $@
  $(bindir)/vile-c-filt:     vile-c-filt
--- 404,410 ----

  # dependency-rules for install/installdirs
  $(bindir)/$(TARGET):       $(TARGET)
!       $(INSTALL_PROGRAM) $@ $(TARGET)
  $(bindir)/vile-manfilt:    vile-manfilt
        $(INSTALL_PROGRAM) vile-manfilt $@
  $(bindir)/vile-c-filt:     vile-c-filt


But on the other hand, it also doesn't want the final name of the
binary in the path mentioned (bad: /usr/local/bin/vile; good: /usr/local/bin/);
I don't know enough make magic to get the basename stripped off. Perhaps
the "$@" should just be $(bindir).


----------------------
Another point of irritation is the autoindent behavior when inserting
blank lines; where vi will continue with a reduced indent after typing a
CTRL-D, vile insists on keeping the indent on par with the last non-empty
line.  (^^D is intended to be temporary, 0^D should be permanent, even if
what you've entered is a blank line.  don't know about simple ^D.)

----------------------

file completion doesn't work in the presence of directories which match
a substring of other files or directories.  that is:
	:!mkdir foo
	:!mkdir food
	:!mkdir fool
	:e foo
yields:
	:e foo/
instead of also providing "food" and "fool" as choices.  with the same
setup, the following:
	:e food
yields:
	:e food/
instead of also providing "fool".

------------------------

When the various DOS/Windoze) .zip files are created, it would be nice if
they included a formatted version of the man page ('cuz DOS/Windoze doesn't
have nroff :-) ).
-----------

	I'm using vile 5.6 on Unix and I'm wondering if you could add to
the next release of vile a method of bringing up a permanent list of
buffers automatically on startup i.e.  execute the show-buffers command on
startup.  [I realise that you haven't fully implemented the + command line
option in vile ]

------------
using '&' in pc-vile as the word-expansion replacement for ':' in regular
vile may someday conflict if we want to spawn stuff in the background
in VMS or win32 vile.  clearly the expansion chars should be made
selectable.  not a big deal yet....

------------------

"visual-matches" mode should be conditional on file size, or perhaps
on time taken to do the search...

-----------------
 > It seems that some files were in the zipfile vil60dos.zip with the read
 > only parameter set.  I unzipped them with infozip's unzipper instead
 > of pkunzip, and this became a read-only attribute on the vile.hlp
 > file.  If this is set, vile.exe can't find it.

----------------- (tom)

These are old wishes/bugs:

	not every system declares the struct-type for utime/utimes.

	make partial-completion in [History] set DOT to the current line
	we're matching from, if [History] is visible.

	make vile know about different types of tags-files (ctags -s, etags),

These date back to 5.4:

	+ should next_column() use HIGHBIT test?

	+ ':' expansion doesn't work with ":write-file" because DOT is
	  commandeered for use in a region.

	+ should allow '$' in identifiers (or make it an option), and modify
	  'tags' to correspond

These are pre-6.0 (undated)

	use CSet C/C++ to flush out unsigned stuff, especially flags that
	ought to be.

	add configure-test for 'ospeed'

	implement gpm

	vi sets '#' on attempted write; vile doesn't

--------------------------------------------------------------------------------

-- 96-09-27 (Lance Heller )

	If I start an aixterm:
		aixterm -bd Wheat -fg Wheat -bg MidnightBlue -ms grey90
	the problem does NOT occur.

	However, if I start it as:
		aixterm -geometry 90x70+110+1
	it does.

	The appropriate section from my .Xdefaults is:
		aixterm*background:     lightsalmon
		aixterm*foreground:     black
		aixterm*saveLines:      1024
		aixterm*scrollPosition: left
		aixterm*pointerColor:   black
		aixterm*fullCursor:     true
		!aixterm.geometry:      90x73+448+0
		aixterm*jumpScroll:     true
		aixterm*font:   -ibm-serf-medium-r-normal-iso9241-10-100-75-75-*-*:
		aixterm*scrollBar:      true
		aixterm*multiScroll:    false
		aixterm*iconName:       aixterm
		aixterm*pointerShape:   pirate

-- 96-10-02 (tom)

add state (variables) to allow a macro to pick up the beginning/ending of a
selected area.

-- 96-10-14 (tom)

add 'mouse-hook' command (maybe generalize with "on" command)

-- 96-10-16 (tom)

implement $title for tcap.c

-- 96-10-19 (tom)

getting an error in $buffer-hook can blow away the buffer that's being hooked
(e.g., if it's a temporary file).

-- 96-10-25 (Anand Mandapati )

	The behavior of 'yq' doesn't seem to match the behavior of other quoted
	motion operations.  Here are some sample scenarios:

	    I) Yank a single line NOT including the eol, ie, like 'y$'
	       1. I type 'yq$q' to yank the line all the way to the eol but
		  don't want to include the eol.
	       2. I then do a 'P' to put this yanked text before the cursor.
	       3. It behaves as 'y$P' would.

	    II) Yank a single line including the eol, ie, like 'yy'
	       1. I type 'yqjq' to yank the line all the way to the eol and
		  want to include the eol in the selection.
	       2. I then do a 'P' to put this yanked text before the cursor.
	       3. It behaves as 'y$P' would, not as 'yyp' would.

	At first I thought maybe this is the expected behavior, but if I use
	'c' to change the same selections instead of yank, the behavior seems
	different.  Let me clarify:

	    I) Change a single line NOT including the eol, ie, like 'c$'
	       1. I type 'cq$q' to change the line all the way to the eol but
		  don't want to include the eol.
	       2. This deletes all the way to the end of the line and I can
		  now type like normal.

	    II) Change a single line including the eol (no equiv. in vi?)
	       1. I type 'cqjq' to change the line all the way to the eol and
		  want to include the eol in the deletion.
	       2. This deletes the entire line including the eol, shifts the
		  next line up to the cursor and I can now type the replacement
		  text.

	The behavior for 'd' and other quoted-motion operations is similar.
	The 'yq' behavior doesn't seem logical.  Do I just not understand it
	correctly?

[I've seen a case of off-by-one on end of selections, possibly related - tom]

-- 96-11-09 (tom)

modify xvile blink_interval to use 2/3 duty-cycle

-- 96-11-22 (tom)

it should be possible to recode the tcap.c mouse-motion to use 'select()' to
check for the user holding down the mouse button, and use _that_ to control a
fake scrolling in the general direction of the mouse.

-- 97-01-17 (tom)

probably should use WINMARK logic, but it's too late (pre-7.0) to do this now.

-- 97-01-17 (tom)

mouse-clicking should set the position so I can use ` or ' to jump back.

-- 97-01-18 (Paul Fox )

	another one i saw this afternoon:  i got into a state where typing
	    ":!rm append"
	in an attempt to remove a file named "append" gave me
	    "[Improper line range]"
	i was able to clear the condition with
	    ":!  ^H^Hrm append"
	i haven't been able to reproduce this one.

-- 97-01-19 (Abraham V. George" )

	While working with huge src files I find it very convenient to keep
	bookmarks.  If I use markers, i would loose them if I were to re-open
	the file.  One way I get through it is to make a book mark file of
	'tags' file format.  I can then get to that src line the same way I use
	ctags reference.

-- 97-01-23 (Clayton Weaver )

reports problem running a curses application within a shell buffer, wants
documentation clarified.  Shell buffers, since they are the output from
redirecting stdout and stderr, won't look like the curses application intended.
(And since they don't accept interactive input, the curses application won't
work well, even when stdin is reconnected to /dev/tty).

-- 97-01-25 (tom)

when filtering, etc., via a pipe, we're interruptible and may be killed (at
least when running in gdb).

-- 97-02-09 (tom)

should add gcc's -Wwrite-strings warnings

-- 97-02-10 (tom)

on VMS, we don't get filename completion with "~", since that's not processed
in glob.c

-- 97-02-26 (Andy Harper )

	Under VMS, the location of the package should be in a rooted directory
	tree, let's say VILE_ROOT:[000000], with subdirectories for VAX
	executables [BIN_VAX], Alpha executables [BIN_ALPHA], documentation
	[DOC] and configuration [CONFIG].

[I believe he's suggesting it be installed this way - tom]

-- 97-03-08 (Otto Lind )

I've been a user of vile since vile-3.33, and have noticed an obnoxious
bug which has appeared in later versions (I'm at 7.0).  If you try and
execute the vi sequence:

        1,$s:/:_:

it reports "[No pattern.]" when pressing the first ':'. The following
does work:

        1,$s^/^_^

But my fingers are hardwired to use : as the substitution delimiter.

-- 97-04-02 (Clark Morgan )

Write pipes are broken on DOS.

-- 97-04-23 (Ron Olsen )

I recently built version 7.0h of vile and xvile on my UnixWare 2.03 system.

vile and xvile (X11 version) seem to work well, but I'm having a problem with
filename completion with the MOTIF/menu version of xvile:

I have to hit TAB three times to get the list of possible completions, and then
when I enter the completion and hit Enter, xvile ignores the Enter key until I
use the mouse to scroll a window, and then hit Enter again.  It looks as if
there are circumstances in which keyboard input is being ignored.

I also have minor pixelization problem with the MOTIF version:  a thin red
border gets drawn around my window the second time I hit TAB during filename
completion.

-- 97-05-16 (Richard A Ward )

I just started using vile 7.1 and I think there may be a new bug.  When I
delete a large number of lines and try to undo, vile seems to hang.

-- 97-05-25 (Guido Socher )

Quoted motion should be usable as ranges for the colon commands.  I.e., you
type "q:  motion-command q" and only complete lines are marked.  The cursor
jumps to the command input line as soon as you type the final q and prints the
range (e.g., 3,28).

-- 97-06-05 (tom)

The 'map' functions should allow mappings with embedded nulls.

-- 97-06-24 (Peter Gallasch )

No core dump was made, and no file in /tmp/ was created

[Reports a problem where xvile 7.1 exited with SIGIOT, no apparent reason.  I
tried duplicating it, with limited success:  after running several hours with
Purify, xvile exited (I think the linewrap logic is involved, he uses it in his
.vilerc).  However, I'd not told Purify to follow child processed (which is
needed for X).  Doing that, I had no repeat of the problem.  - tom]

-- 97-06-27 (Curt Smith )

One xvile problem that only manifests itself on svr4 boxes is that when
exec'ing a shell via:  ^x!  or reading in a new file with wild cards, xvile is
sent a SIGSTP due to an attempt to fool with stdout/stderr or some such?

This problem has come and gone and doesn't exist on non-SVR4 systems like
Linux, DEC Unix that I've issued.  Does exist on UnixWare, NCR Unix and
Solaris.

I had version of 6.x xvile that did not have this problem but had other X
problems.  I compiled 7.0 and now this problem is back.

[the fix for this is to use the +fork option, or use the forkOnStartup resource
since spawning a new xvile process establishes a new process group - tom]

-- 97-07-07 (Larry Gensch )

I have noticed another oddity in the 7.1 version of vile:  I use the window
manager fvwm2.0.45, and use the following focus policies:

Style "*"	ClickToFocus, RandomPlacement, SmartPlacement
GlobalOpts	ClickToFocusPassesClick,ClickToFocusRases

When xvile is launched from an xterm, it occasionally doesn't auto-focus like
it used to.  In other words, I have always expected xvile to become the window
with the focus when it pops up (even if the cursor isn't in the window).  Has
something changed between the last 6.x version and version 7 that would cause
this behavior?

-- 97-08-26 (Ed Henderson )

I have been using vile for quite some time now. I use the file/function
name completion a lot.

Recently I started using Solaris. Now when I press Tab the vile (xvile)
window enters some sort of selected state. The border changes to include
a thin highlighted region around the inside perimeter, and further keystrokes
have no effect. A second press of the tab key clears this condition.

When completing a filename, I must press tab once, which completes the name
and enters the selected state, then press tab again to clear the selected
state. I generally hit tab one too many/few times and am already typing the
next 10 commands :-), so I get really screwed up.

-- 97-09-02 (tom)

The majormode code leaks memory in the qualifiers (e.g., suffixes and
preamble).

-- 97-09-04 (tom)

format-til does not work on rectangular regions (it should also take
into account the comment-prefix).

-- 97-09-11 (Keith Williams )

In xvile, do the following:

    - select a word with the mouse (double-click)
    - move the cursor to a line above the selection (ie: type "kkk")
    - open a line (either 'o' or 'O')
    - note that the text and selection behave correctly
    - press ESC and then undo the line opening
    - note that the text moves up, but the selection does not!

-- 97-09-16 (lar3ry gensch )

The new menu code puts a tiny bar across the top of the screen even if no menus
are defined.  That is, if I do not create menus but the menuing code is enabled
in xvile, it will still put up a tiny (5- or so- pixel) menubar without any
menu buttons in it.  This is visually distracting and wastes some screen
real-estate.

-- 97-09-17 (Robert Chady )

There is one feature that I have not been able to find in vile.  Was wondering
if you could tell me if I'm missing it, or if it really isn't there.  If it
isn't there, maybe you could put it in :)

The feature is the ability to have reverse wraparound.  This is for when you
backspace to the beginning of the line, rather than have to exit edit mode, go
into command mode, move up a line, and continue erasing the line, have it
automatically reverse wraparound.  This is similar to emacs/joe/etc/etc and is
a very nice feature when you are trying to edit part of a sentence that is on
multiple lines.

[the arrow keys and others that generate escape sequences such as home/end
can move the cursor around in edit mode, though this is not exactly what
he's asking for - tom]

-- 97-11-12 (Scott Waldon )

I was introduced to vile about 2 years ago and am really enjoying using it.
However, there is one little but very annoying bug that I am experiencing.  I
switched to using vile about the same time that I switched to CDE and dtterms
(instead of xterms).  In a dtterm the status line on the bottom is constantly
overwritten by some arbitrary line from the file forcing me to ^L constantly to
keep from being confused by stray "}" or other statements...

...Essentially, open any file, goto the bottom such that the last line lines up
just above the message line.  Then H and  which should scroll the
screen down by one and overwrite the message line.  When I was capturing the
script output it also did it on the scroll down as well.

[this is a bug in dtterm:  for example, scrolling lines 1-22 will cause line 23
to be written to line 22 rather than clearing line 22.  The fix is to disable
scrolling regions (csr) in the terminfo description - tom]

-- 97-11-27 (tom)

should make tags-stack based on a buffer rather than its struct so I could
simply kill it.

-- 97-12-03 (tom)

The --without-shell configure option is experimental; note that a genuinely
secure editor should not allow directory names to be specified (but I think
that's the only omission).

-- 97-12-03 (tom)

EMX configuration looks ok (function keys, pipes, name-completion, color),
except that there's nothing to allow changing to a different device (e.g.,
"c:").  Must check/see if EMX supports that.  The termcap files distributed
with EMX are incomplete & incorrect (should we distribute our own?).

-- 97-12-03 (tom)

Recently investigated two "POSIX" layers for WinNT:  gnu-win32 b18 and UWIN
1.33 Neither is suitable for production use (both are still in alpha), so I'll
only make notes.  I ran both of these on a longname filesystem:

gnu-win32
	+ bash was reluctant to run the configure script (and inconsistent;
	  sometimes "sh configure" worked, other times "./configure").

	+ configure script had to be "helped" since the tests for killpg,
	  etc., broke (process never returned).

	+ the fcntl(0, F_SETFL, kbd_flags|O_NDELAY) call for tttypahead()
	  returns success though it does nothing.  I stubbed it out to
	  get a workable program.

	+ the "vt100" terminal emulator is limited-functionality (less, even,
	  than ANSI.SYS).

	+ server pathnames begin with "//".  There is some old code to support
	  Apollo (one of the sources that M$ copied), which seems to work for
	  this purpose.

UWIN:
	+ the configure script mostly ran (though the previous version could
	  not run sed for constructing config.h).

	+ 'environ' did not seem to be present (there's no configure test for
	  that yet).

	+ the isready_c macro has to be tweaked (it doesn't correspond to any
	  of the other flavors).

	+ appears to be same "vt100" emulator as gnu-win32 (perhaps it is).

-- 97-12-08 (paul)

as far as i can tell, procedures now share a namespace with built-in
functions, is that right?  i see that if i "source pictmode.rc" i no longer
have to type "run pic".  i can just type ":pic" instead.  this is neat.

questions:
    - can i bind a key to the new command "pic" at this point?  i don't
	seem to be able to.  it seems like macros would be obsolete if
	i could do this.

    - can i define a procedure which acts as an "operator"?  i.e. can i
	define a procedure which should be named "xxx-til"?  i can imagine
	that with the perl hooks, it will be very tempting to write new
	buffer-filtering stuff in perl (like sean's enhanced paragraph
	formatter), and it would be really nice to define those as
	operators (even if only line-oriented operations were supported, that
	would be a big win), and bind them to a key.

-- 97-12-10 (Ilya Zakharevich )

In article <199712091406.JAA18712@postman.opengroup.org> you write:
> Highlights since 7.2:
>       + beginnings of perl interface

Perl needs (to make the debugger visual) a file viewer which can be accessible
both by user, and by the *driver* program (say, via a pipe).  Is it possible to
use vile for this (start it with an option to read commands from a pipe)?

An ability to highlight current line and use different colors for breakable
lines and lines with breakpoints would be also welcome.

-- 97-12-15 (Billy Little )

is there any way to get the highlighting behavior when the highlighting begins
with a mouse double-click to behave the same way it does when in an xterm?
Specifically, if I double-click on some text in an xterm window, and without
releasing the mouse button after the second click, begin moving the pointer,
the xterm will highlight only the text associated with whole words.

-- 98-01-30 (Matthias Buelow )

things about vile that would be nice...

Backspacing over the beginning of line (at least when a newline has been
inserted in the current insertion/append command, like in vi) and something
like a jump-scroll (scrolling not one line but a couple of lines when going
over the last line of the current page, like in emacs) are imho a good idea.

...yanking text (for example, yanking to mark) could move the cursor to the
mark instead of keeping it at the current location (that would be like vi does
it).

-- 98-02-08 (tom)

Two users report a problem with xvile linked with Motif 2.0 on Linux.
(John Gotts  and Gary Ross ).

I am unable to reproduce the bug, but did find a bug in Purify which caused
realloc to clear its argument when invoked immediately after a fork.

According to these reports, the x_open function is being invoked twice, which
is incorrect; it breaks initialization, causing the scrollbar data to be null,
resulting in a core dump.

On the basis of earlier reports (and from reading news groups) I suggested that
it might be a conflict with glibc2 vs libc5 (no), that the OPT_WORKING code
might be a problem (no), and that forking xvile might be a problem with Motif
(no).  Compiler optimization level may be related (both reports were for -O2
and up).

[98-05-27]
Revisiting this, another possibility is that the x_preparse_args(), which
initializes the display causes a ConfigureWindow event, which is initializing
the scrollbar arrays before x_open is actually called - but only for some
systems (e.g., Motif 2.x).

[98-06-16]
After upgrading to gcc 2.7.2.3, I found that it is due to a bug in gcc; when
optimizing it loses some code.  Turning off optimization makes the problem go
away (tom).

-- 98-03-11 (Richard A Ward )

I sometimes use a global command like

	:g/LtADI/.-1,.+1d

to delete a multiple line groups.  A file segment follows that I would use such
a command on.  Vile doesn't allow this command.  Vi does.

-- 98-04-12 (tom)

OS/2 pipes hang in a write-to-pipe (nothing to do with recent changes for
Win32).  The EMX configuration can read/write pipes.

OS/2 mouse code probably eats too many CPU cycles; since coding that, I've
noticed that OS/2 is sometimes reluctant to switch windows vs EMX windows.

-- 98-05-25 (tom)

if I edit a :, it doesn't necessarily get interpreted as a jump to line
.

[98-07-27] checking this, I don't see that aspect, but do see that I cannot
edit a : with an arrow key, since the arrow causes the  state
to be terminated, and start on the name.  There'll always be the seam, but I
might be able to fix this by tinkering with eol_range so it would accept
left/right arrows.

-- 98-06-16 (Jim Crigler )

This may be specific to the fonts I'm using.  When I compiled xvile
with
        ./configure --prefix=/usr/local --with-perl --with-screen=Xaw
        make
on Linux (RH5), I can't see the decenders from g, q, y, etc.  This happens with
both lucidatypewriter and courier in various sizes.  On Solaris 2.4 at work
(same configure), it only happens with certain fonts.  In both cases I use only
"real" fonts.  Sizes:

	10/12/14/18  (18 is almost too big to be unusable)

Actually, here's some more data:  It seems to happen when the window gets
resized, either via the window manager or by setting the $font variable.  (I
have some font sizes preset in a pseudo-menu I bring up in the command line via
a key mapping.  It helps when someone else needs to look at code over my
shoulder to bump up to 18pt.) I frequently resize xvile via the window manager.

[I cannot reproduce this - tom]

-- 98-06-17 (Abigail )

If you just typed a line of indented text, and have autoindent on, and you hit
return, the cursor goes to the next line, and is lined up with the previous
line.  Just as it should be.  Now I use backspace because I want to stop
indentation - or at least have less indentation.  However, if I hit return
after hitting the backspace key a few times (and no other character in
between), the cursor lines up again with the original indented line - not with
the backspaced one.

Wouldn't it be nice to have an option of "aligning" with the blank line?  Such
that if you backspace away indentation, then hit return, vile remembers you
wanted to decrease indentation?

-- 98-06-18 (Brian Moore )

I want to be able to do:

define-mode mail
    define-submode mail suffixes \\(^\\(/tmp/mutt-[a-z]\\+-[0-9]\\+-[0-9]\\+\\)\\|\\(.followup\\|.letter\\)\\)$
    define-submode mail wm 8
    define-submode mail read-hook "del-sig"

In short, it'd be cool to be able to set hooks based on suffixes or other
signs-o-mode.

It'd be a bit cleaner than hacking '~if ¬ &seq $majormode "mail"'
stuff at the start of a procedure.

-- 98-06-24 (Clark Morgan)

If a vile user changes the value of a universal string mode (e.g.,
backup-style), the old value is carefully saved away in set_mode_value(), but
NOT _freed_ after the change.

-- 98-06-25 (Paul Fox)

officemate ... used to have his palette string set to:
	set palette "7 4 2 14 1 5 3 0"
somehow this in combination with his desktop colors gave him white on
white with vile.exe

[the number of colors increased to 16, making the palette too short.  we
should repeat the palette to fill out the number of colors, or set $ncolors
to match the palette - tom]

-- 98-08-21 (tom)

the [Registers] buffer "should" update '<' after each keystroke, but doesn't
seem to unless I do something call calls update(TRUE).

-- 98-09-01 (Otavio Exel )

3) again, from inside a store-macro, how do I find out if there's a
region defined in the current buffer and, if possible, where the
region is?

-- 98-09-03 (tom)

wishlist:
implement ~foreach iterator.  Add CMDFUNC flags to macro definition
and to describe-bindings view.

-- 98-09-09 (tom)

xvile doesn't build with unproto on SunOS because I get a -B option from
the imake configuration that K&R cc doesn't grok.

-- 99-02-11 (tom)

Steen Savstrup Kristensen  reports that he needs to
use "EXTRA_CFLAGS  = -n32 -mips4" to get xvile to build properly on IRIX.
SGI (IRIX's vendor) is transitioning from an old (-o32) 32-bit architecture
to 64-bit (with -n32 used for compatibility).  I do not yet know how to write
a configure test that will set this properly.

Also, from examining config.log, the 64-bit compiler complains about casts
of addresses to 'int'.  This may be a problem (i.e., cause configure tests
to go awry).

-- 99-02-12 (tom)

The lex filters will not build with old versions of lex, since those do not
support %x.  We can support new versions of lex, but really recommend using
flex, since even the newer versions of lex apparently have more bugs.

-- 99-03-31 (tom)

The configure script should search for -lcrypt.  It doesn't work on FreeBSD
anyway, since it's a stub of some sort.

-- 99-06-27 (tom)

add a pattern to ignore (strip) before checking suffix, e.g., .orig|~

-- 99-07-07 (tom)

down-row and up-row don't work properly with binary files.
(it's using the offset rather than the screen-column)

-- 99-08-29 (tom)

In timode, it would be nice to make '#' insert in column 1 like vile's cmode
does for preprocessor lines (indeed, make this work with the autoindent).

-- 99-10-03 (tom)

There's a remaining problem where re-reading a buffer does not repaint syntax
highlighting.  That happens when it is not the current buffer, e.g., after
running a shell command.

-- 99-11-06 (tom)

The logic I'm using to detach a subprocess for $xshell works properly on
Linux (tested with libc5 and glibc2) and FreeBSD, but has problems on
Solaris (tested with 2.7) and SCO OpenServer.  On both the latter, the
parent process will hang until all of the subprocess xterms are closed.
Also, on Solaris, the 'read' used in /bin/sh to hold the process on
completion does not work.  (One can use XFree86 xterm's -hold option
to work around the last problem).

-- 99-12-06 (tom)

While fixing a file-descriptor leak in npflush for win32 (now32pipe), I
was running winvile.exe from a .bat script which ran nmake and then winvile.
The script itself I ran from vile.exe, which used w32pipe on WinNT.  While
the leak was present, I could "use" ^X-q on the third try of the .bat script.
It appears that the inherited file-descriptor from vile.exe for the w32pipe
was "usable" for the winvile.exe process, when it coincided with the one that
winvile.exe was using.

-- 99-12-23 (tom)

even if I remove the -B option that imake provides, the SunOS unproto
wrapper does not build xvile because the compiler does not understand
	#include VILE_ICON

-- 00-01-12 (tom)

Users can change $ncolors from its initial value, i.e., the maximum number of
colors that the terminal can display.  However, not all windows (e.g., those
that are syntax-highlighted) will be repainted to restrict them to the limited
number of colors.

Even on a monochrome terminal, users can set the fcolor and bcolor modes
to black and white if vile is able to use color.  The actual screen colors
are not updated.

-- 00-01-15 (paul)

... there's the vile-with-perl-on-solaris-with-gcc problem, where
"-B/usr/ccs/bin" needs to be added to LDFLAGS to make it work.  i guess
it might be too late to change configure (though if solaris, and CC ==
gcc and perl is included, it would probably be a safe change -- i
think it's benign if /usr/ccs/bin doesn't exist), but we should at least
have it in a README/Install/ or something.

-- 00-03-24 (brendan)

Perl 5.6.0 is now out.

The simple change is that now all perl globals need a PL_ prefix (which
affects `errgv', `na' and `sv_undef' in perl.xs/ptypemap).  The change
is backward compatible to 5.005 and *should* be to 5.004 although I've
been unable to test that version.

A bigger problem is that the tied filehandle mechanism appears to have
changed to some extent, and shell.pm no longer works.

The problem appears to be that Vile::Buffer does not implement an OPEN
method, and the re-opens of STDIN/STDOUT/STDERR to the pty in the child
appear to be calling it for some reason I've not yet had a chance to
track down.

-- 00-10-15 (tom)

The curses.c driver is still experimental.  It has really only been tested
with ncurses on Linux.  There are some problems displaying on backgrounds
other than black.  The chief problem however is that under some circumstances
the terminal modes are not properly saved/restored when executing a shell
command (and a staircase effect results).

-- 01-01-22 (tom)

I did the bounds implementation in January 1998, but did not finish it at
that point.  It does not (yet) handle limits on an expression delineated
by \( and \).

Considered making a configure option to use Henry Spencer's more up-to-date
regex library, but see that it requires null-terminated strings.

-- 01-06-13 (tom)

win32 (both), os/2 and even tcap could use a thread for the 'working' message.

-- 01-06-18 (tom)

spell checker should flag a repeated word if there's no intervening
punctuation.

-- 01-09-01 (tom)

from discussion with Clark Morgan, it would be nice to accept name-completion
on motion-operators as a special case for some interactive commands that now
accept just a few hardcoded items.

-- 01-12-07 (tom)

vile hits diskdrive too much when writing a file under cygwin (recommend
disabling resolve-links).  It doesn't do that when I run an empty vile.rc (and
one user complains that win95 vile.exe does something similar.

-- 01-12-30 (tom)

modify hooks so I can pass parameters to them, adding logic to support an
$open-hook

-- 02-01-16 (tom)

The undo-dos-trim mode allows undo of the changes made to the buffer, but does
not restore the original recordseparator mode when an undo is made.

-- 02-02-03 (tom)

It would be nice to allow 'p' command in a [p-lines] buffer to generate a new
buffer such as [p-lines-2].  Also, it would be nice to allow reread of a given
[p-lines] buffer by remembering the buffer from which it was extracted, and the
corresponding command which generated it.

-- 02-02-08 (tom)

if we don't have HAVE_ACCESS defined, ffaccess() doesn't handle OR'd bits,
treats them as existence check.

-- 02-02-15 (tom)

if I have a [Tags x] buffer, and cd to another directory, vile does not pick up
the tags file from the new directory.

-- 02-02-23 (tom)

nrmode should be able to handle \fRxx\fByy\fIaa\fR

-- 02-05-01 (tom)

:error-buffer doesn't allow us to use finderr pointing into an internal buffer
such as the  stuff, since the patterns for buffer names include
characters that normally aren't part of filenames.

-- 03-03-18 (tom)

Recent improvements allow search/replace for strings with null characters, but
the related variables $search and $replacepat assume strings are terminated by
nulls.  It would be nice to reimplement those - doing this is a little
complicated since it may impact the use of error_val for propagating error
conditions in expression evaluation.

-- 03-06-29 (tom)

The screen cannot be resized while doing a multimotion command initiated by the
mouse (because of the beginDisplay/endofDisplay in tcap.c interacting with the
check in newscreensize).  When the command ends, vile will update the
screensize.

-- 07-11-26 (tom)
filters using fltstack.h won't build with OSF/1 4.0D since its native flex
declares yy_start (used in BEGIN) after the first code segment - looks like
it's in preparation for the pattern definitions.  I cannot work around that
(use flex 2.54a).

-- 08-01-13 (tom)
lex/flex (all known versions) have no real localization support, using only
a POSIX table for the character classes.  I have in mind that this could be
done by a new variant of flex which does the following:

	a) optionally uses a localized table for character classes.  Reading
	   flex's source, it appears that this was part of its initial design,
	   though it does not behave that way.

	b) optionally provides for reparsing the patterns, generating localized
	   tables at runtime.  That would be doable if the lex program uses
	   exactly the same code (a common library) for building the stubbed
	   lexer/tables and for the runtime analysis.

so-called "new flex" 2.5.34 does not accept lexers written for POSIX lex.
(2.5.31 did accept most POSIX lexers...).

-- 08-03-09 (tom)
spell.pm requires a fairly recent Perl, since it uses File::Temp
That does not work with very old Perl, such as 5.05.002 - a workaround in
that case would be to comment out the "use spell" in vileperl.rc

-- 08-03-24 (tom)
Rendering UTF-8 with the curses driver is less reliable than using the
terminfo/termcap driver.  That is because the curses library has its own
sense of locale which can interfere with vile's locale translations.

Taking that into account, vile will use only the current locale rather
than setting up a narrow locale to correspond to the wide locale when
using the curses driver.

There are two types of curses library against which vile could be linked.
Those are the "narrow" SVr4 curses and the "wide" X/Open curses.  For the
latter, vile will assume that the curses library can actually display
wide characters.  Not all implementations work well (ncursesw is preferred).

-- 08-04-10 (tom)
Select/paste in winvile works transparently for 8-bit (ASCII and ISO-8859-1)
data.  It is possible to copy UTF-8 data from a buffer which stores UTF-8 (or
-16, -32), but the target must expect UTF-8, since winvile is not converting it
to the CF_UNICODETEXT type.

-- 08-07-12 (tom)
'@'command-line option with DJGPP (in a plain W2K cmd.exe shell) is interpreted
by cmd.exe to source the file into the command-line.  Use vile.rc or use
environment variables.

-- 08-07-12 (tom)
The non-ASCII function key bindings in DJGPP do not work with the locale
configuration since the codes above 127 are filtered out, e.g., "\0\215"
becomes "\0".

-- 08-10-19 (tom)
mcolor shows only one part of the modeline extended-colors, due to limitations
of the normal color enumeration.

xvile doesn't allow modeline to be colored using extended-colors.

-- 08-11-30 (tom)
The scriptable vilemenu.rc relies on vile's scripting, which is not fully
available when xvile sets up the display.  To work around this limitation,
xvile creates a fallback menu with just the About/Version entry initially, and
then fills in the complete menu - after the screen is first displayed.

It does this when it sees that the menu file contains directive lines, e.g.,
"~with".  If no directives are found, xvile assumes the file is (as originally)
unscripted, and will initialize the menus before the screen is displayed.

-- 09-06-05 (tom)
The HTML syntax filter uses more start conditions than are supported in some
very old lex programs such as that bundled with HPUX.  That refers to the list
on lines beginning with "%x", which is not adjustable in most lex
implementations (though the HPUX lex program suggests using the "-Xs" option
without actually accepting it).  Use flex for those cases.

-- 10-04-11 (tom)
If editing a mixture of UTF-8 and non-UTF-8 buffers, the [History] buffer
will get a mixture of encodings corresponding to searches, etc., in the various
buffers.  vile does not automatically translate those commands into the same
encoding.
vile-9.8v/builtflt.c000066400000000000000000000447351415556424100145340ustar00rootroot00000000000000/*
 * $Id: builtflt.c,v 1.101 2018/11/12 18:30:34 tom Exp $
 *
 * Main program and I/O for builtin vile syntax/highlighter programs
 */

#include "estruct.h"
#include "builtflt.h"

#ifdef _builtflt_h

#include "edef.h"
#include "nefunc.h"
#include "nevars.h"

#include 
#include 

#ifdef HAVE_LIBDL
#include 
#endif

static jmp_buf flt_recovery;
static FILTER_DEF *current_filter;
static MARK mark_in;
static MARK mark_out;
static TBUFF *gets_data;
static const char *current_params;
static int need_separator;

#define FLT_PUTC(ch) \
    if (filter_only > 0) { \
	putchar(ch); \
    } else { \
	if (ch == '\n') { \
	    if (mark_out.l != buf_head(curbp)) \
		mark_out.l = lforw(mark_out.l); \
	    mark_out.o = w_left_margin(curwp); \
	} else { \
	    mark_out.o++; \
	} \
    }

/******************************************************************************
 * Private functions                                                          *
 ******************************************************************************/

#if OPT_MAJORMODE
/*
 * Given the 'major_name', verify that it applies to this buffer, and if so,
 * lookup $filtername and see if we can associate the external filtername to
 * one of the built-in filters.
 *
 * FIXME:  This only works for filters constructed with the naming convention
 * that we use for our external filters, i.e., "vile-{majormode}-filt".
 *
 * FIXME:  Should we allow lookup of majormodes that aren't assigned to a
 * buffer?
 */
static int
parse_filtername(const char *major_name, const char **params)
{
    static const char prefix[] = "vile-";
    static const char suffix[] = "-filt";

    char *temp;

    *params = 0;

    if (valid_buffer(curbp)
	&& curbp->majr != 0
	&& !strcmp(curbp->majr->shortname, major_name)
	&& (temp = b_val_ptr(curbp, VAL_FILTERNAME)) != 0) {
	if (!strncmp(temp, prefix, sizeof(prefix) - 1)) {
	    char *base = temp + sizeof(prefix) - 1;
	    char *next = base;
	    int n;

	    while (*next) {
		if (!strncmp(next, suffix, sizeof(suffix) - 1)
		    && (isSpace(next[sizeof(suffix) - 1])
			|| (next[sizeof(suffix) - 1] == EOS))) {
		    size_t len = (size_t) (next - base);
		    for (n = 0; builtflt[n] != 0; n++) {
			const char *name = builtflt[n]->filter_name;
			if (strlen(name) == len
			    && !strncmp(base, name, len)) {
			    *params = skip_cblanks(next + sizeof(suffix) - 1);
			    return n;
			}
		    }
		    break;
		}
		next++;
	    }
	}
    }
    return -1;
}
#endif

static char *
param_value(const char **ptr)
{
    char *value = 0;
    const char *s;
    const char *t;

    s = skip_cblanks(*ptr + 1);
    t = skip_ctext(s);
    if (t != s) {
	if ((value = strmalloc(s)) != 0) {
	    value[t - s] = EOS;
	    *ptr = t;
	}
    }
    return value;
}

/*
 * All we're really interested in are the -k and -t options.  Ignore -v and -q.
 * Return true if we had a "-k" option.
 */
static int
ProcessArgs(int flag)
{
    const char *s = current_params;
    char *value;

    if (!flag) {
	char *command = 0;
	size_t needed = strlen(current_filter->filter_name) + 11 + strlen(s);
	if (*s)
	    ++needed;
	if ((command = malloc(needed + 1)) != 0) {
	    sprintf(command, "vile-%s-filt", current_filter->filter_name);
	    if (*s) {
		strcat(command, " ");
		strcat(command, s);
	    }
	    flt_puts(command, (int) needed, "M");
	    free(command);
	}
    }

    memset(flt_options, 0, sizeof(flt_options));
    FltOptions('t') = tabstop_val(curbp);
    while (*s != EOS) {
	s = skip_cblanks(s);
	if (*s == '-') {
	    while (*s != EOS && *++s != EOS && !isSpace(*s)) {
		flt_options[CharOf(*s)] += 1;
		switch (*s) {
		case 'k':
		    if ((value = param_value(&s)) != 0) {
			if (flag) {
			    flt_init_table(value);
			    flt_setup_symbols(value);
			}
			free(value);
		    }
		    break;
		case 't':
		    if ((value = param_value(&s)) != 0) {
			if ((FltOptions('t') = atoi(value)) <= 0)
			    FltOptions('t') = 8;
			free(value);
		    }
		    break;
		}
	    }
	} else {
	    s = skip_ctext(s);
	}
    }
    vile_keywords = !FltOptions('k');
    return !vile_keywords;
}

static void
save_mark(int first)
{
    if (mark_out.o > llength(mark_out.l))
	mark_out.o = llength(mark_out.l);
    if (first)
	DOT = mark_out;
    else
	MK = mark_out;
}

#ifdef HAVE_LIBDL

#ifdef RTLD_NOW
#define my_RTLD RTLD_NOW
#else
#ifdef RTLD_LAZY
#define my_RTLD RTLD_LAZY
#else
make an error
#endif
#endif

static int
load_filter(const char *name)
{
    char defining[NSTRING];
    char filename[NFILEN];
    char leafname[NSTRING];
    void *obj;
    FILTER_DEF *def;
    int found = 0;
    int tried = 0;
    const char *cp = libdir_path;

    if (strlen(name) < NSTRING - 30) {
	int first = TRUE;
	sprintf(defining, "define_%s", name);
	sprintf(leafname, "vile-%s-filt.so", name);
	while ((cp = parse_pathlist(cp, filename, &first)) != 0) {
	    if (strlen(filename) + strlen(leafname) + 3 >= sizeof(filename))
		continue;
	    pathcat(filename, filename, leafname);
	    TRACE(("load_filter(%s) %s\n", filename, defining));
	    ++tried;
	    if ((obj = dlopen(filename, my_RTLD)) != 0) {
		found = 1;
		if ((def = dlsym(obj, defining)) == 0) {
		    dlclose(obj);
		    mlwarn("[Error: can't reference variable %s from %s (%s)]",
			   defining, filename, dlerror());
		    break;
		} else {
		    TRACE(("...load_filter\n"));
		    current_filter->InitFilter = def->InitFilter;
		    current_filter->DoFilter = def->DoFilter;
		    current_filter->options = def->options;
		    current_filter->loaded = 1;
		    break;
		}
	    }
	}

	if (!found && tried) {
	    mlwarn("[Error: can't load shared object %s (%s)]",
		   leafname, dlerror());
	}
    }
    return current_filter->loaded;
}
#endif /* HAVE_LIBDL */

/******************************************************************************
 * Public functions                                                           *
 ******************************************************************************/

/*
 * Trim newline from the string, returning true if it was found.
 */
int
chop_newline(char *s)
{
    size_t len = strlen(s);

    if (len != 0 && s[len - 1] == '\n') {
	s[--len] = '\0';
	return 1;
    }
    return 0;
}

void
flt_echo(const char *string, int length)
{
    int ch;
    while (length-- > 0) {
	ch = *string++;
	FLT_PUTC(ch);
    }
}

/*
 * Followup from flt_failed() by returning zero if we are recovering from a
 * fatal error.
 */
int
flt_succeeds(void)
{
    return !setjmp(flt_recovery);
}

/*
 * This is used to stop lex/flex from exiting the program on a syntax error.
 */
void
flt_failed(const char *msg)
{
    mlforce("[Filter: %s]", msg);
    longjmp(flt_recovery, 1);
}

void
flt_finish(void)
{
    tb_free(&gets_data);
}

#define MustFixupCrLf() \
    (   (b_val(curbp, VAL_RECORD_SEP) == RS_CR) \
     || (b_val(curbp, VAL_RECORD_SEP) == RS_LF)  )

/*
 * Syntax filters expect text to be separated by newlines, and don't
 * expect embedded carriage returns.  Try to meet that expectation.
 */
static int
fixup_cr_lf(int ch)
{
    if (b_val(curbp, VAL_RECORD_SEP) == RS_CR) {
	if (ch == '\n')
	    ch = ' ';
	else if (ch == '\r')
	    ch = '\n';
    } else if (b_val(curbp, VAL_RECORD_SEP) == RS_LF) {
	if (ch == '\r')
	    ch = ' ';
    }
    return ch;
}

char *
flt_gets(char **ptr, size_t *len)
{
    int need = is_header_line(mark_in, curbp) ? -1 : llength(mark_in.l);

    *len = 0;
    *ptr = 0;

    if (need >= 0
	&& tb_init(&gets_data, 0) != 0
	&& tb_bappend(&gets_data, lvalue(mark_in.l), (size_t) need) != 0
	&& tb_append(&gets_data, use_record_sep(curbp)) != 0
	&& tb_append(&gets_data, EOS) != 0) {
	*ptr = tb_values(gets_data);
	*len = (unsigned) (need + len_record_sep(curbp));

	TRACE(("flt_gets %6d:%.*s\n",
	       line_no(curbp, mark_in.l),
	       *ptr ? need : 1,
	       NONNULL(*ptr)));

	mark_in.l = lforw(mark_in.l);

	/*
	 * Syntax filters expect text to be separated by newlines, and don't
	 * expect embedded carriage returns.  Try to meet that expectation.
	 */
	if (MustFixupCrLf()) {
	    size_t len2 = tb_length(gets_data);
	    if (len2 != 0) {
		size_t n;
		char *values = tb_values(gets_data);
		int ch;

		for (n = 0; n < len2; ++n) {
		    ch = values[n];
		    if (isreturn(ch))
			values[n] = (char) fixup_cr_lf(ch);
		}
	    }
	}
    } else {
	TRACE(("flt_gets - EOF\n"));
    }
    return *ptr;
}

/*
 * Return the line number at which we are about to write a token.
 */
int
flt_get_line(void)
{
    return line_no(curbp, mark_out.l);
}

/*
 * Return the column/offset for the current token.
 */
int
flt_get_col(void)
{
    return offs2col(curwp, mark_out.l, mark_out.o);
}

#ifdef MDFILTERMSGS
/*
 * Get the pointer to filter-messages buffer.  Ensure that its "filtermsgs"
 * mode is off, so we don't get caught by trying to use it as input/output.
 */
static BUFFER *
find_filtermsgs(void)
{
    BUFFER *bp = make_ro_bp(FLTMSGS_BufName, BFINVS);
    if (bp != 0) {
	set_local_b_val(bp, MDFILTERMSGS, FALSE);
    }
    return bp;
}

/*
 * Clear the text from [Filter Messages].
 */
static void
init_flt_error(void)
{
    BUFFER *bp;
    if (b_val(curbp, MDFILTERMSGS)) {
	if ((bp = find_filtermsgs()) != 0) {
	    b_clr_changed(bp);	/* so bclear does not prompt */
	    bclear(bp);
	}
    }
}
#else
#define init_flt_error()	/* nothing */
#endif

/*
 * Log an error detected by the syntax filter.
 */
void
flt_error(const char *fmt,...)
{
#ifdef MDFILTERMSGS
    if (b_val(curbp, MDFILTERMSGS)) {
	const char *filename = ((curbp != 0)
				? (isInternalName(curbp->b_fname)
				   ? curbp->b_bname
				   : curbp->b_fname)
				: "");
	BUFFER *bp;
	va_list ap;

	if ((bp = find_filtermsgs()) != 0) {
	    (void) b2printf(bp, "%s: %d:%d: ",
			    filename,
			    flt_get_line(),
			    flt_get_col() + 1);

	    va_start(ap, fmt);
	    (void) b2vprintf(bp, fmt, ap);
	    va_end(ap);

	    (void) b2printf(bp, "\n");
	}
    }
#endif
}

/*
 * Log an message from the syntax filter.
 */
void
flt_message(const char *fmt,...)
{
#ifdef MDFILTERMSGS
    if (b_val(curbp, MDFILTERMSGS)) {
	BUFFER *bp;
	va_list ap;

	if ((bp = find_filtermsgs()) != 0) {
	    va_start(ap, fmt);
	    (void) b2vprintf(bp, fmt, ap);
	    va_end(ap);
	}
    }
#endif
}

/*
 * This function is used from flex to read chunks from the input file.  We'll
 * make it simple by ending each read at the end of a line; some long lines
 * will be split across successive reads.
 */
int
flt_input(char *buffer, int max_size)
{
    const char *separator = "\n";
    int need = (int) strlen(separator);
    int used = 0;
    int ch;

    if (need_separator) {
	strcpy(buffer, separator);
	used = need;
	need_separator = FALSE;
    }
    if (!is_header_line(mark_in, curbp)) {
	while (used < max_size) {
	    if (mark_in.o < llength(mark_in.l)) {
		ch = lgetc(mark_in.l, mark_in.o++);
		if (filter_only) {
		    buffer[used++] = (char) ch;
		} else {
		    if (isreturn(ch))
			ch = fixup_cr_lf(ch);
		    buffer[used++] = (char) ch;
		}
	    } else {
		mark_in.l = lforw(mark_in.l);
		mark_in.o = w_left_margin(curwp);
		need_separator = TRUE;
		break;
	    }
	}
	if (need_separator && (used + need) < max_size) {
	    strcpy(buffer + used, separator);
	    used += need;
	    need_separator = FALSE;
	}
    }
    return used;
}

const char *
flt_name(void)
{
    return current_filter ? current_filter->filter_name : "";
}

char *
flt_put_blanks(char *string)
{
    char *result = skip_blanks(string);
    if (result != string)
	flt_puts(string, (int) (result - string), "");
    return result;
}

void
flt_putc(int ch)
{
    FLT_PUTC(ch);
}

static int
hex2int(int ch)
{
    int value;

    if (ch >= '0' && ch <= '9')
	value = (ch - '0');
    else if (ch >= 'A' && ch <= 'Z')
	value = (ch - 'A') + 10;
    else if (ch >= 'a' && ch <= 'z')
	value = (ch - 'a') + 10;
    else
	value = 0;

    return value;
}

static int
int2hex(int value)
{
    int ch;

    if (value >= 0 && value <= 9)
	ch = value + '0';
    else if (value >= 10 && value <= 15)
	ch = (value - 10) + 'A';
    else
	ch = '?';

    return ch;
}

static int
lookup_ctrans(int ch)
{
    int value = hex2int(ch);
    return int2hex(ctrans[value % NCOLORS]);
}

void
flt_puts(const char *string, int length, const char *marker)
{
    char bfr1[NSTRING];
    char *last;
    int count;

    if (filter_only > 0) {
	if (marker != 0 && *marker != EOS && *marker != 'N') {
	    size_t limit = sizeof(bfr1) - 2;

	    strncpy(bfr1, marker, limit)[limit] = EOS;
	    for (last = bfr1; *last; ++last) {
		if (*last == 'C' && isXDigit(CharOf(last[1]))) {
		    ++last;
		    *last = (char) lookup_ctrans(CharOf(*last));
		}
	    }
	    printf("%c%d%s:", CTL_A, length, bfr1);
	}
	flt_echo(string, length);
    } else {
	if (length > 0 && marker != 0 && *marker != EOS && *marker != 'N') {
	    size_t prefix;

	    save_mark(TRUE);

	    sprintf(bfr1, "%c%d", CTL_A, length);
	    prefix = strlen(bfr1);

	    vl_strncpy(bfr1 + prefix, marker, sizeof(bfr1) - (prefix + 3));
	    last = bfr1 + strlen(bfr1);
	    *last++ = ':';
	    *last = EOS;

	    decode_attribute(bfr1, (size_t) (last - bfr1), (size_t) 0, &count);

	    if (count > 0) {
		flt_echo(string, length);
		save_mark(FALSE);

		if (apply_attribute()) {
		    REGIONSHAPE save_shape = regionshape;
		    regionshape = rgn_EXACT;
		    (void) attributeregion();
		    videoattribute = 0;
		    regionshape = save_shape;
		}
	    } else {
		save_mark(FALSE);
	    }
	} else {
	    flt_echo(string, length);
	}
    }
}

/*
 * For the given majormode 'name', check if we have a builtin filter by that
 * name, or if it has an associated filtername, check if that is a builtin.
 *
 * Sets current_filter and current_params as a side-effect.
 */
int
flt_lookup(char *name)
{
    int n;

    TRACE(("flt_lookup(%s)\n", name));
#if OPT_MAJORMODE
    if ((n = parse_filtername(name, ¤t_params)) >= 0) {
	TRACE(("...%s(%s)\n", builtflt[n]->filter_name, current_params));
	current_filter = builtflt[n];
	return TRUE;
    }
#endif
    for (n = 0; builtflt[n] != 0; n++) {
	if (!strcmp(name, builtflt[n]->filter_name)) {
	    current_filter = builtflt[n];
	    current_params = "";
	    TRACE(("...%s\n", builtflt[n]->filter_name));
	    return TRUE;
	}
    }
    TRACE(("...not found\n"));
    return FALSE;
}

int
flt_start(char *name)
{
    int rc = FALSE;

    TRACE((T_CALLED "flt_start(%s)\n", name));
    if (flt_lookup(name)
#ifdef HAVE_LIBDL
	&& (current_filter->loaded || load_filter(current_filter->filter_name))
#endif
	) {
	MARK save_dot;
	MARK save_mk;
	int nextarg;

	save_dot = DOT;
	save_mk = MK;

	need_separator = FALSE;
	mark_in.l = lforw(buf_head(curbp));
	mark_in.o = w_left_margin(curwp);
	mark_out = mark_in;
	tb_init(&gets_data, 0);

	init_flt_error();

	(void) ProcessArgs(0);

	flt_initialize(current_filter->filter_name);

	current_filter->InitFilter(1);

	/* setup colors for the filter's default-table */
	flt_read_keywords(MY_NAME);
	if (strcmp(MY_NAME, current_filter->filter_name)) {
	    flt_read_keywords(current_filter->filter_name);
	}

	nextarg = ProcessArgs(1);
	if (nextarg == 0) {
	    if (strcmp(MY_NAME, default_table)
		&& strcmp(current_filter->filter_name, default_table)) {
		flt_read_keywords(default_table);
	    }
	}
	set_symbol_table(default_table);
	if (FltOptions('Q')) {
	    flt_dump_symtab(NULL);
	} else {
	    current_filter->InitFilter(0);
	    current_filter->DoFilter(stdin);
	}
#if NO_LEAKS
	current_filter->FreeFilter();
#endif

	DOT = save_dot;
	MK = save_mk;

	rc = TRUE;
    }
    returnCode(rc);
}

/*
 * The spelling filter uses this function, since it parses the buffer more
 * than once, using the parsed data for a list of words to check.  So we
 * do not wipe the symbol table.
 */
int
flt_restart(char *name)
{
    TRACE(("flt_restart(%s)\n", name));
    if (flt_lookup(name)
#ifdef HAVE_LIBDL
	&& (current_filter->loaded || load_filter(current_filter->filter_name))
#endif
	) {
	need_separator = FALSE;
	mark_in.l = lforw(buf_head(curbp));
	mark_in.o = w_left_margin(curwp);
	mark_out = mark_in;
	tb_init(&gets_data, 0);

	init_flt_error();
	set_symbol_table(default_table);

	return TRUE;
    }
    return FALSE;
}

static TBUFF *filter_list;

int
var_FILTER_LIST(TBUFF **rp, const char *vp)
{
    int n;

    if (rp) {
	if (filter_list == 0) {
	    for (n = 0; builtflt[n] != 0; n++) {
		if (n)
		    tb_sappend0(&filter_list, " ");
		tb_sappend0(&filter_list, builtflt[n]->filter_name);
	    }
	}
	tb_scopy(rp, tb_values(filter_list));
	return TRUE;
    } else if (vp) {
	return ABORT;		/* read-only */
    } else {
	return FALSE;
    }
}

/*
 * Check if the command name is one of vile's set/unset variants.
 */
int
vl_is_setting(const void *cmd)
{
    const CMDFUNC *ptr = (const CMDFUNC *) cmd;
    int result = 0;

    if (ptr != 0) {
	if (ptr == &f_setglobmode
	    || ptr == &f_delglobmode
	    || ptr == &f_setlocmode
	    || ptr == &f_dellocmode
#if OPT_EVAL
	    || ptr == &f_setvar
	    || ptr == &f_unsetvar
#endif
	    ) {
	    result = 1;
	}
    }
    return result;
}

#if OPT_EXTRA_COLOR
int
vl_is_xcolor(const void *cmd)
{
    const CMDFUNC *ptr = (const CMDFUNC *) cmd;
    int result = 0;

    if (ptr != 0) {
	if (ptr == &f_set_extra_colors) {
	    result = 1;
	}
    }
    return result;
}
#endif

/*
 * Check if the command name is one of vile's submode set/unset variants.
 */
int
vl_is_majormode(const void *cmd)
{
    int result = 0;
#if OPT_MAJORMODE
    const CMDFUNC *ptr = (const CMDFUNC *) cmd;

    if (ptr != 0) {
	if (ptr == &f_define_mode
	    || ptr == &f_remove_mode) {
	    result = 1;
	}
    }
#endif
    return result;
}

/*
 * Check if the command name is one of vile's submode set/unset variants.
 */
int
vl_is_submode(const void *cmd)
{
    int result = 0;
#if OPT_MAJORMODE
    const CMDFUNC *ptr = (const CMDFUNC *) cmd;

    if (ptr != 0) {
	if (ptr == &f_define_submode
	    || ptr == &f_remove_submode) {
	    result = 1;
	}
    }
#endif
    return result;
}

int
vl_check_cmd(const void *cmd, unsigned long flags)
{
    const CMDFUNC *actual = (const CMDFUNC *) cmd;
    int result = 0;

    if (actual != 0) {
	result = ((actual->c_flags & flags) != 0);
    }
    return result;
}

const void *
vl_lookup_cmd(const char *name)
{
    return (const void *) engl2fnc(name);
}

/*
 * Lookup a symbol to see if it is one of vile's modes, majormodes or
 * submodes).
 */
int
vl_lookup_mode(const char *name)
{
    return vl_find_mode(name);
}

/*
 * Lookup a symbol to see if it is one of vile's built-in symbols.
 */
int
vl_lookup_var(const char *name)
{
    int result = 0;
    if (*name == '$')
	++name;
    if (vl_lookup_statevar(name) < 0
	&& vl_lookup_mode(name) < 0) {
	result = -1;
    }
    return result;
}

#if NO_LEAKS
void
flt_leaks(void)
{
    flt_free_symtab();
    FreeAndNull(default_table);
    FreeAndNull(default_attr);
    tb_free(&filter_list);
}
#endif

#else

extern void builtflt(void);
void
builtflt(void)
{
}

#endif /* _builtflt_h */
vile-9.8v/charsets.c000066400000000000000000000572441415556424100145220ustar00rootroot00000000000000/*
 * $Id: charsets.c,v 1.80 2018/10/21 19:18:36 tom Exp $
 *
 * see
 http://msdn.microsoft.com/library/default.asp?url=/library/en-us/intl/unicode_42jv.asp
 http://en.wikipedia.org/wiki/Byte_Order_Mark
 http://en.wikipedia.org/wiki/UTF-16
 */

#include 
#include 
#include 
#include 

#if OPT_ICONV_FUNCS
#include 
#include 
#endif
/* *INDENT-OFF* */
static const UCHAR mark_NONE[]    = { 0x00 };
static const UCHAR mark_UTF8[]    = { 0xef, 0xbb, 0xbf };
static const UCHAR mark_UTF16LE[] = { 0xff, 0xfe };
static const UCHAR mark_UTF16BE[] = { 0xfe, 0xff };
static const UCHAR mark_UTF32LE[] = { 0xff, 0xfe, 0x00, 0x00 };
static const UCHAR mark_UTF32BE[] = { 0x00, 0x00, 0xfe, 0xff };

#define IsNonNull(code) (code == 0xff)

typedef struct {
    BOM_CODES code;
    const UCHAR *mark;
    size_t size;
} BOM_TABLE;

#define DATA(name) { bom_##name, mark_##name, sizeof(mark_##name) }
static const BOM_TABLE bom_table[] = {
    { bom_NONE, mark_NONE, 0 },
    DATA(UTF8),
    DATA(UTF32LE),	/* must be before UTF-16 entries */
    DATA(UTF32BE),
    DATA(UTF16LE),
    DATA(UTF16BE),
};
#undef DATA
/* *INDENT-ON* */

/******************************************************************************/

static int
allow_decoder(BUFFER *bp, size_t need)
{
    if (need > bp->decode_utf_len) {
	bp->decode_utf_len = (need + 1) * 2;
	safe_typereallocn(UINT, bp->decode_utf_buf, bp->decode_utf_len);
    }
    return (bp->decode_utf_buf != 0);
}

static int
allow_encoder(BUFFER *bp, size_t need)
{
    if (need > bp->encode_utf_len) {
	bp->encode_utf_len = (need + 1) * 2;
	safe_typereallocn(char, bp->encode_utf_buf, bp->encode_utf_len);
    }
    return (bp->encode_utf_buf != 0);
}

int
vl_conv_to_utf8(UCHAR * target, UINT source, B_COUNT limit)
{
#define CH(n) (UCHAR)((source) >> ((n) * 8))
    int rc = 0;

    if (source <= 0x0000007f)
	rc = 1;
    else if (source <= 0x000007ff)
	rc = 2;
    else if (source <= 0x0000ffff)
	rc = 3;
    else if (source <= 0x001fffff)
	rc = 4;
    else if (source <= 0x03ffffff)
	rc = 5;
    else			/* (source <= 0x7fffffff) */
	rc = 6;

    if ((B_COUNT) rc > limit) {	/* whatever it is, we cannot decode it */
	TRACE2(("limit failed in vl_conv_to_utf8 %d/%ld %#06x\n",
		rc, limit, source));
	rc = 0;
    }

    if (target != 0) {
	switch (rc) {
	case 1:
	    target[0] = (UCHAR) CH(0);
	    break;

	case 2:
	    target[1] = (UCHAR) (0x80 | (CH(0) & 0x3f));
	    target[0] = (UCHAR) (0xc0 | (CH(0) >> 6) | ((CH(1) & 0x07) << 2));
	    break;

	case 3:
	    target[2] = (UCHAR) (0x80 | (CH(0) & 0x3f));
	    target[1] = (UCHAR) (0x80 | (CH(0) >> 6) | ((CH(1) & 0x0f) << 2));
	    target[0] = (UCHAR) (0xe0 | ((int) (CH(1) & 0xf0) >> 4));
	    break;

	case 4:
	    target[3] = (UCHAR) (0x80 | (CH(0) & 0x3f));
	    target[2] = (UCHAR) (0x80 | (CH(0) >> 6) | ((CH(1) & 0x0f) << 2));
	    target[1] = (UCHAR) (0x80 |
				 ((int) (CH(1) & 0xf0) >> 4) |
				 ((int) (CH(2) & 0x03) << 4));
	    target[0] = (UCHAR) (0xf0 | ((int) (CH(2) & 0x1f) >> 2));
	    break;

	case 5:
	    target[4] = (UCHAR) (0x80 | (CH(0) & 0x3f));
	    target[3] = (UCHAR) (0x80 | (CH(0) >> 6) | ((CH(1) & 0x0f) << 2));
	    target[2] = (UCHAR) (0x80 |
				 ((int) (CH(1) & 0xf0) >> 4) |
				 ((int) (CH(2) & 0x03) << 4));
	    target[1] = (UCHAR) (0x80 | (CH(2) >> 2));
	    target[0] = (UCHAR) (0xf8 | (CH(3) & 0x03));
	    break;

	case 6:
	    target[5] = (UCHAR) (0x80 | (CH(0) & 0x3f));
	    target[4] = (UCHAR) (0x80 | (CH(0) >> 6) | ((CH(1) & 0x0f) << 2));
	    target[3] = (UCHAR) (0x80 | (CH(1) >> 4) | ((CH(2) & 0x03) << 4));
	    target[2] = (UCHAR) (0x80 | (CH(2) >> 2));
	    target[1] = (UCHAR) (0x80 | (CH(3) & 0x3f));
	    target[0] = (UCHAR) (0xfc | ((int) (CH(3) & 0x40) >> 6));
	    break;
	}
	TRACE2(("decode %#08x %02X.%02X.%02X.%02X %d:%.*s\n", source,
		CH(3), CH(2), CH(1), CH(0), rc, rc, target));
    }

    return rc;			/* number of bytes needed in target */
#undef CH
}

int
vl_check_utf8(const char *source, B_COUNT limit)
{
    int rc = 0;
    int j;

    /*
     * Find the number of bytes we will need from the source.
     */
    if ((*source & 0x80) == 0) {
	rc = 1;
    } else if ((*source & 0xe0) == 0xc0) {
	rc = 2;
    } else if ((*source & 0xf0) == 0xe0) {
	rc = 3;
    } else if ((*source & 0xf8) == 0xf0) {
	rc = 4;
    } else if ((*source & 0xfc) == 0xf8) {
	rc = 5;
    } else if ((*source & 0xfe) == 0xfc) {
	rc = 6;
    }

    /*
     * sanity-check.
     */
    if (rc > 1) {
	int have = rc;

	if ((int) limit < have)
	    have = (int) limit;

	for (j = 1; j < have; j++) {
	    if ((source[j] & 0xc0) != 0x80)
		break;
	}
	if (j != have) {
	    TRACE2(("check failed %d/%d in vl_check_utf8\n", j, rc));
	    rc = 0;
	}
    }
    return rc;
}

int
vl_conv_to_utf32(UINT * target, const char *source, B_COUNT limit)
{
#define CH(n) (UCHAR)((*target) >> ((n) * 8))
    int rc = vl_check_utf8(source, limit);

    if ((B_COUNT) rc > limit) {	/* whatever it is, we cannot decode it */
	TRACE2(("limit failed %d/%ld in vl_conv_to_utf32\n", rc, limit));
	rc = 0;
    }

    if (target != 0) {
	UINT mask = 0;
	int j;
	int shift = 0;
	*target = 0;

	switch (rc) {
	case 1:
	    mask = (UINT) * source;
	    break;
	case 2:
	    mask = (UINT) (*source & 0x1f);
	    break;
	case 3:
	    mask = (UINT) (*source & 0x0f);
	    break;
	case 4:
	    mask = (UINT) (*source & 0x07);
	    break;
	case 5:
	    mask = (UINT) (*source & 0x03);
	    break;
	case 6:
	    mask = (UINT) (*source & 0x01);
	    break;
	default:
	    mask = 0;
	    break;
	}

	for (j = 1; j < rc; j++) {
	    *target |= (UINT) (source[rc - j] & 0x3f) << shift;
	    shift += 6;
	}
	*target |= mask << shift;

	TRACE2(("encode %2d:%.*s -> %#08x %02X.%02X.%02X.%02X\n",
		rc, rc, source,
		*target,
		CH(3), CH(2), CH(1), CH(0)));
    }
    return rc;
#undef CH
}

static const BOM_TABLE *
find_mark_info(BOM_CODES code)
{
    const BOM_TABLE *result = 0;
    unsigned n;

    for (n = 0; n < TABLESIZE(bom_table); ++n) {
	const BOM_TABLE *mp = bom_table + n;
	if (mp->code == code) {
	    result = mp;
	    break;
	}
    }
    return result;
}

static BOM_CODES
get_bom(BUFFER *bp)
{
    BOM_CODES rc = (BOM_CODES) b_val(bp, VAL_BYTEORDER_MARK);
    if (rc == bom_NONE)
	rc = bp->implied_BOM;
    return rc;
}

/*
 * If we read a file without a byteorder-mark, it is using one of the
 * le-assumed or be-assumed values for the corresponding mode.  See what the
 * file-encoding is, and choose a specific byteorder-mark, needed when we
 * write the data to a file.
 */
static BOM_CODES
inferred_bom2(BUFFER *bp, BOM_CODES code)
{
    BOM_CODES result = code;

    switch (result) {
    case bom_LE_ASSUMED:
	switch (b_val(bp, VAL_FILE_ENCODING)) {
	case enc_UTF16:
	    result = bom_UTF16LE;
	    break;
	case enc_UTF32:
	    result = bom_UTF32LE;
	    break;
	default:
	    result = bom_NONE;
	    break;
	}
	break;
    case bom_BE_ASSUMED:
	switch (b_val(bp, VAL_FILE_ENCODING)) {
	case enc_UTF16:
	    result = bom_UTF16BE;
	    break;
	case enc_UTF32:
	    result = bom_UTF32BE;
	    break;
	default:
	    result = bom_NONE;
	    break;
	}
	break;
    case bom_NONE:
	switch (b_val(bp, VAL_FILE_ENCODING)) {
	case enc_UTF16:
	    result = bom_UTF16LE;
	    break;
	case enc_UTF32:
	    result = bom_UTF32LE;
	    break;
	}
	break;
    default:
	break;
    }
#if OPT_TRACE > 1
    if (result != code)
	TRACE2(("inferred_bom(%s) %s\n",
		byteorder2s(code),
		byteorder2s(result)));
#endif
    return result;
}

static BOM_CODES
inferred_bom(BUFFER *bp, const BOM_TABLE * mp)
{
    return inferred_bom2(bp, mp->code);
}

/*
 * If the buffer has no explicit byteorder-mark, but the encoding is UTF-16
 * or UTF-32, we still need to know the assumed or implicit byteorder-mark.
 *
 * When reading the buffer, and no byteorder-mark is found for UTF-16/-32,
 * we store an implied BOM in the buffer attributes, and set an assumed
 * byteorder-mark that the user can see/modify.  If the assumed BOM is reset,
 * e.g., to auto or none, we can still use the implied BOM, e.g., for writing
 * the file.
 */
static const BOM_TABLE *
find_mark_info2(BUFFER *bp)
{
    const BOM_TABLE *mp = find_mark_info(get_bom(bp));

    if ((mp != 0) &&
	(mp->size == 0) &&
	(b_val(bp, VAL_FILE_ENCODING) > enc_UTF8)) {
	mp = find_mark_info(inferred_bom(bp, mp));
    } else if (mp == 0 &&
	       (b_val(bp, VAL_FILE_ENCODING) > enc_UTF8)) {
	mp = find_mark_info(inferred_bom2(bp, (BOM_CODES) b_val(bp, VAL_BYTEORDER_MARK)));
    }
    return mp;
}

static int
line_has_mark(const BOM_TABLE * mp, UCHAR * buffer, B_COUNT length)
{
    int result = FALSE;

    if (length >= mp->size
	&& mp->size != 0
	&& memcmp(buffer, mp->mark, mp->size) == 0) {
	result = TRUE;
    }
    return result;
}

static int
dump_as_utfXX(BUFFER *bp, const char *buf, int nbuf, const char *ending)
{
#define BYTE_OF(k,n) (char) (bp->decode_utf_buf[k] >> ((n) * 8))
    int rc = 0;
    const BOM_TABLE *mp = find_mark_info2(bp);

    if (mp != 0 && mp->size > 1) {
	size_t j = 0;
	size_t k = 0;
	size_t need = (size_t) nbuf + strlen(ending);
	size_t lend = strlen(ending);

	if (!allow_encoder(bp, need * mp->size))
	    goto finish;
	if (!allow_decoder(bp, need))
	    goto finish;

	while (j < (unsigned) nbuf) {
	    int skip = vl_conv_to_utf32(bp->decode_utf_buf + k++,
					buf + j,
					(B_COUNT) ((UINT) nbuf - j));
	    if (skip == 0)
		goto finish;
	    j += (UINT) skip;
	}
	while (*ending != 0) {
	    int skip = vl_conv_to_utf32(bp->decode_utf_buf + k++,
					ending++,
					(B_COUNT) (lend--));
	    if (skip == 0)
		goto finish;
	}
	need = k;

	for (j = k = 0; k < need; j += mp->size, ++k) {
	    switch (mp->code) {
	    case bom_NONE:
		/* FALLTHRU */
	    case bom_UTF8:
		/* FALLTHRU */
	    case bom_LE_ASSUMED:
		/* FALLTHRU */
	    case bom_BE_ASSUMED:
		/* ignored */
		break;
	    case bom_UTF16LE:
		bp->encode_utf_buf[j + 0] = BYTE_OF(k, 0);
		bp->encode_utf_buf[j + 1] = BYTE_OF(k, 1);
		break;
	    case bom_UTF16BE:
		bp->encode_utf_buf[j + 1] = BYTE_OF(k, 0);
		bp->encode_utf_buf[j + 0] = BYTE_OF(k, 1);
		break;
	    case bom_UTF32LE:
		bp->encode_utf_buf[j + 0] = BYTE_OF(k, 0);
		bp->encode_utf_buf[j + 1] = BYTE_OF(k, 1);
		bp->encode_utf_buf[j + 2] = BYTE_OF(k, 2);
		bp->encode_utf_buf[j + 3] = BYTE_OF(k, 3);
		break;
	    case bom_UTF32BE:
		bp->encode_utf_buf[j + 3] = BYTE_OF(k, 0);
		bp->encode_utf_buf[j + 2] = BYTE_OF(k, 1);
		bp->encode_utf_buf[j + 1] = BYTE_OF(k, 2);
		bp->encode_utf_buf[j + 0] = BYTE_OF(k, 3);
		break;
	    }
	}
	rc = (int) j;
    }
  finish:
    return rc;
#undef BYTE_OF
}

static void
set_byteorder_mark(BUFFER *bp, int value)
{
    if (value != ENUM_UNKNOWN
	&& value != global_b_val(VAL_BYTEORDER_MARK)) {
	set_local_b_val(bp, VAL_BYTEORDER_MARK, value);

	TRACE(("set_byteorder_mark for '%s' to %s\n",
	       bp->b_bname,
	       byteorder2s(b_val(bp, VAL_BYTEORDER_MARK))));
    }
}

static void
set_encoding(BUFFER *bp, int value)
{
    if (value != ENUM_UNKNOWN
	&& value != global_b_val(VAL_FILE_ENCODING)) {
	set_local_b_val(bp, VAL_FILE_ENCODING, value);

	TRACE(("set_encoding for '%s' to %s\n",
	       bp->b_bname,
	       encoding2s(b_val(bp, VAL_FILE_ENCODING))));
    }
}

static int
load_as_utf8(BUFFER *bp, LINE *lp)
{
#define CH(n) ((UCHAR)(lgetc(lp, n)))
    int rc = FALSE;
    const BOM_TABLE *mp = find_mark_info2(bp);

    if (mp != 0 && mp->size > 1) {
	int pass;
	size_t j, k;
	size_t need = (size_t) llength(lp);
	size_t used;

	TRACE2(("load_as_utf8:%d:%s\n", need, lp_visible(lp)));
	if (allow_decoder(bp, need)) {
	    rc = TRUE;
	    if (need) {
		for (j = k = 0; j < need; ++k) {
		    UCHAR ch = CH(j);
		    if (ch == '\r' || ch == '\n') {
			bp->decode_utf_buf[k] = ch;
			++j;	/* see remove_crlf_nulls() */
			continue;
		    }
		    switch (inferred_bom(bp, mp)) {
		    case bom_NONE:
			/* FALLTHRU */
		    case bom_UTF8:
			/* FALLTHRU */
		    case bom_LE_ASSUMED:
			/* FALLTHRU */
		    case bom_BE_ASSUMED:
			/* ignored */
			break;
		    case bom_UTF16LE:
			bp->decode_utf_buf[k] = (CH(j)
						 + (UINT) (CH(j + 1) << 8));
			break;
		    case bom_UTF16BE:
			bp->decode_utf_buf[k] = (CH(j + 1)
						 + (UINT) (CH(j) << 8));
			break;
		    case bom_UTF32LE:
			bp->decode_utf_buf[k] = (CH(j + 0)
						 + (UINT) (CH(j + 1) << 8)
						 + (UINT) (CH(j + 2) << 16)
						 + (UINT) (CH(j + 3) << 24));
			break;
		    case bom_UTF32BE:
			bp->decode_utf_buf[k] = (CH(j + 3)
						 + (UINT) (CH(j + 2) << 8)
						 + (UINT) (CH(j + 1) << 16)
						 + (UINT) (CH(j + 0) << 24));
			break;
		    }
		    j += (UINT) mp->size;
		}
		used = k;

		for (pass = 1; pass <= 2; ++pass) {
		    UCHAR *buffer = (pass == 1) ? 0 : (UCHAR *) lvalue(lp);
		    for (j = k = 0; j < used; ++j) {
			int nn = vl_conv_to_utf8(buffer,
						 bp->decode_utf_buf[j],
						 (B_COUNT) (used + 1 - j));
			if (buffer != 0)
			    buffer += nn;
			k += (UINT) nn;
		    }
		    if (pass == 1) {
			TRACE2(("need %d, have %d\n", k, lp->l_size));
			if ((int) k > llength(lp)) {
			    char *ntext;

			    /*
			     * We are doing this conversion on the initial load
			     * of the buffer, do not want to allow undo.  Just
			     * go ahead and reallocate the line's text buffer.
			     */
			    if ((ntext = castalloc(char, (k + 1))) == NULL) {
				rc = FALSE;
				break;
			    }
			    ltextfree(lp, bp);
			    lvalue(lp) = ntext;
			    lp->l_size = k;
			    llength(lp) = (int) k;
			} else {
			    llength(lp) = (int) k;
			}
		    }
		}
	    }
	} else {
	    bp->decode_utf_len = 0;
	}
    }
    return rc;
#undef CH
}

/*
 * Remove the extra nulls (if any - according to the encoding) after
 * \r and \n bytes.  This is done to make the existing logic for checking
 * recordseparator work without change.
 */
static void
remove_crlf_nulls(BUFFER *bp, UCHAR * buffer, B_COUNT * length)
{
    const BOM_TABLE *mp = find_mark_info2(bp);
    UCHAR mark_cr[4];
    UCHAR mark_lf[4];
    size_t marklen = 0;

    if (mp != 0) {
	memset(mark_cr, 0, sizeof(mark_cr));
	memset(mark_lf, 0, sizeof(mark_lf));

	switch (mp->code) {
	case bom_NONE:
	    /* FALLTHRU */
	case bom_UTF8:
	    /* FALLTHRU */
	case bom_LE_ASSUMED:
	    /* FALLTHRU */
	case bom_BE_ASSUMED:
	    /* ignored */
	    break;
	case bom_UTF16LE:
	    marklen = 2;
	    mark_cr[0] = '\r';
	    mark_lf[0] = '\n';
	    break;
	case bom_UTF16BE:
	    marklen = 2;
	    mark_cr[1] = '\r';
	    mark_lf[1] = '\n';
	    break;
	case bom_UTF32LE:
	    marklen = 4;
	    mark_cr[0] = '\r';
	    mark_lf[0] = '\n';
	    break;
	case bom_UTF32BE:
	    marklen = 4;
	    mark_cr[3] = '\r';
	    mark_lf[3] = '\n';
	    break;
	}
	if (marklen != 0) {
	    B_COUNT dst = 0;
	    B_COUNT src = 0;
	    char skip = 0;
	    while (src < *length) {
		if (!memcmp(mark_cr, buffer + src, marklen))
		    skip = '\r';
		else if (!memcmp(mark_lf, buffer + src, marklen))
		    skip = '\n';
		if (skip) {
		    buffer[dst++] = (UCHAR) skip;
		    skip = 0;
		} else {
		    memcpy(buffer + dst, buffer + src, marklen);
		    dst += (B_COUNT) marklen;
		}
		src += (B_COUNT) marklen;
	    }
	    *length = dst;
	}
    }
}

/*
 * Returns a percentage for the number of cells in the buffer which are
 * explained by interpreting them according to the given byte-order mark
 * pattern with the assumption that most of the content is ASCII or ISO-8859-1
 * (8-bits).
 */
static int
riddled_buffer(const BOM_TABLE * mp, UCHAR * buffer, B_COUNT length)
{
    int result = 0;
    B_COUNT total = 0;
    size_t offset = 0;
    size_t j, k;

    if (mp->size && !(mp->size % 2)) {
	TRACE(("checking if %s / %u-byte\n",
	       byteorder2s(mp->code),
	       (UINT) mp->size));

	/* Check the line-length.  If it is not a multiple of the pattern
	 * size, just give up.
	 */
	if ((length + offset) % mp->size) {
	    TRACE(("length %ld vs pattern %u - give up\n",
		   length,
		   (UINT) mp->size));
	} else {
	    /*
	     * Now walk through the line and measure the pattern against it.
	     */
	    for (j = offset; j < (unsigned) length; j += mp->size) {
		int found = 1;
		for (k = 0; k < mp->size; ++k) {
		    UCHAR have = buffer[j + k];
		    UCHAR want = (UCHAR) IsNonNull(mp->mark[k]);
		    if (!have ^ !want) {
			found = 0;
			break;
		    }
		}
		if (found) {
		    total += (B_COUNT) mp->size;
		}
	    }
	}
	result = (int) (length
			? (((100.0 * (double) total) / (double) length))
			: 0);

	TRACE(("...%ld/%ld ->%d%%\n", total, length, result));
    }
    return result;
}

static void
set_encoding_from_bom(BUFFER *bp, BOM_CODES bom_value)
{
    const BOM_TABLE *mp;
    int result;

    if (bom_value > bom_NONE
	&& (mp = find_mark_info(bom_value)) != 0) {

	switch (mp->code) {
	case bom_UTF8:
	    result = enc_UTF8;
	    break;
	case bom_UTF16LE:
	case bom_UTF16BE:
	    result = enc_UTF16;
	    break;
	case bom_UTF32LE:
	case bom_UTF32BE:
	    result = enc_UTF32;
	    break;
	default:
	    result = ENUM_UNKNOWN;
	    break;
	}
	TRACE(("set_encoding_from_bom(%s) ->%s\n",
	       byteorder2s(mp->code),
	       encoding2s(result)));
	set_encoding(bp, result);
    }
}

static void
set_bom_from_encoding(BUFFER *bp, int enc_value)
{
    int result = b_val(bp, VAL_BYTEORDER_MARK);

    if (result > bom_NONE) {
	switch (enc_value) {
	case enc_UTF8:
	case enc_UTF16:
	case enc_UTF32:
	    break;
	default:
	    if (result != ENUM_UNKNOWN
		&& result != global_b_val(VAL_BYTEORDER_MARK)) {
		set_local_b_val(bp, VAL_BYTEORDER_MARK, bom_NONE);
	    }
	    break;
	}
    }
}

/******************************************************************************/

int
aligned_charset(BUFFER *bp, UCHAR * buffer, B_COUNT * length)
{
    int rc = FALSE;
    const BOM_TABLE *mp = find_mark_info(get_bom(bp));

    (void) buffer;
    if (mp != 0 && mp->size > 1) {
	rc = !(*length % mp->size);
    }
    return rc;
}

int
cleanup_charset(BUFFER *bp, UCHAR * buffer, B_COUNT * length)
{
    remove_crlf_nulls(bp, buffer, length);
    return TRUE;
}

/*
 * Call this once after reading the buffer (or the first line).
 * But do it before deducing the majormode (to avoid conflict with "preamble").
 *
 * It checks if the byteorder-mark is "auto", and if so, looks at the
 * line to determine what value to use.  It sets the local buffer mode
 * for the result.
 *
 * Having a value other than "none", it then modifies the first line,
 * stripping the BOM bytes.
 */
int
decode_bom(BUFFER *bp, UCHAR * buffer, B_COUNT * length)
{
    const BOM_TABLE *mp;
    int code = FALSE;
    int result;
    unsigned n;

    TRACE((T_CALLED "decode_bom(%s) length %ld\n", bp->b_bname, *length));

    if (b_val(bp, VAL_BYTEORDER_MARK) == ENUM_UNKNOWN) {
	result = bom_NONE;
	for (n = 0; n < TABLESIZE(bom_table); ++n) {
	    mp = bom_table + n;
	    if (line_has_mark(mp, buffer, *length)) {
		result = mp->code;
		TRACE(("...matched %d\n", result));
		break;
	    }
	}
	set_byteorder_mark(bp, result);
    }

    if (b_val(bp, VAL_BYTEORDER_MARK) > bom_NONE
	&& (mp = find_mark_info((BOM_CODES) b_val(bp,
						  VAL_BYTEORDER_MARK))) != 0
	&& line_has_mark(mp, buffer, *length)) {
	for (n = 0; n < *length - mp->size; ++n) {
	    buffer[n] = buffer[n + mp->size];
	}
	while (n < *length) {
	    buffer[n++] = 0;
	}
	*length -= (B_COUNT) mp->size;

	set_encoding_from_bom(bp, (BOM_CODES) b_val(bp, VAL_BYTEORDER_MARK));
	code = TRUE;
    }
    returnCode(code);
}

/*
 * Rewrite the line from UTF-16 or UTF-32 into UTF-8.
 * That may increase the number of bytes used to store the data.
 */
int
decode_charset(BUFFER *bp, LINE *lp)
{
    int rc = FALSE;

    if (b_val(bp, VAL_FILE_ENCODING) == enc_UTF16
	|| b_val(bp, VAL_FILE_ENCODING) == enc_UTF32) {
	rc = load_as_utf8(bp, lp);
    }
    return rc;
}

/*
 * Check if we have an explicit encoding.  If not, inspect the buffer contents
 * to decide what encoding to use.
 *
 * By observation, some UTF-16 files written by other editors have no BOM.  It
 * is possible that UTF-32 files may be missing a BOM as well.  We can
 * determine this by seeing if the file is riddled with nulls (in the right
 * pattern of course).  If we find a match for one of these, recode the buffer
 * into UTF-8.
 *
 * If the encoding is unknown or 8-bit, we can inspect the buffer to see if it
 * makes more sense as UTF-8.
 */
int
deduce_charset(BUFFER *bp, UCHAR * buffer, B_COUNT * length, int always)
{
    int rc = FALSE;

    TRACE((T_CALLED "deduce_charset(%s) bom:%s, encoding:%s\n",
	   bp->b_bname,
	   byteorder2s(b_val(bp, VAL_BYTEORDER_MARK)),
	   encoding2s(b_val(bp, VAL_FILE_ENCODING))));

    bp->implied_BOM = bom_NONE;
    if (b_is_enc_AUTO(bp)) {
	unsigned n;
	int match = 0;
	int found = -1;

	for (n = 0; n < TABLESIZE(bom_table); ++n) {
	    int check = riddled_buffer(&bom_table[n], buffer, *length);
	    if (check > match) {
		match = check;
		found = (int) n;
	    }
	}
	if (found > 0 && match >= b_val(bp, VAL_PERCENT_UTF8)) {
	    bp->implied_BOM = bom_table[found].code;
	    set_encoding_from_bom(bp, bp->implied_BOM);
	    TRACE(("...found_charset %s\n",
		   byteorder2s(bp->implied_BOM)));

	    switch (bp->implied_BOM) {
	    case bom_UTF16BE:
	    case bom_UTF32BE:
		set_byteorder_mark(bp, bom_BE_ASSUMED);
		break;
	    case bom_UTF16LE:
	    case bom_UTF32LE:
		set_byteorder_mark(bp, bom_LE_ASSUMED);
		break;
	    default:
		break;
	    }
	    rc = TRUE;
	} else if (always) {
	    TRACE(("...try looking for UTF-8\n"));
	    if (check_utf8(buffer, *length) == TRUE)
		found_utf8(bp);
	}
    } else {
	rc = TRUE;
    }
    remove_crlf_nulls(bp, buffer, length);
    returnCode(rc);
}

/*
 * Check if the given buffer should be treated as UTF-8.
 * For UTF-8, we have to have _some_ UTF-8 encoding, and _all_
 * of the buffer has to match the pattern.
 */
int
check_utf8(UCHAR * buffer, B_COUNT length)
{
    B_COUNT n;
    int check = TRUE;
    int skip = 0;
    int found;
    UINT target;

    for (n = 0, found = 0; n < length - 1; n += (B_COUNT) skip) {
	skip = vl_conv_to_utf32(&target,
				(char *) (buffer + n),
				length - n);
	if (skip == 0) {
	    check = FALSE;
	    break;
	} else if (skip > 1) {
	    found = 1;
	}
    }
    return ((check && found)
	    ? TRUE
	    : (check
	       ? SORTOFTRUE
	       : FALSE));
}

/*
 * If we found UTF-8 encoding, set the buffer to match.
 */
void
found_utf8(BUFFER *bp)
{
    TRACE(("...found UTF-8\n"));
    bp->implied_BOM = bom_UTF8;
    set_encoding_from_bom(bp, bp->implied_BOM);
}

/*
 * encode BOM while writing file, without modifying the buffer.
 */
int
write_bom(BUFFER *bp)
{
    const BOM_TABLE *mp;
    int status = FIOSUC;

    if ((mp = find_mark_info((BOM_CODES) b_val(bp, VAL_BYTEORDER_MARK))) != 0) {
	status = ffputline((const char *) mp->mark, (int) mp->size, NULL);
    }
    return status;
}

/*
 * encode the UTF-8 text into UTF-16 or UTF-32, according to the buffer's
 * file-encoding mode.
 */
int
encode_charset(BUFFER *bp, const char *buf, int nbuf, const char *ending)
{
    int rc = 0;

    if (b_val(bp, VAL_FILE_ENCODING) == enc_UTF16
	|| b_val(bp, VAL_FILE_ENCODING) == enc_UTF32) {
	rc = dump_as_utfXX(bp, buf, nbuf, ending ? ending : "");
    }
    return rc;
}

/*
 * if byteorder mark changes, ensure that file-encoding is set compatibly.
 */
int
chgd_byteorder(BUFFER *bp,
	       VALARGS * args,
	       int glob_vals,
	       int testing)
{
    if (!testing && !glob_vals) {
	set_encoding_from_bom(bp, (BOM_CODES) args->local->vp->i);
    }
    return TRUE;
}

/*
 * If file-encoding changes to non-UTF-8, set byteorder-mark to none.
 * Only keep it set if changing from one UTF-encoding to another.
 */
int
chgd_fileencode(BUFFER *bp,
		VALARGS * args,
		int glob_vals,
		int testing)
{
    if (testing) {
	;
    } else {
	int new_encoding = args->local->vp->i;
	if (glob_vals) {
	    if (new_encoding == enc_POSIX) {
		rebuild_charclasses(0, 127);
	    } else {
		rebuild_charclasses(global_g_val(GVAL_PRINT_LOW),
				    global_g_val(GVAL_PRINT_HIGH));
	    }
	} else {
	    set_bom_from_encoding(bp, new_encoding);
	}
	set_bufflags(glob_vals, WFHARD | WFMODE);
    }
    return TRUE;
}

const char *
byteorder2s(int code)
{
    return choice_to_name(&fsm_byteorder_mark_blist, code);
}

const char *
encoding2s(int code)
{
    return choice_to_name(&fsm_file_encoding_blist, code);
}
vile-9.8v/chgdfunc.h000066400000000000000000000032201415556424100144550ustar00rootroot00000000000000/*
 * Prototypes for functions in the mode-tables (must be declared before the
 * point at which proto.h is included).
 *
 * $Id: chgdfunc.h,v 1.24 2008/11/08 13:40:12 tom Exp $
 */
extern int chgd_autobuf  (CHGD_ARGS);
extern int chgd_buffer   (CHGD_ARGS);
extern int chgd_charset  (CHGD_ARGS);
extern int chgd_disabled (CHGD_ARGS);
extern int chgd_dos_mode (CHGD_ARGS);
extern int chgd_fences   (CHGD_ARGS);
extern int chgd_hilite   (CHGD_ARGS);
extern int chgd_major    (CHGD_ARGS);
extern int chgd_mouse    (CHGD_ARGS);
extern int chgd_percent  (CHGD_ARGS);
extern int chgd_rs       (CHGD_ARGS);
extern int chgd_status   (CHGD_ARGS);
extern int chgd_undoable (CHGD_ARGS);
extern int chgd_uniqbuf  (CHGD_ARGS);
extern int chgd_win_mode (CHGD_ARGS);
extern int chgd_window   (CHGD_ARGS);
extern int chgd_working  (CHGD_ARGS);
extern int chgd_xterm    (CHGD_ARGS);
extern int chgd_xtermkeys(CHGD_ARGS);

#if OPT_COLOR
extern int chgd_color    (CHGD_ARGS);
#endif

#if OPT_COLOR_SCHEMES
extern int chgd_scheme   (CHGD_ARGS);
#endif

#if OPT_CURTOKENS   
extern int chgd_curtokens(CHGD_ARGS);
#endif

#if OPT_FINDPATH
extern int chgd_find_cfg(CHGD_ARGS);
#endif

#if OPT_MAJORMODE
extern int chgd_mm_order (CHGD_ARGS);
extern int chgd_filter   (CHGD_ARGS);
#endif

#if OPT_MULTIBYTE
extern int chgd_byteorder(CHGD_ARGS);
extern int chgd_fileencode(CHGD_ARGS);
#endif

#if OPT_TITLE
extern int chgd_swaptitle(CHGD_ARGS);
#endif

#if SYS_WINNT && defined(VILE_OLE)
extern int chgd_redir_keys(CHGD_ARGS);
#endif

#if SYS_WINNT
extern int chgd_icursor(CHGD_ARGS);
extern int chgd_popupmenu(CHGD_ARGS);
extern int chgd_rcntfiles(CHGD_ARGS);
extern int chgd_rcntfldrs(CHGD_ARGS);
#endif
vile-9.8v/cmdtbl000066400000000000000000001725121415556424100137260ustar00rootroot00000000000000# This file contains all of the editor's command and key linkages.
# It also contains data for tables which are automatically generated in the
# editor.
#
# It should be processed by the "mktbls" program, which produces the
#  headers #included by main.c
#
# All that is necessary to add a new function to the editor is to add
#  an entry to this file, write the function, make sure it's in the
#  makefile, and rebuild.  (This is not to be confused with adding a
#  new key binding, which can be done with the rebind command if it
#  was compiled in.)
#
# If you want to know which keyboard bindings are already taken, look
#  at nebind.h, after you build it.
#
# The entries are functions within the editor.  They _must_ match the
#  functions' names.  On the same line as the name is the set of flags
#  describing that function.
# Also accompanying each function is a list of english names  for the
#  command, in double quotes, and a list of keys bound to the command,
#  in single quotes.  These are the default key bindings -- they can change
#  at runtime.  English names must be all lowercase.
# Any function, name, or key may be followed by a conditional, i.e. the
#  name of a preprocessor #define which must be defined non-zero for that
#  line to become part of the editor.  If a function name is made conditional,
#  the names and keys listed with it will be conditional also.
# The names and keys must be preceded by a tab character.
# Blank lines must be completely empty.
# For convenience only, this table is kept in roughly alphabetical order,
#  by first character of function name.
#
# For example, consider the following entry:
#
#	somefunc	ABSM|MOTION		BSD|DOS
#		"funkycom"
#		'^X-F'
#		'FN-2'				DOS
#		'M-s'
#
# As a special case, if a function key definition ('FN-A') is followed
# by a conditional beginning with "KEY_", like:
#		'FN-A'				KEY_Up
# then that name is output to nefkeys.h as a SPEC|x definition, for use
# by the screen/keyboard drivers.  The key is also bound, as usual, and
# is made conditional on the _third_ field on the line.  (Since KEY_xxx
# definitions are meant to be pretty generic, there should be little
# need for conditional build-time binding.)
#
# This says that somefunc() is an absolute motion command, that it should
#  only be included in the editor if we're running BSD or DOS, that its
#  english name as one would type on the command line is "funkycom", and
#  that it is bound to ^X-F, to function key 2 under DOS, and to "meta-s",
#  that is, an 's' with the high bit set.
#
# Function flags have the following meanings:
#	REDO means the dotcmd command recorder should be halted, so that
#		the command can be redone.
#	UNDO means the undo stacks should be cleared, in preparation for
#		an undoable command.
#	OPER means the command is an "operator", that is, it acts on a region
#		demarcated by the current cursor position and the cursor
#		position following a subsequent motion command.
#	MOTION means this command moves dot, and specifically is compatible
#		with the operator commands.
#	FL only occurs with MOTION, means that if the motion is an argument
#		to an operator, the operation should affect Full Lines
#	ABSM only occurs with MOTION, means that the motion is absolute,
#		i.e. not relative to the current position or screen.  It causes
#		the "lastdotmark", ldmark to be set to dot before the move
#		takes place.
#	MINIBUF is a special case, commands which can be used in the
#		minibuffer.  This includes MOTION and editing commands.
#	GOAL signifies a motion that will attempt to retain the
#		current column position after the motion.
#	GLOBOK says the function can follow a global command
#		(e.g. the 'd' in "g/pattern/d")
#
#	This file was designed and constructed by Paul Fox for vile, (c)1990
#
#	Some of the flags given are "ex" flags, related to what
#		kind of line-range arguments the command can take.  Not all are
#		currently used or implemented, but they were defined in the
#		command table for the Steve Kirkendall's elvis editor, so I
#		included them here for completeness.
#	BANG says the command (in real vi) can take a trailing ! character,
#		and will behave differently.  In vile, most such commands
#		have separate entries, e.g. quit and quithard and separate
#		functions which are executed.  in some cases this is very
#		impractical, as is the case with w and w!  -- so, if a command
#		is entered ending with a '!' (it must be in this table by
#		that name) _and_ the BANG flag is set for that command, then
#		the function will be invoked with "special" values for f and
#		n (i.e. values unlikely to be typed) so the function can
#		distinguish the two cases.
#		If the BANG flag appears, and there is no command-name ending
#		in '!' listed, then the flag does nothing, and should be
#		viewed simply as documentation.
#
# $Id: cmdtbl,v 1.273 2013/03/31 14:13:46 tom Exp $
#
#

abbrev		EXRCOK|EXTRA
	"abbreviate"
	"list-abbreviations"		!FEWNAMES
	"show-abbreviations"
	
altbuff		NONE
	"alternate-buffer"		!FEWNAMES
	'^^'
	'CTRL+6'			W32KY	SYS_WINNT
	
append		REDO|UNDO
	"append-chars"			!FEWNAMES
	'a'
	
append_i	REDO|UNDO
	"append-indented-chars"		!FEWNAMES
	"a!"
	
appstring	REDO|UNDO		!SMALLER
	"append-string"
	
appnumber	REDO|UNDO		!SMALLER
	"append-number"
	
appendeol	REDO|UNDO
	"append-chars-at-eol"		!FEWNAMES
	'A'
	
backchar	MOTION|MINIBUF
	"backward-character"		!FEWNAMES
	
backchar_to_bol	MOTION|MINIBUF
	"backward-character-to-bol"	!FEWNAMES
	"left-arrow"
	'h'
	'^H'
	'^?'
	'FN-D'				KEY_Left
	
backdelchar	REDO|UNDO|MINIBUF
	"delete-previous-character"	!FEWNAMES
	'X'
	
backhunt	ABSM|MOTION		!SMALLER
	"hunt-backward"
	
backhpage	MOTION
	"previous-half-page"		!FEWNAMES
	"back-half-page"		!FEWNAMES
	"up-half-page"			!FEWNAMES
	'^U'
	
backline	GOAL|MOTION|FL
	"previous-line"			!FEWNAMES
	"back-line"			!FEWNAMES
	"up-line"			!FEWNAMES
	"up-arrow"			!FEWNAMES
	'k'
	'^P'
	'FN-A'				KEY_Up
	
backbline	MOTION|FL
	"previous-line-at-bol"		!FEWNAMES
	"back-line-at-bol"		!FEWNAMES
	"up-line-at-bol"		!FEWNAMES
	'-'
	
backpage	MOTION
	"previous-page"			!FEWNAMES
	"back-page"			!FEWNAMES
	'^B'
	'FN-p'				KEY_Prior
	
back_row	GOAL|MOTION
	'^X-^U'
	"backward-row"			!FEWNAMES
	"previous-row"			!FEWNAMES
	
backword	MOTION|MINIBUF
	"previous-word"			!FEWNAMES
	"back-word"			!FEWNAMES
	'B'
	
backviword	MOTION|MINIBUF
	"previous-punctuated-word"	!FEWNAMES
	"back-punctuated-word"		!FEWNAMES
	'b'
	
backsearch	ABSM|MOTION
	"search-reverse"		!FEWNAMES
	'?'
	
bcsrch		MOTION|MINIBUF
	"backward-char-scan"		!FEWNAMES
	'F'
	
bcsrch_to	MOTION|MINIBUF
	"backward-char-scan-to"		!FEWNAMES
	'T'
	
bindkey		NONE			OPT_REBIND
	"bind-key"
	"rebind-key"
	
bind_i_key	NONE			OPT_REBIND
	"bind-insmode-key"
	"rebind-insmode-key"
	
bind_c_key	NONE			OPT_REBIND
	"bind-cmdmode-key"
	"rebind-cmdmode-key"
	
bind_s_key	NONE			OPT_REBIND
	"bind-selmode-key"
	"rebind-selmode-key"
	
bktoshell	BANG			OPT_SHELL
	"suspend"
	"suspend!"
	"stop"
	"stop!"
	'^Z'
	
vl_chdir	NONE			OPT_SHELL
	"cd"
	"change-directory"
	
cntl_x_func	NONE
	"cntl_x-prefix"
	'^X'
	
chgchar		REDO|UNDO
	"change-char"			!FEWNAMES
	"delete-char-and-insert-chars"	!FEWNAMES
	's'
	
chgline		REDO|UNDO
	"change-line"			!FEWNAMES
	"delete-line-and-insert-chars"	!FEWNAMES
	'S'
	
chgtoeol	REDO|UNDO
	"change-to-eol"			!FEWNAMES
	"delete-to-eol-and-insert-chars" !FEWNAMES
	'C'
	
clear_match_attrs	NONE		OPT_HILITEMATCH
	"clear-visual-matches"
	'='
	
clrmes		NONE
	"clear-message-line"		!FEWNAMES
	
comp_err_exps	NONE			OPT_FINDERR
	"compile-error-expressions"
	<(re)compile the [Error Expressions] buffer>
show_err_regex	NONE			OPT_FINDERR
	"list-error-expressions"	!FEWNAMES
	"show-error-expressions"
	
consearch	ABSM|MOTION
	"continue-search"		!FEWNAMES
	'n'
	
opercopy	OPER|RANGE|EXTRA
	"copy-til"
	"co"
	
kbd_mac_startstop	NONE
	"end-keyboard-macro"		!FEWNAMES
	"begin-keyboard-macro"		!FEWNAMES
	'^X-('
	'^X-)'
	
kbd_mac_exec	REDO|UNDO|VIEWOK
	"execute-keyboard-macro"	!FEWNAMES
	'^X-&'
	
kbd_mac_save	NONE
	"save-keyboard-macro"
	'^X-^'
	
cbuf1		REDO			OPT_EXEC_MACROS>0
	"execute-macro-1"		!FEWNAMES
	'FN-1'				KEY_F1
	'FN-P'				KEY_KP_F1
	
cbuf2		REDO			OPT_EXEC_MACROS>1
	"execute-macro-2"		!FEWNAMES
	'FN-2'				KEY_F2
	'FN-Q'				KEY_KP_F2
	
cbuf3		REDO			OPT_EXEC_MACROS>2
	"execute-macro-3"		!FEWNAMES
	'FN-3'				KEY_F3
	'FN-R'				KEY_KP_F3
	
cbuf4		REDO			OPT_EXEC_MACROS>3
	"execute-macro-4"		!FEWNAMES
	'FN-4'				KEY_F4
	'FN-S'				KEY_KP_F4
	
cbuf5		REDO			OPT_EXEC_MACROS>4
	"execute-macro-5"		!FEWNAMES
	'FN-5'				KEY_F5
	
cbuf6		REDO			OPT_EXEC_MACROS>5
	"execute-macro-6"		!FEWNAMES
	'FN-6'				KEY_F6
	
cbuf7		REDO			OPT_EXEC_MACROS>6
	"execute-macro-7"		!FEWNAMES
	'FN-7'				KEY_F7
	
cbuf8		REDO			OPT_EXEC_MACROS>7
	"execute-macro-8"		!FEWNAMES
	'FN-8'				KEY_F8
	
cbuf9		REDO			OPT_EXEC_MACROS>8
	"execute-macro-9"		!FEWNAMES
	'FN-9'				KEY_F9
	
cbuf10		REDO			OPT_EXEC_MACROS>9
	'FN-0'				KEY_F10
	"execute-macro-10"		!FEWNAMES
	
cbuf11		REDO			OPT_EXEC_MACROS>10
	"execute-macro-11"		!FEWNAMES
	'FN-!'				KEY_F11
	
cbuf12		REDO			OPT_EXEC_MACROS>11
	'FN-@'				KEY_F12
	"execute-macro-12"		!FEWNAMES
	
cbuf13		REDO			OPT_EXEC_MACROS>12
	'FN-#'				KEY_F13
	"execute-macro-13"		!FEWNAMES
	
cbuf14		REDO			OPT_EXEC_MACROS>13
	'FN-$'				KEY_F14
	"execute-macro-14"		!FEWNAMES
	
cbuf15		REDO			OPT_EXEC_MACROS>14
	'FN-%'				KEY_F15
	"execute-macro-15"		!FEWNAMES
	
cbuf16		REDO			OPT_EXEC_MACROS>15
	'FN-^'				KEY_F16
	"execute-macro-16"		!FEWNAMES
	
cbuf17		REDO			OPT_EXEC_MACROS>16
	'FN-&'				KEY_F17
	"execute-macro-17"		!FEWNAMES
	
cbuf18		REDO			OPT_EXEC_MACROS>17
	'FN-*'				KEY_F18
	"execute-macro-18"		!FEWNAMES
	
cbuf19		REDO			OPT_EXEC_MACROS>18
	'FN-('				KEY_F19
	"execute-macro-19"		!FEWNAMES
	
cbuf20		REDO			OPT_EXEC_MACROS>19
	'FN-)'				KEY_F20
	"execute-macro-20"		!FEWNAMES
	
cbuf21		REDO			OPT_EXEC_MACROS>20
	'FN-\241'			KEY_F21
	"execute-macro-21"		!FEWNAMES
	
cbuf22		REDO			OPT_EXEC_MACROS>21
	'FN-\242'			KEY_F22
	"execute-macro-22"		!FEWNAMES
	
cbuf23		REDO			OPT_EXEC_MACROS>22
	'FN-\243'			KEY_F23
	"execute-macro-23"		!FEWNAMES
	
cbuf24		REDO			OPT_EXEC_MACROS>23
	'FN-\244'			KEY_F24
	"execute-macro-24"		!FEWNAMES
	
cbuf25		REDO			OPT_EXEC_MACROS>24
	'FN-\245'			KEY_F25
	"execute-macro-25"		!FEWNAMES
	
cbuf26		REDO			OPT_EXEC_MACROS>25
	'FN-\246'			KEY_F26
	"execute-macro-26"		!FEWNAMES
	
cbuf27		REDO			OPT_EXEC_MACROS>26
	'FN-\247'			KEY_F27
	"execute-macro-27"		!FEWNAMES
	
cbuf28		REDO			OPT_EXEC_MACROS>27
	'FN-\250'			KEY_F28
	"execute-macro-28"		!FEWNAMES
	
cbuf29		REDO			OPT_EXEC_MACROS>28
	'FN-\251'			KEY_F29
	"execute-macro-29"		!FEWNAMES
	
cbuf30		REDO			OPT_EXEC_MACROS>29
	'FN-\252'			KEY_F30
	"execute-macro-30"		!FEWNAMES
	
cbuf31		REDO			OPT_EXEC_MACROS>30
	'FN-\253'			KEY_F31
	"execute-macro-31"		!FEWNAMES
	
cbuf32		REDO			OPT_EXEC_MACROS>31
	'FN-\254'			KEY_F32
	"execute-macro-32"		!FEWNAMES
	
cbuf33		REDO			OPT_EXEC_MACROS>32
	'FN-\255'			KEY_F33
	"execute-macro-33"		!FEWNAMES
	
cbuf34		REDO			OPT_EXEC_MACROS>33
	'FN-\256'			KEY_F34
	"execute-macro-34"		!FEWNAMES
	
cbuf35		REDO			OPT_EXEC_MACROS>34
	'FN-\257'			KEY_F35
	"execute-macro-35"		!FEWNAMES
	
cbuf36		REDO			OPT_EXEC_MACROS>35
	"execute-macro-36"		!FEWNAMES
	'FN-\260'			KEY_F36
	
cbuf37		REDO			OPT_EXEC_MACROS>36
	"execute-macro-37"		!FEWNAMES
	'FN-\261'			KEY_F37
	
cbuf38		REDO			OPT_EXEC_MACROS>37
	"execute-macro-38"		!FEWNAMES
	'FN-\262'			KEY_F38
	
cbuf39		REDO			OPT_EXEC_MACROS>38
	"execute-macro-39"		!FEWNAMES
	'FN-\263'			KEY_F39
	
cbuf40		REDO			OPT_EXEC_MACROS>39
	"execute-macro-40"		!FEWNAMES
	'FN-\264'			KEY_F40
	
cbuf41		REDO			OPT_EXEC_MACROS>40
	"execute-macro-41"		!FEWNAMES
	'FN-\265'			KEY_F41
	
cbuf42		REDO			OPT_EXEC_MACROS>41
	"execute-macro-42"		!FEWNAMES
	'FN-\266'			KEY_F42
	
cbuf43		REDO			OPT_EXEC_MACROS>42
	"execute-macro-43"		!FEWNAMES
	'FN-\267'			KEY_F43
	
cbuf44		REDO			OPT_EXEC_MACROS>43
	"execute-macro-44"		!FEWNAMES
	'FN-\270'			KEY_F44
	
cbuf45		REDO			OPT_EXEC_MACROS>44
	"execute-macro-45"		!FEWNAMES
	'FN-\271'			KEY_F45
	
cbuf46		REDO			OPT_EXEC_MACROS>45
	"execute-macro-46"		!FEWNAMES
	'FN-\272'			KEY_F46
	
cbuf47		REDO			OPT_EXEC_MACROS>46
	"execute-macro-47"		!FEWNAMES
	'FN-\273'			KEY_F47
	
cbuf48		REDO			OPT_EXEC_MACROS>47
	"execute-macro-48"		!FEWNAMES
	'FN-\274'			KEY_F48
	
define_mode	NONE			OPT_MAJORMODE
	"define-majormode"
	"define-mode"
	
derive_mode	NONE			OPT_MAJORMODE
	"derive-majormode"
	"derive-mode"
	
define_submode	NONE			OPT_MAJORMODE
	"define-submode"
	
define_color_scm NONE			OPT_COLOR_SCHEMES
	"define-color-scheme"
	
delwind		NONE
	"delete-window"			!FEWNAMES
	'^K'
	'^X-0'
	
forceblank	REDO|UNDO
	"delete-blank-lines"		!FEWNAMES
	"force-blank-lines"		!FEWNAMES
	'^A-d'
	
del_emptylines	OPER|REDO|UNDO|GLOBOK|RANGE	!SMALLER
	"delete-empty-lines"		!FEWNAMES
	'^A-e'
	
frc_emptylines	OPER|REDO|UNDO|GLOBOK|RANGE	!SMALLER
	"force-empty-lines"		!FEWNAMES
	'^X-E'
	
delglobmode	NONE
	"delete-global-mode"		!FEWNAMES
	"setgno"
	"unsetg"
	"setno"
	"unset"
	
dellocmode	EXRCOK|EXTRA
	"delete-mode"			!FEWNAMES
	"setlno"
	"unsetl"
	
deltoeol	REDO|UNDO|MINIBUF
	"delete-to-eol"			!FEWNAMES
	'D'
	
desbind		NONE			OPT_REBIND
	"describe-bindings"
	"list-bindings"			!FEWNAMES
	"list-commands"			!FEWNAMES
	"show-bindings"
	"show-commands"
	
des_i_bind	NONE			OPT_REBIND
	"describe-insmode-bindings"
	"list-insmode-bindings"		!FEWNAMES
	"show-insmode-bindings"
	
des_c_bind	NONE			OPT_REBIND
	"describe-cmdmode-bindings"
	"list-cmdmode-bindings"		!FEWNAMES
	"show-cmdmode-bindings"
	
des_s_bind	NONE			OPT_REBIND
	"describe-selmode-bindings"
	"list-selmode-bindings"		!FEWNAMES
	"show-selmode-bindings"
	
desall_bind	NONE			OPT_REBIND
	"describe-all-keys"
	"list-all-keys"			!FEWNAMES
	"show-all-keys"
	
desall_i_bind	NONE			OPT_REBIND
	"describe-all-insmode-keys"
	"list-all-insmode-keys"		!FEWNAMES
	"show-all-insmode-keys"
	
desall_c_bind	NONE			OPT_REBIND
	"describe-all-cmdmode-keys"
	"list-all-cmdmode-keys"		!FEWNAMES
	"show-all-cmdmode-keys"
	
desall_s_bind	NONE			OPT_REBIND
	"describe-all-selmode-keys"
	"list-all-selmode-keys"		!FEWNAMES
	"show-all-selmode-keys"
	
des_keynames	NONE			OPT_REBIND
	"list-key-names"		!FEWNAMES
	"show-key-names"
	
descolors	NONE			OPT_SHOW_COLORS
	"list-colors"			!FEWNAMES
	"show-colors"
	
desmotions	NONE			OPT_REBIND
	"list-motions"			!FEWNAMES
	"describe-motions"
	"show-motions"
	
desglobals	NONE			OPT_REBIND
	"list-globals"			!FEWNAMES
	"describe-globals"
	"show-globals"
	
desopers	NONE			OPT_REBIND
	"list-operators"		!FEWNAMES
	"describe-operators"
	"show-operators"
	
desschemes	NONE			OPT_COLOR_SCHEMES
	"list-color-schemes"		!FEWNAMES
	"show-color-schemes"
	
desprint	NONE			OPT_SHOW_CTYPE
	"show-printable"
	
deswprint	NONE			OPT_SHOW_CTYPE&&OPT_MULTIBYTE
	"show-wide-printable"
	
dessubstr	NONE			OPT_REBIND
	"apropos"
	"list-commands-apropos-to"
	
desfunc		NONE			OPT_REBIND
	"describe-function"
	"show-function"
	
deskey		NONE			OPT_REBIND
	"describe-key"
	
des_i_key	NONE			OPT_REBIND
	"describe-insmode-key"
	
des_c_key	NONE			OPT_REBIND
	"describe-cmdmode-key"
	
des_s_key	NONE			OPT_REBIND
	"describe-selmode-key"
	
dotcmdplay	UNDO
	"repeat-last-cmd"		!FEWNAMES
	'.'
	
des_amp_funcs	NONE			OPT_EVAL
	"describe-&functions"
	"describe-user-functions"	!FEWNAMES
des_dlr_vars	NONE			OPT_EVAL
	"describe-$variables"
	"describe-state-variables"	!FEWNAMES
evaluate	NONE			OPT_EVAL
	"eval"
	"execute-string"		!FEWNAMES
	
ex		BANG|FILE1
	"ex"
	
execbuf		EXRCOK|EXTRA		!SMALLER
	"execute-buffer"		!FEWNAMES
	
execfile	EXRCOK|EXTRA		
	"execute-file"			!FEWNAMES
	"source"
	
exechypercmd	NONE			OPT_HYPERTEXT
	"execute-hypertext-command"	!FEWNAMES
	
showhypercmd	NONE			OPT_HYPERTEXT
	"show-hypertext-command"	!FEWNAMES
	
execkreg	REDO|UNDO|VIEWOK|USEREG
	"execute-register"
	'@'
	
execproc	REDO|EXRCOK|EXTRA	OPT_PROCEDURES
	"execute-procedure"		!FEWNAMES
	"run"
	
enlargewind	GOAL
	"grow-window"			!FEWNAMES
	'V'
	
esc_func	NONE
	"abort-command"			!FEWNAMES
	'^['
	
flow_control_enable	NONE		SYS_UNIX
	"flow-control-enable"
	
fcsrch		MOTION|MINIBUF
	"forward-char-scan"		!FEWNAMES
	'f'
	
fcsrch_to	MOTION|MINIBUF
	"forward-char-scan-up-to"	!FEWNAMES
	't'
	
filefind	BANG|FILE1|PLUS
	"e"
	"E"
	"edit-file"			!FEWNAMES
	"find-file"			!FEWNAMES
	'^X-e'
	
fileread	EXRCOK|FILE1		
	"e!"
	"replace-with-file"		!FEWNAMES
	
vl_filename	NAMEDF
	"change-file-name"		!FEWNAMES
	"f"
	"file"
	"filename"
	
filesave	BANG			!SMALLER
	"save-file"
	"save-file!"
	
filewrite	BANG
	"write-file"			!FEWNAMES
	"write-file!"			!FEWNAMES
	
vile_filter	REDO|UNDO		OPT_SHELL
	"|"
	"filter-buffer"			!FEWNAMES
	
finderr		NONE			OPT_FINDERR
	"find-next-error"		!FEWNAMES
	'^X-^X'
	
finderrbuf	NONE			OPT_FINDERR
	"find-next-error-buffer-name"
	"error-buffer"
	
firstbuffer	NONE
	"rewind"
	"rew!"
	
firstnonwhite	MOTION|MINIBUF
	"first-nonwhite"		!FEWNAMES
	'^'
	
fisearch	NONE			OPT_ISRCH
	"incremental-search"		!FEWNAMES
	'^X-S'
	
flipchar	REDO|UNDO|MINIBUF
	"flip-character"		!FEWNAMES
	'~'
	
forwdelchar	REDO|UNDO|MINIBUF
	"delete-next-character"		!FEWNAMES
	'x'
	'FN-d'				KEY_Delete
	
forwhpage	MOTION
	"forward-half-page"		!FEWNAMES
	"next-half-page"		!FEWNAMES
	"down-half-page"		!FEWNAMES
	'^D'
	
forwchar	MOTION|MINIBUF
	"forward-character"		!FEWNAMES
	"next-character"		!FEWNAMES
	
forwchar_to_eol	MOTION|MINIBUF
	"forward-character-to-eol"	!FEWNAMES
	"next-character-to-eol"		!FEWNAMES
	"right-arrow"
	' '
	'l'
	'FN-C'				KEY_Right
	
forwpage	MOTION
	"forward-page"			!FEWNAMES
	"next-page"			!FEWNAMES
	"down-page"			!FEWNAMES
	'^F'
	'FN-n'				KEY_Next
	
forw_row	GOAL|MOTION
	'^X-^D'
	"forward-row"			!FEWNAMES
	"next-row"			!FEWNAMES
	
forwline	GOAL|MOTION|FL
	"forward-line"			!FEWNAMES
	"next-line"			!FEWNAMES
	"down-line"			!FEWNAMES
	"down-arrow"			!FEWNAMES
	'j'
	'^J'
	'^N'
	'FN-B'				KEY_Down
	
forwbline	MOTION|FL
	"forward-line-at-bol"		!FEWNAMES
	"next-line-at-bol"		!FEWNAMES
	"down-line-at-bol"		!FEWNAMES
	'+'
	'^M'
	
forwword	MOTION|MINIBUF
	"forward-word"			!FEWNAMES
	"next-word"			!FEWNAMES
	'W'
	
forwviword	MOTION|MINIBUF
	"forward-punctuated-word"	!FEWNAMES
	"next-punctuated-word"		!FEWNAMES
	'w'
	
forwendw	MOTION|MINIBUF
	"forward-word-end"		!FEWNAMES
	"next-word-end"			!FEWNAMES
	'E'
	
forwviendw	MOTION|MINIBUF
	"forward-punctuated-word-end"	!FEWNAMES
	"next-punctuated-word-end"	!FEWNAMES
	'e'
	
forwhunt	ABSM|MOTION		!SMALLER
	"hunt-forward"			!FEWNAMES
	
forwsearch	ABSM|MOTION
	"search-forward"		!FEWNAMES
	'/'
	'FN-f'				KEY_Find
	
matchfence	ABSM|MOTION		OPT_CFENCE
	"goto-matching-fence"		!FEWNAMES
	'%'
	
matchfenceback	ABSM|MOTION		OPT_CFENCE
	"goto-matching-fence-behind"	!FEWNAMES
	'^X-%'
	
globals		NONE
	"oglobals"			VILE_NEVER

# the gotdotplus() function is mostly for internal use only, for the
# stuttered operator commands, but it corresponds to the real vi '_'
# command, so we give it a name, so it can be bound to if desired.
godotplus	MOTION|FL
	"whole-lines"
	

# this function is for internal use only, for ex commands
gomark		MOTION|FL|RANGE|ZERO

gotobop		ABSM|MOTION
	"previous-paragraph"		!FEWNAMES
	"back-paragraph"		!FEWNAMES
	"up-paragraph"			!FEWNAMES
	'{'
	
gotoeop		ABSM|MOTION
	"forward-paragraph"		!FEWNAMES
	"next-paragraph"		!FEWNAMES
	"down-paragraph"		!FEWNAMES
	'}'
	
gotobob		ABSM|MOTION		!SMALLER
	"beginning-of-file"		!FEWNAMES
	"goto-beginning-of-file"	!FEWNAMES
	'FN-H'				KEY_Home
	
gotoeob		ABSM|MOTION		!SMALLER
	"goto-end-of-file"		!FEWNAMES
	"end-of-file"			!FEWNAMES
	'FN-E'				KEY_End
	
gotobol		MOTION|MINIBUF
	"goto-bol"			!FEWNAMES
	"beginning-of-line"		!FEWNAMES
	"bol"				!FEWNAMES
	'0'
	
gotoeol		GOAL|MOTION|MINIBUF
	"goto-eol"			!FEWNAMES
	"end-of-line"			!FEWNAMES
	"eol"				!FEWNAMES
	'$'
	
gotobos		ABSM|MOTION|FL
	"goto-beginning-of-screen"	!FEWNAMES
	"beginning-of-screen"		!FEWNAMES
	'H'
	
gotomos		ABSM|MOTION|FL
	"goto-middle-of-screen"		!FEWNAMES
	"middle-of-screen"		!FEWNAMES
	'M'
	
gotoeos		ABSM|MOTION|FL
	"goto-end-of-screen"		!FEWNAMES
	"end-of-screen"			!FEWNAMES
	'L'
	
gotobosec	ABSM|MOTION
	"previous-section"		!FEWNAMES
	"back-section"			!FEWNAMES
	"up-section"			!FEWNAMES
	'['
	
gotoeosec	ABSM|MOTION
	"forward-section"		!FEWNAMES
	"next-section"			!FEWNAMES
	"down-section"			!FEWNAMES
	']'
	
gotobosent	ABSM|MOTION
	"previous-sentence"		!FEWNAMES
	"back-sentence"			!FEWNAMES
	"up-sentence"			!FEWNAMES
	'('
	
gotoeosent	ABSM|MOTION
	"forward-sentence"		!FEWNAMES
	"next-sentence"			!FEWNAMES
	"down-sentence"			!FEWNAMES
	')'
	
gototag		NONE			OPT_TAGS
	"ta"
	"tag"
	"find-tag"			!FEWNAMES
	'^]'
	
gotochr		ABSM|MOTION		!SMALLER
	"goto-char"
	'^X-G'
	
gotopct		ABSM|MOTION		!SMALLER
	"goto-percent"
	
gotocol		MOTION|MINIBUF
	"goto-column"			!FEWNAMES
	'|'
	
gotoline	ABSM|MOTION|FL|RANGE
	"goto-line"			!FEWNAMES
	'G'
	
# golinenmmark and goexactnmmark are special cases--
#	no ABSM even though they are absolute, since these are the commands
#	that use the last-dot-mark
golinenmmark	MOTION|FL
	"goto-named-mark"		!FEWNAMES
#  single quote -- can't use '''
	'\047'
	
goexactnmmark	MOTION
	"goto-named-mark-exact"		!FEWNAMES
	'`'
	
gorectnmmark	MOTION|VL_RECT
	"goto-named-mark-rectangular"	!FEWNAMES
	'\0134'
	
vl_help		NONE
	"h"
	"help"
	"list-help"
	"show-help"
	'^A-h'
	'^X-h'
	'FN-?'				KEY_Help
	'FN-m'				KEY_Menu
	
histbuff	NONE
	"historical-buffer"		!FEWNAMES
	"_"
	'_'
	
histbuff_to_current_window	NONE
	"historical-buffer-to-current-window"	!FEWNAMES
	'^X-_'
	
insert		REDO|UNDO
	"insert-chars"			!FEWNAMES
	'FN-i'				KEY_Insert
	'i'
	
insert_no_aindent	REDO|UNDO
	"insert-chars-no-autoindent"	!FEWNAMES
	'^A-i'
	
insertbol	REDO|UNDO
	"insert-chars-at-bol"	!FEWNAMES
	'I'
	
insfile		REDO|UNDO|GLOBOK|FROM|ZERO|NAMEDF
	"r"
	"insert-file"			!FEWNAMES
	"read-file"			!FEWNAMES
	'^R'
	
insspace	REDO|UNDO|MINIBUF	!SMALLER
	"insert-space"			!FEWNAMES
	
insstring	REDO|UNDO		!SMALLER
	"insert-string"
	
insnumber	REDO|UNDO		!SMALLER
	"insert-number"
	
joinlines	REDO|UNDO
	"join-lines"			!FEWNAMES
	'J'
	
for_buffers	NONE			!SMALLER
	"for-buffers"			!FEWNAMES
	"fb"
	'^X-x'
	
killbuffer	GOAL
	"delete-buffer"			!FEWNAMES
	"kill-buffer"			!FEWNAMES
	"ki"
	'^X-k'
	
showlength	DFLALL|FROM|TO|NOMOVE
	"buffer-length"			!FEWNAMES
	"="
	
lastnonwhite	MOTION|MINIBUF		!SMALLER
	"last-nonwhite"			!FEWNAMES
	
listbuffers	NONE
	"list-buffers"			!FEWNAMES
	"show-buffers"			!FEWNAMES
	'^A-*'
	
vl_set_args	FILES
	"set-buffers"			!FEWNAMES
	"args"
	
vl_set_args2	FILES
	"force-set-buffers"		!FEWNAMES
	"args!"
	
showhistory	NONE			OPT_HISTORY
	"show-history"
	
lineputafter	REDO|UNDO|GLOBOK|FROM|ZERO|OPTREG
	"put-as-lines-after"		!FEWNAMES
	"put"
	'^X-p'
	
lineputbefore	REDO|UNDO|GLOBOK|FROM|OPTREG
	"put-as-lines-before"		!FEWNAMES
	"Put"
	'^X-P'
	
rectputafter	REDO|UNDO|GLOBOK|FROM|ZERO|OPTREG
	"put-as-rectangle-after"	!FEWNAMES
	"rput"
	'^A-p'
	
rectputbefore	REDO|UNDO|GLOBOK|FROM|OPTREG
	"put-as-rectangle-before"	!FEWNAMES
	"rPut"
	'^A-P'
	
lineundo	NONE
	"undo-line-changes"		!FEWNAMES
	'U'
	
loadkreg	USEREG|EXTRA
	"load-register"
	
loadplugin	NONE			OPT_PLUGIN
	"load-plugin"
	
showkreg	NONE			OPT_SHOW_REGS
	"show-registers"
	"showregisters"			!FEWNAMES
	"list-registers"		!FEWNAMES
	
sysmap		EXRCOK|EXTRA		OPT_SHOW_MAPS
	"show-system-mapped-chars"
	
map		EXRCOK|EXTRA
	"map"
	"show-mapped-chars"
	
map_bang	EXRCOK|EXTRA
	"map!"
	"show-mapped!-chars"
	
gui_hide_menus	NONE			OPT_MENUS
	"hide-menus"
	
gui_remove_menus NONE			OPT_MENUS
	"remove-menus"
	
gui_show_menus	NONE			OPT_MENUS
	"show-menus"