nvi: import version 2.2.1

This commit is contained in:
Baptiste Daroussin 2023-09-27 18:01:58 +02:00
commit 0fcececbac
16 changed files with 298 additions and 106 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
contrib/nvi/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`.

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)

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 @@ addr_verify:
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

@ -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));
}

View File

@ -1,2 +1 @@
#define VI_VERSION "2.2.0 (2020-08-01)"
#define VI_VERSION "2.2.1 (2023-09-25)"

View File

@ -1,84 +1,85 @@
#define O_ALTWERASE 0
#define O_AUTOINDENT 1
#define O_AUTOPRINT 2
#define O_AUTOWRITE 3
#define O_BACKUP 4
#define O_BEAUTIFY 5
#define O_CDPATH 6
#define O_CEDIT 7
#define O_COLUMNS 8
#define O_COMBINED 9
#define O_COMMENT 10
#define O_TMPDIR 11
#define O_EDCOMPATIBLE 12
#define O_ERRORBELLS 13
#define O_ESCAPETIME 14
#define O_EXPANDTAB 15
#define O_EXRC 16
#define O_EXTENDED 17
#define O_FILEC 18
#define O_FILEENCODING 19
#define O_FLASH 20
#define O_HARDTABS 21
#define O_ICLOWER 22
#define O_IGNORECASE 23
#define O_INPUTENCODING 24
#define O_KEYTIME 25
#define O_LEFTRIGHT 26
#define O_LINES 27
#define O_LISP 28
#define O_LIST 29
#define O_LOCKFILES 30
#define O_MAGIC 31
#define O_MATCHCHARS 32
#define O_MATCHTIME 33
#define O_MESG 34
#define O_MODELINE 35
#define O_MSGCAT 36
#define O_NOPRINT 37
#define O_NUMBER 38
#define O_OCTAL 39
#define O_OPEN 40
#define O_OPTIMIZE 41
#define O_PARAGRAPHS 42
#define O_PATH 43
#define O_PRINT 44
#define O_PROMPT 45
#define O_READONLY 46
#define O_RECDIR 47
#define O_REDRAW 48
#define O_REMAP 49
#define O_REPORT 50
#define O_RULER 51
#define O_SCROLL 52
#define O_SEARCHINCR 53
#define O_SECTIONS 54
#define O_SECURE 55
#define O_SHELL 56
#define O_SHELLMETA 57
#define O_SHIFTWIDTH 58
#define O_SHOWMATCH 59
#define O_SHOWMODE 60
#define O_SIDESCROLL 61
#define O_SLOWOPEN 62
#define O_SOURCEANY 63
#define O_TABSTOP 64
#define O_TAGLENGTH 65
#define O_TAGS 66
#define O_TERM 67
#define O_TERSE 68
#define O_TILDEOP 69
#define O_TIMEOUT 70
#define O_TTYWERASE 71
#define O_VERBOSE 72
#define O_W1200 73
#define O_W300 74
#define O_W9600 75
#define O_WARN 76
#define O_WINDOW 77
#define O_WINDOWNAME 78
#define O_WRAPLEN 79
#define O_WRAPMARGIN 80
#define O_WRAPSCAN 81
#define O_WRITEANY 82
#define O_OPTIONCOUNT 83
#define O_ALTNOTATION 0
#define O_ALTWERASE 1
#define O_AUTOINDENT 2
#define O_AUTOPRINT 3
#define O_AUTOWRITE 4
#define O_BACKUP 5
#define O_BEAUTIFY 6
#define O_CDPATH 7
#define O_CEDIT 8
#define O_COLUMNS 9
#define O_COMBINED 10
#define O_COMMENT 11
#define O_TMPDIR 12
#define O_EDCOMPATIBLE 13
#define O_ERRORBELLS 14
#define O_ESCAPETIME 15
#define O_EXPANDTAB 16
#define O_EXRC 17
#define O_EXTENDED 18
#define O_FILEC 19
#define O_FILEENCODING 20
#define O_FLASH 21
#define O_HARDTABS 22
#define O_ICLOWER 23
#define O_IGNORECASE 24
#define O_INPUTENCODING 25
#define O_KEYTIME 26
#define O_LEFTRIGHT 27
#define O_LINES 28
#define O_LISP 29
#define O_LIST 30
#define O_LOCKFILES 31
#define O_MAGIC 32
#define O_MATCHCHARS 33
#define O_MATCHTIME 34
#define O_MESG 35
#define O_MODELINE 36
#define O_MSGCAT 37
#define O_NOPRINT 38
#define O_NUMBER 39
#define O_OCTAL 40
#define O_OPEN 41
#define O_OPTIMIZE 42
#define O_PARAGRAPHS 43
#define O_PATH 44
#define O_PRINT 45
#define O_PROMPT 46
#define O_READONLY 47
#define O_RECDIR 48
#define O_REDRAW 49
#define O_REMAP 50
#define O_REPORT 51
#define O_RULER 52
#define O_SCROLL 53
#define O_SEARCHINCR 54
#define O_SECTIONS 55
#define O_SECURE 56
#define O_SHELL 57
#define O_SHELLMETA 58
#define O_SHIFTWIDTH 59
#define O_SHOWMATCH 60
#define O_SHOWMODE 61
#define O_SIDESCROLL 62
#define O_SLOWOPEN 63
#define O_SOURCEANY 64
#define O_TABSTOP 65
#define O_TAGLENGTH 66
#define O_TAGS 67
#define O_TERM 68
#define O_TERSE 69
#define O_TILDEOP 70
#define O_TIMEOUT 71
#define O_TTYWERASE 72
#define O_VERBOSE 73
#define O_W1200 74
#define O_W300 75
#define O_W9600 76
#define O_WARN 77
#define O_WINDOW 78
#define O_WINDOWNAME 79
#define O_WRAPLEN 80
#define O_WRAPMARGIN 81
#define O_WRAPSCAN 82
#define O_WRITEANY 83
#define O_OPTIONCOUNT 84