1
0
mirror of https://git.FreeBSD.org/src.git synced 2024-10-18 02:19:39 +00:00

nvi: import version 2.2.1

This commit is contained in:
Baptiste Daroussin 2023-09-26 09:08:15 +02:00
parent 8e6e122418
commit 16c0a3151e
15 changed files with 222 additions and 20 deletions

View File

@ -37,6 +37,7 @@ if (NOT APPLE)
endif()
add_compile_options($<$<CONFIG:Release>:-Wuninitialized>)
add_compile_options($<$<CONFIG:Release>:-Wno-dangling-else>)
add_compile_options(-Wno-string-compare)
add_compile_options(-Wstack-protector -fstack-protector)
add_compile_options(-Wstrict-aliasing -fstrict-aliasing)
@ -148,6 +149,9 @@ if(USE_WIDECHAR)
target_sources(regex PRIVATE ${REGEX_SRCS})
target_include_directories(regex PUBLIC regex)
target_compile_definitions(regex PUBLIC __REGEX_PRIVATE)
# The macro _XOPEN_SOURCE_EXTENDED is needed to get the waddnwstr()
# definition on at least FreeBSD and recent macOS.
target_compile_definitions(nvi PRIVATE _XOPEN_SOURCE_EXTENDED)
target_link_libraries(nvi PRIVATE regex)
else()
find_library(CURSES_LIBRARY NAMES ncurses curses HINTS /usr/lib)

47
INSTALL.md Normal file
View File

@ -0,0 +1,47 @@
# Install from source
For instructions to bring nvi2 as a part of your operating system's base system, see [Porting](https://github.com/lichray/nvi2/wiki/Porting) in the Wiki. This document is an overview of the build process that allows you to give nvi2 a try.
## Prerequisites
- CMake >= 3.17;
- Ninja build system;
- libiconv (for `USE_ICONV`);
- libncursesw (for `USE_WIDECHAR`);
Anything required by a minimal nvi, notably:
- Berkeley DB1 in libc;
- /var/tmp/vi.recover/ with mode 41777.
## Building
Nvi2 uses CMake build system generator. By specifying "Ninja Multi-Config" as the build system to generate, you can compile the project in both Debug and Release modes without re-running CMake. Under the project root directory, run
```sh
cmake -G "Ninja Multi-Config" -B build
```
Now `build` becomes your build directory to hold the artifacts. To build nvi2 in Debug mode, run
```sh
ninja -C build
```
Upon finishing, the nvi2 executable will be available as `build/Debug/nvi`. To launch it in `ex` mode, you can create a symlink
```sh
ln -s nvi build/Debug/ex
```
and run `./build/Debug/ex` rather than `./build/Debug/nvi`.
To build nvi2 in Release mode, use the following command instead:
```sh
ninja -C build -f build-Release.ninja
```
Upon finishing, you will be able to edit files with `./build/Release/nvi`.
To change configure-time options, such as disabling wide character support, use `ccmake build`.

26
README
View File

@ -1,4 +1,4 @@
This is version 2.2.0 (2020-08-01) of nex/nvi, a reimplementation of the ex/vi
This is version 2.2.1 (2023-09-25) of nex/nvi, a reimplementation of the ex/vi
text editors originally distributed as part of the Fourth Berkeley
Software Distribution (4BSD), by the University of California, Berkeley.
@ -24,6 +24,30 @@ o Nvi was written by Keith Bostic, and the last version is 1.79. After that,
Jun-ichiro itojun Hagino developed the file encoding detection
techniques in his nvi-m17n.
o In nvi2, Zhihao Yuan incorporated the multibyte encoding support onto DB1.
It was not possible without great support from Alexander Leidinger,
Peter Wemm, and the FreeBSD community.
Last but not least, money from Google Summer of Code.
o Since then,
Todd C. Miller and Craig Leres adopted and refined the NetBSD-style
expandtab option.
Yamamoto Takashi, Matija Skala, and Jessica Clarke ported the
software to macOS and Linux.
Anthony J. Bentley made heroic efforts to modernize the code base
and documentation, leveraging experience from OpenBSD to improve the
quality of the project.
...and many others, including Michael McConville, Marc Simpson,
Jeffrey H. Johnson, Bosco García, Anton Konyahin, Walter Alejandro
Iglesias, and those who tried hard to keep anonymous on GitHub :)
Their insights render the software usable, secure, and sustainable.
The following acknowledgments were written by Keith Bostic:
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=

View File

@ -31,6 +31,7 @@ static int v_event_grow(SCR *, int);
static int v_key_cmp(const void *, const void *);
static void v_keyval(SCR *, int, scr_keyval_t);
static void v_sync(SCR *, int);
static const char *alt_key_notation(int ch);
/*
* !!!
@ -252,6 +253,10 @@ v_key_name(SCR *sp, ARG_CHAR_T ach)
* followed by the character offset from the '@' character in the ASCII
* character set. Del (0x7f) is represented as '^' followed by '?'.
*
* If set O_ALTNOTATION, control characters less than 0x20 are
* represented in <C-char> notations. Carriage feed, escape, and
* delete are marked as <Enter>, <Esc>, and <Del>, respectively.
*
* XXX
* The following code depends on the current locale being identical to
* the ASCII map from 0x40 to 0x5f (since 0x1f + 0x40 == 0x5f). I'm
@ -264,9 +269,14 @@ v_key_name(SCR *sp, ARG_CHAR_T ach)
if (CAN_PRINT(sp, ach))
goto done;
nopr: if (iscntrl(ch) && (ch < 0x20 || ch == 0x7f)) {
sp->cname[0] = '^';
sp->cname[1] = ch == 0x7f ? '?' : '@' + ch;
len = 2;
if (O_ISSET(sp, O_ALTNOTATION)) {
const char *notation = alt_key_notation(ch);
len = strlcpy(sp->cname, notation, sizeof(sp->cname));
} else {
sp->cname[0] = '^';
sp->cname[1] = ch == 0x7f ? '?' : '@' + ch;
len = 2;
}
goto done;
}
#ifdef USE_WIDECHAR
@ -745,6 +755,85 @@ v_sync(SCR *sp, int flags)
rcv_sync(sp, flags);
}
/*
* alt_key_notation --
* Lookup for alternative notations of control characters.
*/
static const char*
alt_key_notation(int ch)
{
switch (ch) {
case 0x00:
return "<C-@>";
case 0x01:
return "<C-a>";
case 0x02:
return "<C-b>";
case 0x03:
return "<C-c>";
case 0x04:
return "<C-d>";
case 0x05:
return "<C-e>";
case 0x06:
return "<C-f>";
case 0x07:
return "<C-g>";
case 0x08:
return "<C-h>";
case 0x09:
return "<Tab>";
case 0x0A:
return "<NL>";
case 0x0B:
return "<C-k>";
case 0x0C:
return "<C-l>";
case 0x0D:
return "<Enter>";
case 0x0E:
return "<C-n>";
case 0x0F:
return "<C-o>";
case 0x10:
return "<C-p>";
case 0x11:
return "<C-q>";
case 0x12:
return "<C-r>";
case 0x13:
return "<C-s>";
case 0x14:
return "<C-t>";
case 0x15:
return "<C-u>";
case 0x16:
return "<C-v>";
case 0x17:
return "<C-w>";
case 0x18:
return "<C-x>";
case 0x19:
return "<C-y>";
case 0x1A:
return "<C-z>";
case 0x1B:
return "<Esc>";
case 0x1C:
return "<C-\\>";
case 0x1D:
return "<C-]>";
case 0x1E:
return "<C-^>";
case 0x1F:
return "<C-_>";
case 0x7f:
return "<Del>";
default:
__builtin_unreachable();
}
}
/*
* v_event_err --
* Unexpected event.

View File

@ -419,8 +419,7 @@ err: rval = 1;
* PUBLIC: void v_end(GS *);
*/
void
v_end(gp)
GS *gp;
v_end(GS *gp)
{
MSGS *mp;
SCR *sp;

View File

@ -46,6 +46,8 @@ static int opts_print(SCR *, OPTLIST const *);
* VI and EX Text Editors", 1990.
*/
OPTLIST const optlist[] = {
/* O_ALTNOTATION */
{L("altnotation"), f_print, OPT_0BOOL, 0},
/* O_ALTWERASE 4.4BSD */
{L("altwerase"), f_altwerase, OPT_0BOOL, 0},
/* O_AUTOINDENT 4BSD */

View File

@ -147,7 +147,7 @@ f_print(SCR *sp, OPTION *op, char *str, u_long *valp)
int offset = op - sp->opts;
/* Preset the value, needed for reinitialization of lookup table. */
if (offset == O_OCTAL) {
if (offset == O_OCTAL || offset == O_ALTNOTATION) {
if (*valp)
O_SET(sp, offset);
else

View File

@ -103,9 +103,14 @@ prev: if (sp->re == NULL) {
++p;
break;
}
if (plen > 1 && p[0] == '\\' && p[1] == delim) {
++p;
--plen;
if (plen > 1 && p[0] == '\\') {
if (p[1] == delim) {
++p;
--plen;
} else if ( p[1] == '\\') {
*t++ = *p++;
--plen;
}
}
}
if (epp != NULL)

13
ex/ex.c
View File

@ -154,6 +154,10 @@ ex(SCR **spp)
if (file_end(sp, NULL, F_ISSET(sp, SC_EXIT_FORCE)))
return (1);
*spp = screen_next(sp);
if (*spp) {
F_CLR(*spp, SC_SCR_VI);
F_SET(*spp, SC_SCR_EX);
}
return (screen_end(sp));
}
}
@ -1463,8 +1467,13 @@ usage: msgq(sp, M_ERR, "086|Usage: %s", ecp->cmd->usage);
LF_INIT(FL_ISSET(ecp->iflags, E_C_HASH | E_C_LIST | E_C_PRINT));
if (!LF_ISSET(E_C_HASH | E_C_LIST | E_C_PRINT | E_NOAUTO) &&
!F_ISSET(sp, SC_EX_GLOBAL) &&
O_ISSET(sp, O_AUTOPRINT) && F_ISSET(ecp, E_AUTOPRINT))
LF_INIT(E_C_PRINT);
O_ISSET(sp, O_AUTOPRINT) && F_ISSET(ecp, E_AUTOPRINT)) {
/* Honor the number option if autoprint is set. */
if (F_ISSET(ecp, E_OPTNUM))
LF_INIT(E_C_HASH);
else
LF_INIT(E_C_PRINT);
}
if (LF_ISSET(E_C_HASH | E_C_LIST | E_C_PRINT)) {
cur.lno = sp->lno;

View File

@ -764,11 +764,11 @@ err: if (ifp != NULL)
* shell that does that is broken.
*/
for (p = bp, len = 0, ch = EOF;
(ch = GETC(ifp)) != EOF; *p++ = ch, blen-=sizeof(CHAR_T), ++len)
(ch = GETC(ifp)) != EOF; *p++ = ch, blen -= sizeof(CHAR_T), ++len)
if (blen < 5) {
ADD_SPACE_GOTOW(sp, bp, *blenp, *blenp * 2);
ADD_SPACE_GOTO(sp, CHAR_T, bp, *blenp, *blenp * 2);
p = bp + len;
blen = *blenp - len;
blen = *blenp - len * sizeof(CHAR_T);
}
/* Delete the final newline, nul terminate the string. */

View File

@ -643,7 +643,9 @@ nextmatch: match[0].rm_so = 0;
goto lquit;
}
} else {
if (ex_print(sp, cmdp, &from, &to, 0) ||
const int flags =
O_ISSET(sp, O_NUMBER) ? E_C_HASH : 0;
if (ex_print(sp, cmdp, &from, &to, flags) ||
ex_scprint(sp, &from, &to))
goto lquit;
if (ex_txt(sp, tiq, 0, TXT_CR))
@ -1195,7 +1197,8 @@ re_tag_conv(SCR *sp, CHAR_T **ptrnp, size_t *plenp, int *replacedp)
for (; len > 0; --len) {
if (p[0] == '\\' && (p[1] == '/' || p[1] == '?')) {
++p;
--len;
if (len > 1)
--len;
} else if (STRCHR(L("^.[]$*"), p[0]))
*t++ = '\\';
*t++ = *p++;

View File

@ -2282,6 +2282,10 @@ and
.Nm vi
modes, unless otherwise specified.
.Bl -tag -width Ds
.It Cm altnotation Bq off
Display control characters less than 0x20 in <C-char> notations.
Carriage feed, escape, and delete are marked as <Enter>, <Esc>, and <Del>,
respectively.
.It Cm altwerase Bq off
.Nm vi
only.

View File

@ -96,6 +96,16 @@ typedef struct {
#define REG_LARGE 01000 /* force large representation */
#define REG_BACKR 02000 /* force use of backref code */
#ifdef USE_WIDECHAR
/*
* Avoid function name conflicts with the system regex functions.
* This is needed e.g. to build with AddressSanitizer.
*/
#define regcomp nvi_regcomp
#define regerror nvi_regerror
#define regexec nvi_regexec
#define regfree nvi_regfree
#endif
int regcomp(regex_t *, const RCHAR_T *, int);
size_t regerror(int, const regex_t *, char *, size_t);
int regexec(const regex_t *,

View File

@ -39,15 +39,20 @@
if (p[0] == '\014') { \
if (!--cnt) \
goto found; \
if (pstate == P_INTEXT && !--cnt) \
goto found; \
continue; \
} \
if (p[0] != '.' || len < 2) \
continue; \
for (lp = VIP(sp)->ps; *lp != '\0'; lp += 2) \
if (lp[0] == p[1] && \
(lp[1] == ' ' && len == 2 || lp[1] == p[2]) && \
!--cnt) \
goto found; \
(lp[1] == ' ' && len == 2 || lp[1] == p[2])) { \
if (!--cnt) \
goto found; \
if (pstate == P_INTEXT && !--cnt) \
goto found; \
} \
} while (0)
/*

View File

@ -29,5 +29,6 @@
int
v_redraw(SCR *sp, VICMD *vp)
{
F_SET(sp, SC_SCR_REFORMAT);
return (sp->gp->scr_refresh(sp, 1));
}