lichray / nvi2 Goto Github PK
View Code? Open in Web Editor NEWA multibyte fork of the nvi editor for BSD
License: Other
A multibyte fork of the nvi editor for BSD
License: Other
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. The directory layout is as follows: LICENSE ....... Copyright, use and redistribution information. README ........ This file. catalog ....... Message catalogs; see catalog/README. cl ............ Vi interface to the curses(3) library. common ........ Code shared by ex and vi. ex ............ Ex source code. files ......... Template files. man ........... Ex/vi documentation. regex ......... Modified regex library with wide character support. vi ............ Vi source code. =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= o Nvi was written by Keith Bostic, and the last version is 1.79. After that, Sven Verdoolaege added the iconv support and the DB3 locking. 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: =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= o This software is several years old and is the product of many folks' work. This software was originally derived from software contributed to the University of California, Berkeley by Steve Kirkendall, the author of the vi clone elvis. Without his work, this work would have been far more difficult. IEEE POSIX 1003.2 style regular expression support is courtesy of Henry Spencer, for which I am *very* grateful. Elan Amir did the original 4BSD curses work that made it possible to support a full-screen editor using curses. George Neville-Neil added the Tcl interpreter, and the initial interpreter design was his. Sven Verdoolaege added the Perl interpreter. Rob Mayoff provided the original Cscope support. o Many, many people suggested enhancements, and provided bug reports and testing, far too many to individually thank. o From the original vi acknowledgements, by William Joy and Mark Horton: Bruce Englar encouraged the early development of this display editor. Peter Kessler helped bring sanity to version 2's command layout. Bill Joy wrote versions 1 and 2.0 through 2.7, and created the framework that users see in the present editor. Mark Horton added macros and other features and made the editor work on a large number of terminals and Unix systems. o And... The financial support of UUNET Communications Services is gratefully acknowledged.
Hi.
Sometimes, one may be forced to work with a read-only root filesystem, like the rescue mode mentioned in issue #63. However, I cannot find an easy way to tell nvi2 to not create temporary and recovery files. I've tried the followings:
nvi -F <file>
nvi -c 'set dir=""' <file>
but with no luck... A workaround is to use something like TMPDIR=<writable-directory> nvi <file>
. Is there a simpler/cleaner way to deal with this issue? Maybe options to disable temporary file or recovery file or both?
Regards,
Aaron
cmake -G "Ninja Multi-Config" -B build && ninja -C build
(as described in INSTALL.md
) fails with a ton of errors about recno_t
not being defined.
Just typedef'ing that to u_int32_t
, including db_185.h
, installing libdb1-compat
doesn't get me very far either. The most I could get from it (after manually modifying the generated *.ninja files) was to get a binary that crashes with
Berkeley DB: DB 1.85's recno bfname field is not supported.
[repeated ad-nauseam]
Segmentation fault
Compiling and running either nvi-1.79, nvi-1.81.6 (or my heavily modified version of the latter) works fine (after a couple of configure tweaks).
@lichray There was an earlier issue related to this: #69
However there are remaining problems. The first is that ${CMAKE_OSX_SYSROOT}/usr/include/db.h
expands to //usr/include/db.h
(notice double slash), when it is actually in /
and not inside Xcode app, and this breaks include:
[ 15%] Building C object CMakeFiles/nvi.dir/cl/cl_funcs.c.o
/opt/local/bin/gcc-mp-13 -DDB_H_ABS_PATH="<//usr/include/db.h>" -D_XOPEN_SOURCE_EXTENDED -D__REGEX_PRIVATE -I/opt/local/var/macports/build/_opt_PPCSnowLeopardPorts_editors_nvi2/nvi2/work/build -I/opt/local/include -I/opt/local/var/macports/build/_opt_PPCSnowLeopardPorts_editors_nvi2/nvi2/work/nvi2-2.2.1/regex -pipe -Os -DNDEBUG -isystem/opt/local/include/LegacySupport -I/opt/local/include -arch ppc -mmacosx-version-min=10.6 -Wno-string-compare -Wstack-protector -fstack-protector -Wstrict-aliasing -fstrict-aliasing -MD -MT CMakeFiles/nvi.dir/cl/cl_funcs.c.o -MF CMakeFiles/nvi.dir/cl/cl_funcs.c.o.d -o CMakeFiles/nvi.dir/cl/cl_funcs.c.o -c /opt/local/var/macports/build/_opt_PPCSnowLeopardPorts_editors_nvi2/nvi2/work/nvi2-2.2.1/cl/cl_funcs.c
In file included from /opt/local/var/macports/build/_opt_PPCSnowLeopardPorts_editors_nvi2/nvi2/work/nvi2-2.2.1/cl/cl_screen.c:28:
/opt/local/var/macports/build/_opt_PPCSnowLeopardPorts_editors_nvi2/nvi2/work/nvi2-2.2.1/cl/../common/common.h:15:23: error: missing terminating > character
15 | #include DB_H_ABS_PATH
| ^
<command-line>: error: empty filename in #include
Once that is fixed, it fails on:
[ 15%] Building C object CMakeFiles/nvi.dir/cl/cl_read.c.o
/opt/local/bin/gcc-mp-13 -DDB_H_ABS_PATH="</usr/include/db.h>" -D_XOPEN_SOURCE_EXTENDED -D__REGEX_PRIVATE -I/opt/local/var/macports/build/_opt_PPCSnowLeopardPorts_editors_nvi2/nvi2/work/build -I/opt/local/include -I/opt/local/var/macports/build/_opt_PPCSnowLeopardPorts_editors_nvi2/nvi2/work/nvi2-2.2.1/regex -pipe -Os -DNDEBUG -isystem/opt/local/include/LegacySupport -I/opt/local/include -arch ppc -mmacosx-version-min=10.6 -Wno-string-compare -Wstack-protector -fstack-protector -Wstrict-aliasing -fstrict-aliasing -MD -MT CMakeFiles/nvi.dir/cl/cl_read.c.o -MF CMakeFiles/nvi.dir/cl/cl_read.c.o.d -o CMakeFiles/nvi.dir/cl/cl_read.c.o -c /opt/local/var/macports/build/_opt_PPCSnowLeopardPorts_editors_nvi2/nvi2/work/nvi2-2.2.1/cl/cl_read.c
/opt/local/var/macports/build/_opt_PPCSnowLeopardPorts_editors_nvi2/nvi2/work/nvi2-2.2.1/cl/cl_term.c: In function 'cl_term_end':
/opt/local/var/macports/build/_opt_PPCSnowLeopardPorts_editors_nvi2/nvi2/work/nvi2-2.2.1/cl/cl_term.c:195:33: warning: implicit declaration of function 'SLIST_REMOVE_AFTER'; did you mean 'SLIST_REMOVE_HEAD'? [-Wimplicit-function-declaration]
195 | SLIST_REMOVE_AFTER(pre_qp, q);
| ^~~~~~~~~~~~~~~~~~
| SLIST_REMOVE_HEAD
/opt/local/var/macports/build/_opt_PPCSnowLeopardPorts_editors_nvi2/nvi2/work/nvi2-2.2.1/cl/cl_term.c:195:60: error: 'q' undeclared (first use in this function); did you mean 'qp'?
195 | SLIST_REMOVE_AFTER(pre_qp, q);
| ^
| qp
This is because sys/queue.h
is not guaranteed to have it on macOS.
Apple own code suggests this:
#ifndef SLIST_REMOVE_AFTER
#define SLIST_REMOVE_AFTER(elm, field) do { \
SLIST_NEXT(elm, field) = \
SLIST_NEXT(SLIST_NEXT(elm, field), field); \
} while (0)
#endif
https://opensource.apple.com/source/Libc/Libc-997.1.1/gen/FreeBSD/popen.c.auto.html
Since this is used in more than one file, it can be placed in common.h
instead. Then the build succeeds.
Riza Dindir emailed me a private bug report:
Here is the problem. I have a file "~/.nexrc", which sources "docs/dot.nexrc". The dot.nexrc on the other hand sources "docs/settings.rc" and "docs/macros.rc" files.
src/dot.nexrc has these lines
source ~/docs/settings.rc
source ~/docs/macros.rc
When I remove one of the lines above (or comment one line out), vi starts up and sets up macros. But if both lines are in there it dumps core.
I played around in a 13.1 poudriere jail and was able to reproduce via:
unsetenv EXINIT
cd
mkdir docs
echo 'source /dev/null' > docs/dot.nexrc
echo 'source /dev/null' >> docs/dot.nexrc
echo 'source ~/docs/dot.nexrc' > .nexrc
nvi docs
I built a nvi binary with -g and -O0 and tried valgrind:
zinc 192 @ valgrind --leak-check=yes --log-file=/tmp/valgrind.log /usr/bin/vi docs
zinc 193 @ cat /tmp/valgrind.log
==32399== Memcheck, a memory error detector
==32399== Copyright (C) 2002-2022, and GNU GPL'd, by Julian Seward et al.
==32399== Using Valgrind-3.19.0 and LibVEX; rerun with -h for copyright info
==32399== Command: /usr/bin/vi docs
==32399== Parent PID: 89767
==32399==
==32399== Invalid free() / delete / delete[] / realloc()
==32399== at 0x484E3BC: free (vg_replace_malloc.c:876)
==32399== by 0x13AD3F: ??? (in /usr/bin/nview)
==32399== by 0x145C66: ??? (in /usr/bin/nview)
==32399== by 0x130ED3: ??? (in /usr/bin/nview)
==32399== by 0x125693: ??? (in /usr/bin/nview)
==32399== by 0x12408C: ??? (in /usr/bin/nview)
==32399== by 0x4823007: ???
==32399== Address 0x5524af0 is 0 bytes inside a block of size 21 free'd
==32399== at 0x484E3BC: free (vg_replace_malloc.c:876)
==32399== by 0x13AD3F: ??? (in /usr/bin/nview)
==32399== by 0x145C66: ??? (in /usr/bin/nview)
==32399== by 0x130ED3: ??? (in /usr/bin/nview)
==32399== by 0x125693: ??? (in /usr/bin/nview)
==32399== by 0x12408C: ??? (in /usr/bin/nview)
==32399== by 0x4823007: ???
==32399== Block was alloc'd at
==32399== at 0x484C884: malloc (vg_replace_malloc.c:385)
==32399== by 0x13A12C: ??? (in /usr/bin/nview)
==32399== by 0x14614A: ??? (in /usr/bin/nview)
==32399== by 0x14B3BC: ??? (in /usr/bin/nview)
==32399== by 0x13C32B: ??? (in /usr/bin/nview)
==32399== by 0x145C66: ??? (in /usr/bin/nview)
==32399== by 0x130ED3: ??? (in /usr/bin/nview)
==32399== by 0x125693: ??? (in /usr/bin/nview)
==32399== by 0x12408C: ??? (in /usr/bin/nview)
==32399== by 0x4823007: ???
==32399==
==32399==
==32399== HEAP SUMMARY:
==32399== in use at exit: 180,118 bytes in 49 blocks
==32399== total heap usage: 493 allocs, 445 frees, 830,020 bytes allocated
==32399==
==32399== 100 bytes in 1 blocks are possibly lost in loss record 25 of 47
==32399== at 0x484C884: malloc (vg_replace_malloc.c:385)
==32399== by 0x13A190: ??? (in /usr/bin/nview)
==32399== by 0x14611D: ??? (in /usr/bin/nview)
==32399== by 0x14B3BC: ??? (in /usr/bin/nview)
==32399== by 0x146044: ??? (in /usr/bin/nview)
==32399== by 0x145C14: ??? (in /usr/bin/nview)
==32399== by 0x130ED3: ??? (in /usr/bin/nview)
==32399== by 0x125693: ??? (in /usr/bin/nview)
==32399== by 0x12408C: ??? (in /usr/bin/nview)
==32399== by 0x4823007: ???
==32399==
==32399== 148 bytes in 3 blocks are definitely lost in loss record 27 of 47
==32399== at 0x484C884: malloc (vg_replace_malloc.c:385)
==32399== by 0x13A190: ??? (in /usr/bin/nview)
==32399== by 0x14611D: ??? (in /usr/bin/nview)
==32399== by 0x14B3BC: ??? (in /usr/bin/nview)
==32399== by 0x13C32B: ??? (in /usr/bin/nview)
==32399== by 0x145C66: ??? (in /usr/bin/nview)
==32399== by 0x130ED3: ??? (in /usr/bin/nview)
==32399== by 0x125693: ??? (in /usr/bin/nview)
==32399== by 0x12408C: ??? (in /usr/bin/nview)
==32399== by 0x4823007: ???
==32399==
==32399== 817 bytes in 1 blocks are definitely lost in loss record 35 of 47
==32399== at 0x484C884: malloc (vg_replace_malloc.c:385)
==32399== by 0x4982122: cgetset (in /lib/libc.so.7)
==32399== by 0x48DC321: _nc_read_termcap_entry (in /lib/libncursesw.so.9)
==32399== by 0x48CCB57: _nc_read_entry2 (in /lib/libncursesw.so.9)
==32399== by 0x48C5912: _nc_setupterm (in /lib/libncursesw.so.9)
==32399== by 0x1255DE: ??? (in /usr/bin/nview)
==32399== by 0x12408C: ??? (in /usr/bin/nview)
==32399== by 0x4823007: ???
==32399==
==32399== LEAK SUMMARY:
==32399== definitely lost: 965 bytes in 4 blocks
==32399== indirectly lost: 0 bytes in 0 blocks
==32399== possibly lost: 100 bytes in 1 blocks
==32399== still reachable: 179,053 bytes in 44 blocks
==32399== suppressed: 0 bytes in 0 blocks
==32399== Reachable blocks (those to which a pointer was found) are not shown.
==32399== To see them, rerun with: --leak-check=full --show-leak-kinds=all
==32399==
==32399== For lists of detected and suppressed errors, rerun with: -s
==32399== ERROR SUMMARY: 4 errors from 4 contexts (suppressed: 0 from 0)
Some things I noticed along the way:
The first crash I attempted to debug involved two calls to vs_msgsave(), for the first call the msg queue was empty and the next pointer was null. But on the second call the next pointer had been clobbered with ascii. When I put a watchpoint on the memory location it was setenv() that was setting TERM from cl_vi_init() and somehow writing on top of the msg queue.
Currently text at :help
, :viusage
, and :exusage
is only in English. It would be nice to have these translatable as well, in order to have a cohesive l10n environment.
The truncation behavior for characters invalid in the current encoding is... unfriendly. This is a regression from 1.79, where non-ASCII bytes are visually escaped and don't cause weird behavior.
Display corruption after completion when numbering.
To reproduce:
This seems to affect all versions of nvi from at least 1.79.
Confirmed in 5fcdc13
Reported by: Walter Alejandro Iglesias [email protected]
Using the move forward with paragraphs separated by tags (those in para options) as in the example below doesn't move the cursor to the right place.
Example:
Open with vi(1) a file containing the following lines. Put your cursor at the '1' or in the empty line right above, and try using '}' (move to next paragraph) with different number prefixes (placing again the cursor at "1" each time).
1
2
3
4
5
6
There it works as expected. Now repeat the same on these lines (keeping paragraphs option untouched):
.PP
1
.PP
2
.PP
3
.PP
4
.PP
5
.PP
6
The prefixes in this case will move your cursor to "prefix + prefix - 1" paragraphs. This is:
and so on.
Finally, repeat the same steps on these lines:
.PP 1
.PP 2
.PP 3
.PP 4
.PP 5
.PP 6
.PP 7
.PP 8
Now the cursor will go "prefix *= 2"
It behaves in the same fashion moving to previous paragraphs.
I took a look to this file:
/usr/src/usr.bin/vi/vi/v_paragraph.c
But I wasn't able to understand what it does. Especially this part:
/*
* If we start in text, we want to switch states
* (2 * N - 1) times, in non-text, (2 * N) times.
*/
cnt = F_ISSET(vp, VC_C1SET) ? vp->count : 1;
cnt *= 2;
if (len == 0 || v_isempty(p, len))
pstate = P_INBLANK;
else {
--cnt;
pstate = P_INTEXT;
}
From email
last char first char behavior
multi-width multi-width nothing ins'ed
multi-width single-width 1 spc ins'ed
single-width multi-width 1 spc ins'ed
single-width single-width original
http://mail-index.netbsd.org/tech-userlevel/2017/11/06/msg010940.html
It's very unlikely we can find a language with
visually wide characters but still spaced with
single width spaces.
If you are editing a file with expandtab on and pipe a line with 8 leading blanks through the fmt shell command (e.g. !!fmt<return), fmt replaces the blanks with a tab which end up in the input buffer.
I think this is a bug; if you agree I'll work on a fix.
See title. Having homebrew support would really make macOS installation easier. It's available on Linux as well.
(Encountered under OS X.)
First case:
printf "\nfoo" > a && nvi a
d(
Second case:
printf "bar\n\n baz" > b && nvi +3 b
d(
Haven't had time to look into this yet; here's the offending call,
(lldb) up
frame #2: 0x000000010000b0b1 nvi`del(sp=0x0000000100805400, fm=0x00007fff5fbff2a8, tm=0x00007fff5fbff2b8, lmode=0) + 1969 at delete.c:100
97 GET_SPACE_RETW(sp, bp, blen, len);
98 if (fm->cno != 0)
99 MEMCPY(bp, p, fm->cno);
-> 100 MEMCPY(bp + fm->cno, p + (tm->cno + 1),
101 len - (tm->cno + 1));
102 if (db_set(sp, fm->lno,
103 bp, len - ((tm->cno - fm->cno) + 1)))
Frame variables (break set -f delete.c -l 100
):
(lldb) fr var
(SCR *) sp = 0x0000000100805400
(MARK *) fm = 0x00007fff5fbff288
(MARK *) tm = 0x00007fff5fbff298
(int) lmode = 0
(recno_t) lno = 2
(size_t) blen = 256
(size_t) len = 0
(size_t) nlen = 210453397506
(size_t) tlen = 0
(CHAR_T *) bp = 0x000000010020b1a0 L"\U0000fffd\U0000fffd\U0000fffd\U0000fffd\U0000fffd\U0000fffd\U0000fffd\U0000fffd": unmodified: line 1 (pid 28160)
(CHAR_T *) p = 0x000000010020b2f0 L"foo"
(int) eof = 1
(int) rval = 8410112
At the moment all split-screens will be back-grounded when resizing the terminal running nvi. Is this intentional?
This is a similar issue to #134, reproduced like so:
$ printf '%s\n' 'a|' . %p | nvi -e
This should print a newline. A potential fix:
--- a/ex/ex_append.c
+++ b/ex/ex_append.c
@@ -179,7 +179,9 @@ ex_aci(SCR *sp, EXCMD *cmdp, enum which cmd)
if (len != 0)
cmdp->save_cmd = t;
cmdp->save_cmdlen = len;
- }
+ } else if (*(cmdp->save_cmd - 1) == '|' &&
+ db_append(sp, 1, lno++, NULL, 0))
+ return (1);
if (F_ISSET(sp, SC_EX_GLOBAL)) {
if ((sp->lno = lno) == 0 && db_exist(sp, 1))
hello,
I've built successfully nvi2 with db 5.3 or db 18.1, both with db 1.85 compat mode enabled ("--enable-compat185
")
However, nvi2 runtime fails with this message from (lib)db:
Berkeley DB: DB 1.85's recno bfname field is not supported.
So nvi2 requires a "real" db 1.85 ? 1.85 compat mode is not supported ? or my build is a mess ?
Create a file consisting of one line, exactly as follows:
XXXXXXXXXXXXX YYYYYYYYYYYYYYYYY
(That's 13 X, followed by two tabs, followed by 17 Y.)
After it has been created, open it in nvi.
Type ':' or '/', then backspace. (I.e., put a character in the status bar.)
Type 'A' to append to the line, and insert a single space.
At this point, '^@' will show up to the right of the cursor.
esc :q!
On both my i386 and amd64 machines, this will crash about 1 in 20 times. Where it crashes varies; I've seen it crash immediately after 'A', immediately after 'esc', or immediately after ':q!enter'.
Tested on FreeBSD 12.1:
$ cd build
$ cmake . && make
$ echo foobar > file
$ ./nvi -e -c '/foo/p' file
-c option, 1: file: read lock was unavailable
file: 1 lines, 6 characters
Press Enter to continue:
$ cmake -DUSE_WIDECHAR=OFF . && make
$ ./nvi -e -c '/foo/p' file
foobar
Press Enter to continue:
Latest master fails to build on macOS.
Steps:
cmake .
make
Output:
Scanning dependencies of target regex
[ 1%] Building C object CMakeFiles/regex.dir/Users/emirsari/Projeler/GitHub/nvi2/regex/regcomp.c.o
[ 2%] Building C object CMakeFiles/regex.dir/Users/emirsari/Projeler/GitHub/nvi2/regex/regerror.c.o
[ 3%] Building C object CMakeFiles/regex.dir/Users/emirsari/Projeler/GitHub/nvi2/regex/regexec.c.o
[ 4%] Building C object CMakeFiles/regex.dir/Users/emirsari/Projeler/GitHub/nvi2/regex/regfree.c.o
[ 5%] Linking C static library libregex.a
[ 5%] Built target regex
[ 6%] Generating /Users/emirsari/Projeler/GitHub/nvi2/ex/version.h
[ 6%] Generating /Users/emirsari/Projeler/GitHub/nvi2/cl/extern.h
[ 7%] Generating /Users/emirsari/Projeler/GitHub/nvi2/common/extern.h
[ 8%] Generating /Users/emirsari/Projeler/GitHub/nvi2/ex/extern.h
[ 9%] Generating /Users/emirsari/Projeler/GitHub/nvi2/vi/extern.h
[ 10%] Generating /Users/emirsari/Projeler/GitHub/nvi2/common/options_def.h
[ 10%] Generating /Users/emirsari/Projeler/GitHub/nvi2/ex/ex_def.h
Scanning dependencies of target nvi
[ 11%] Building C object CMakeFiles/nvi.dir/Users/emirsari/Projeler/GitHub/nvi2/cl/cl_funcs.c.o
In file included from /Users/emirsari/Projeler/GitHub/nvi2/cl/cl_funcs.c:32:
/Users/emirsari/Projeler/GitHub/nvi2/cl/../common/common.h:12:10: fatal error: '/usr/include/db.h'
file not found
#include "/usr/include/db.h" /* Only include db1. */
^~~~~~~~~~~~~~~~~~~
1 error generated.
make[2]: *** [CMakeFiles/nvi.dir/Users/emirsari/Projeler/GitHub/nvi2/cl/cl_funcs.c.o] Error 1
make[1]: *** [CMakeFiles/nvi.dir/all] Error 2
make: *** [all] Error 2
berkeley-db 18.1.32_1 is already installed on my system.
We removed the cscope features downstream in OpenBSD because it was interfering with privilege dropping via pledge(2)
.
If I understand correctly, this code lets you view connections between vi and cscope instances, and lets you execute cscope commands from vi.
Is there interest in keeping this code? Do people use it? I suspect that it's very rarely used, and its interference with pledging suggests that it uses privileges and system resources otherwise unnecessary in vi. This is a potentially dangerous combination.
Of course, you can still use cscope with vi - you just won't have these extra features. As a daily (practically minute-ly) cscope user, removing this seems like the best option to me.
If people agree, I'm happy to cook up a diff.
I use this version of nvi exclusively. It is great. But there is a bug somewhere that causes occasional, seemingly random, segfaults on OpenBSD amd64. I haven’t noticed a pattern—it happens with 150000-line assembly files or ten-line emails.
Here is a backtrace from the latest coredump:
#0 seq_find (sp=0x1391dec5ad78, lastqp=0x0, e_input=0x1391e476d000,
c_input=0x0, ilen=2, stype=SEQ_INPUT, ispartialp=0x7f7ffffca41c)
at /usr/ports/pobj/nvi-2.1.1-iconv/nvi-2.1.1/common/seq.c:236
#1 0x0000138fdc114537 in v_event_get (sp=0x1391eae0f630, argp=0x7f7ffffca880,
timeout=600, flags=4)
at /usr/ports/pobj/nvi-2.1.1-iconv/nvi-2.1.1/common/key.c:646
#2 0x0000138fdc142c09 in v_txt (sp=0x1391eae0f630, vp=0x7f7ffffcaac0, tm=Variable "tm" is not available.
)
at /usr/ports/pobj/nvi-2.1.1-iconv/nvi-2.1.1/vi/v_txt.c:480
#3 0x0000138fdc13c867 in v_change (sp=0x1391eae0f630, vp=0x7f7ffffcaac0)
at /usr/ports/pobj/nvi-2.1.1-iconv/nvi-2.1.1/vi/v_itxt.c:314
#4 0x0000138fdc148531 in vi (spp=0x7f7ffffcacd8)
at /usr/ports/pobj/nvi-2.1.1-iconv/nvi-2.1.1/vi/vi.c:229
#5 0x0000138fdc11773a in editor (gp=0x1391e76b7000, argc=2,
argv=0x7f7ffffcaed0)
at /usr/ports/pobj/nvi-2.1.1-iconv/nvi-2.1.1/common/main.c:421
#6 0x0000138fdc10d4d1 in main (argc=2, argv=0x7f7ffffcaec8)
at /usr/ports/pobj/nvi-2.1.1-iconv/nvi-2.1.1/cl/cl_main.c:120
I’ve encountered an occasional crash on OpenBSD. To cause it, open nvi in a directory with lots of files in it, type “:r *”, and press enter. Whether it crashes at this point or not seems to depend on the specific filenames in the current directory and unfortunately I haven’t come up with a sensible test case yet.
(gdb) bt
#0 argv_sexp (sp=0x31e4239e630, bpp=0x7f7ffffcd418, blenp=0x7f7ffffcd428,
lenp=0x7f7ffffcd420)
at /usr/ports/pobj/nvi-2.1.3-iconv/nvi2-2.1.3/ex/ex_argv.c:763
#1 0x0000031c059287ac in argv_exp2 (sp=0x31e4239e630, excp=0x31eca36c0e0,
cmd=0x31eab2e8900, cmdlen=Variable "cmdlen" is not available.
)
at /usr/ports/pobj/nvi-2.1.3-iconv/nvi2-2.1.3/ex/ex_argv.c:194
#2 0x0000031c0592ff19 in ex_read (sp=0x31e4239e630, cmdp=0x31eca36c0e0)
at /usr/ports/pobj/nvi-2.1.3-iconv/nvi2-2.1.3/ex/ex_read.c:193
#3 0x0000031c059231ed in ex_cmd (sp=0x31e4239e630)
at /usr/ports/pobj/nvi-2.1.3-iconv/nvi2-2.1.3/ex/ex.c:1383
#4 0x0000031c0593b928 in v_ex (sp=0x31e4239e630, vp=0x7f7ffffcd800)
at /usr/ports/pobj/nvi-2.1.3-iconv/nvi2-2.1.3/vi/v_ex.c:405
#5 0x0000031c05949cf5 in vi (spp=0x7f7ffffcda28)
at /usr/ports/pobj/nvi-2.1.3-iconv/nvi2-2.1.3/vi/vi.c:230
#6 0x0000031c05917af3 in editor (gp=0x31eca36c000, argc=1,
argv=0x7f7ffffcdc30)
at /usr/ports/pobj/nvi-2.1.3-iconv/nvi2-2.1.3/common/main.c:421
#7 0x0000031c0590d4af in main (argc=1, argv=0x7f7ffffcdc28)
at /usr/ports/pobj/nvi-2.1.3-iconv/nvi2-2.1.3/cl/cl_main.c:119
Right now, :read! printf '\t'
will insert a tab regardless of the expandtab
setting, which might be inconsistent with the intent of 7d3f435, as !!printf '\t'
does respect expandtab
.
I'm considering doing something like this in OpenVi, but having the expandtab
behavior on filtering enabled with an option separate from plain expandtab
. I'm not even totally sure that these two filters should be the same re: expandtab
.
Regardless, as it is now, the nvi2 behavior might be a bit confusing.
I don't know if this is related to the previous issue. If I copy an invalid UTF-8 character to the clipboard (via xclip or similar), open nvi, enter insert mode, and paste the character, nvi prints "Invalid input. Truncated" (good) and then crashes (bad). 100% reproducible on OpenBSD amd64.
$ echo $LC_CTYPE
en_US.UTF-8
$ printf "\x80" | xclip
$ nvi # open nvi, enter insert mode, then paste
Abort trap (core dumped)
(gdb) bt
#0 0x000003897e6f698a in kill () at <stdin>:2
#1 0x000003897e75d161 in abort () at /usr/src/lib/libc/stdlib/abort.c:68
#2 0x000003877ad13e6f in v_event_err (sp=0x63f3, evp=0x7f7ffffcadf0)
at /usr/ports/pobj/nvi-2.1.1-iconv/nvi-2.1.1/common/key.c:811
#3 0x000003877ad42ce2 in v_txt (sp=0x38986fac630, vp=0x7f7ffffcb010, tm=Variable "tm" is not available.
)
at /usr/ports/pobj/nvi-2.1.1-iconv/nvi-2.1.1/vi/v_txt.c:527
#4 0x000003877ad3c2b6 in v_ii (sp=0x38986fac630, vp=0x7f7ffffcb010)
at /usr/ports/pobj/nvi-2.1.1-iconv/nvi-2.1.1/vi/v_itxt.c:163
#5 0x000003877ad48531 in vi (spp=0x7f7ffffcb228)
at /usr/ports/pobj/nvi-2.1.1-iconv/nvi-2.1.1/vi/vi.c:229
#6 0x000003877ad1773a in editor (gp=0x3897df29000, argc=1,
argv=0x7f7ffffcb420)
at /usr/ports/pobj/nvi-2.1.1-iconv/nvi-2.1.1/common/main.c:421
#7 0x000003877ad0d4d1 in main (argc=1, argv=0x7f7ffffcb418)
at /usr/ports/pobj/nvi-2.1.1-iconv/nvi-2.1.1/cl/cl_main.c:120
Hi,
Since "[6c26f11]" I can't compile.
cat /proc/version
Linux version 6.5.5-arch1-1 (linux@archlinux) (gcc (GCC) 13.2.1 20230801, GNU ld (GNU Binutils) 2.41.0) #1 SMP PREEMPT_DYNAMIC Sat, 23 Sep 2023 22:55:13 +0000
gcc --version
gcc (GCC) 13.2.1 20230801
cmake --version
cmake version 3.27.6
ldd --version
ldd (GNU libc) 2.38
Error at compilation:
...
...
[ 99%] Building C object CMakeFiles/nvi.dir/vi/vs_smap.c.o
[100%] Building C object CMakeFiles/nvi.dir/vi/vs_split.c.o
[100%] Linking C executable nvi
/usr/bin/ld: CMakeFiles/nvi.dir/common/log.c.o: in function apply_with': log.c:(.text+0x1259): undefined reference to
__builtin_is_aligned'
collect2: error: ld returned 1 exit status
make[2]: *** [CMakeFiles/nvi.dir/build.make:1978: nvi] Error 1
make[1]: *** [CMakeFiles/Makefile2:85: CMakeFiles/nvi.dir/all] Error 2
make: *** [Makefile:91: all] Error 2
Any clue ?
Thanks
From Xin Li:
It looks like the new nvi version don't accept in the context of
substitute. A minimal use case would be to replace all leading 8
spaces with tabs, what one would do on older version of nvi would be:
: 1,$ s/^ //g
Now, with nvi in FreeBSD 10.x+, entering won't yield the
character. This seems to be a regression from older nvi version.
Due to macOS System Integrity Protection (SIP), it's not possible to write to /usr/share/
. The only way to use catalogs on macOS is manually editing pathnames.h.in
file after cmake
, specifying _PATH_MSGCAT
manually as /usr/local/share/vi/catalog/
.
I glanced over the CMake file to make something out of it, but couldn't find a way to do it.
From email:
When a double-width character does not fit in a line, and cursor
moves to that char by 'l' command, cursor is put on the 1st column
of that char, instead of the 2nd column. Then, if cursor moves
further from a double-width char in that line to a single-width one,
it is located on the 2nd column of the double-width char, instead of
the single-width char it moving toward.
http://mail-index.netbsd.org/tech-userlevel/2017/11/06/msg010940.html
The patch also fixes an issue on iTerm2, where when cursor indicates a
multi-width character, putting it on the first column of the character,
does not focus on the entire the character, the right-most column instead.
Run nvi with no arguments.
:set fileencoding=iso-8859-1 (or some other known encoding)
:set fileencoding=test (or some other nonexistent encoding)
:q
Result:
nvi in free(): error: chunk is already free 0x128730e03700
(gdb) bt
#0 0x0000128735bd294a in kill () at <stdin>:2
#1 0x0000128735c33a4a in abort () at /usr/src/lib/libc/stdlib/abort.c:70
#2 0x0000128735c31024 in wrterror (msg=Variable "msg" is not available.
)
at /usr/src/lib/libc/stdlib/malloc.c:273
#3 0x0000128735c3231f in free (ptr=0x1287281120c0)
at /usr/src/lib/libc/stdlib/malloc.c:1252
#4 0x000012852621947b in opts_free (sp=0x128736076630)
at /usr/ports/pobj/nvi-2.1.2-iconv/nvi-2.1.2/common/options.c:1186
#5 0x000012852621e75f in screen_end (sp=0x128736076630)
at /usr/ports/pobj/nvi-2.1.2-iconv/nvi-2.1.2/common/screen.c:196
#6 0x0000128526248482 in vi (spp=0x7f7ffffd1be8)
at /usr/ports/pobj/nvi-2.1.2-iconv/nvi-2.1.2/vi/vi.c:255
#7 0x00001285262175fa in editor (gp=0x12872fdb4000, argc=1,
argv=0x7f7ffffd1dd8)
at /usr/ports/pobj/nvi-2.1.2-iconv/nvi-2.1.2/common/main.c:422
#8 0x000012852620d491 in main (argc=1, argv=0x7f7ffffd1dd0)
at /usr/ports/pobj/nvi-2.1.2-iconv/nvi-2.1.2/cl/cl_main.c:119
Open nvi with no arguments. Enter insert mode, and type the following:
O̼O̼O̼O̼O̼O̼O̼O̼O̼O̼O̼O̼O̼O̼O̼O̼O̼O̼O̼O̼O̼O̼O̼O̼O̼O̼O̼O̼O̼O̼O̼O̼O̼O̼O̼O̼O̼O̼O̼O̼a
Segmentation fault. Backtrace omitted, as it’s very very long, 15108 levels… (stack overflow?)
Seems related to combining characters. The number of characters necessary varies with the number of accents.
Hi
I am attempting the following on OS X 10.10.5 (Yosemite):
$ cd nvi2/build
$ cmake .
-- The C compiler identification is AppleClang 7.0.2.7000181
-- Check for working C compiler: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/cc
-- Check for working C compiler: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/cc -- works
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Detecting C compile features
-- Detecting C compile features - done
-- Looking for openpty
-- Looking for openpty - found
-- Looking for __b64_ntop
-- Looking for __b64_ntop - not found
-- Looking for __iconv
-- Looking for __iconv - not found
-- Performing Test ICONV_TRADITIONAL
-- Performing Test ICONV_TRADITIONAL - Success
-- Looking for include file libutil.h
-- Looking for include file libutil.h - not found
-- Looking for include file ncurses.h
-- Looking for include file ncurses.h - found
-- Looking for include file term.h
-- Looking for include file term.h - found
-- Configuring done
-- Generating done
-- Build files have been written to: /Users/larry/nvi2/build
So far, so good.
$ make
Scanning dependencies of target regex
[ 1%] Building C object CMakeFiles/regex.dir/Users/larry/nvi2/regex/regcomp.c.o
[ 2%] Building C object CMakeFiles/regex.dir/Users/larry/nvi2/regex/regerror.c.o
[ 3%] Building C object CMakeFiles/regex.dir/Users/larry/nvi2/regex/regexec.c.o
[ 4%] Building C object CMakeFiles/regex.dir/Users/larry/nvi2/regex/regfree.c.o
[ 5%] Linking C static library libregex.a
[ 5%] Built target regex
Scanning dependencies of target nvi
[ 6%] Building C object CMakeFiles/nvi.dir/Users/larry/nvi2/cl/cl_funcs.c.o
In file included from /Users/larry/nvi2/cl/cl_funcs.c:32:
In file included from /Users/larry/nvi2/cl/../common/common.h:81:
/Users/larry/nvi2/cl/../common/cut.h:35:2: error: unknown type name 'recno_t'
recno_t lno; /* 1-N: file line. */
^
In file included from /Users/larry/nvi2/cl/cl_funcs.c:32:
In file included from /Users/larry/nvi2/cl/../common/common.h:84:
/Users/larry/nvi2/cl/../common/mark.h:26:2: error: unknown type name 'recno_t'
recno_t lno; /* Line number. */
^
/Users/larry/nvi2/cl/../common/mark.h:32:2: error: unknown type name 'recno_t'
recno_t lno; /* Line number. */
^
In file included from /Users/larry/nvi2/cl/cl_funcs.c:32:
In file included from /Users/larry/nvi2/cl/../common/common.h:86:
/Users/larry/nvi2/cl/../common/../ex/ex.h:71:2: error: unknown type name 'recno_t'
recno_t start, stop; /* Start/stop of the range. */
^
/Users/larry/nvi2/cl/../common/../ex/ex.h:79:2: error: unknown type name 'recno_t'
recno_t if_lno; /* Associated line number. */
^
/Users/larry/nvi2/cl/../common/../ex/ex.h:96:2: error: unknown type name 'recno_t'
recno_t range_lno; /* @/global range: set line number. */
^
/Users/larry/nvi2/cl/../common/../ex/ex.h:115:2: error: unknown type name 'recno_t'
recno_t lineno; /* Command: line number. */
^
In file included from /Users/larry/nvi2/cl/cl_funcs.c:32:
In file included from /Users/larry/nvi2/cl/../common/common.h:86:
In file included from /Users/larry/nvi2/cl/../common/../ex/ex.h:233:
/Users/larry/nvi2/cl/../common/../ex/extern.h:44:32: warning: type specifier missing, defaults to 'int' [-Wimplicit-int]
int ex_g_insdel(SCR *, lnop_t, recno_t);
^
/Users/larry/nvi2/cl/../common/../ex/extern.h:72:46: error: unknown type name 'recno_t'
int ex_readfp(SCR *, char *, FILE *, MARK *, recno_t *, int);
^
/Users/larry/nvi2/cl/../common/../ex/extern.h:78:22: warning: type specifier missing, defaults to 'int' [-Wimplicit-int]
int sscr_exec(SCR *, recno_t);
^
/Users/larry/nvi2/cl/../common/../ex/extern.h:115:41: warning: type specifier missing, defaults to 'int' [-Wimplicit-int]
void ex_cinit(SCR *, EXCMD *, int, int, recno_t, recno_t, int);
^
/Users/larry/nvi2/cl/../common/../ex/extern.h:115:50: warning: type specifier missing, defaults to 'int' [-Wimplicit-int]
void ex_cinit(SCR *, EXCMD *, int, int, recno_t, recno_t, int);
^
/Users/larry/nvi2/cl/../common/../ex/extern.h:115:50: error: redefinition of parameter 'recno_t'
/Users/larry/nvi2/cl/../common/../ex/extern.h:115:41: note: previous declaration is here
void ex_cinit(SCR *, EXCMD *, int, int, recno_t, recno_t, int);
^
In file included from /Users/larry/nvi2/cl/cl_funcs.c:32:
In file included from /Users/larry/nvi2/cl/../common/common.h:87:
/Users/larry/nvi2/cl/../common/gs.h:28:2: error: unknown type name 'recno_t'
recno_t lno; /* 1-N: file cursor line. */
^
/Users/larry/nvi2/cl/../common/gs.h:92:2: error: unknown type name 'recno_t'
recno_t if_lno; /* Current associated line number. */
^
In file included from /Users/larry/nvi2/cl/cl_funcs.c:32:
In file included from /Users/larry/nvi2/cl/../common/common.h:88:
/Users/larry/nvi2/cl/../common/screen.h:62:2: error: unknown type name 'recno_t'
recno_t lno; /* 1-N: file line. */
^
/Users/larry/nvi2/cl/../common/screen.h:74:2: error: unknown type name 'recno_t'
recno_t rptlchange; /* Ex/vi: last L_CHANGED lno. */
^
/Users/larry/nvi2/cl/../common/screen.h:75:2: error: unknown type name 'recno_t'
recno_t rptlines[L_YANKED + 1];/* Ex/vi: lines changed by last op. */
^
/Users/larry/nvi2/cl/../common/screen.h:81:2: error: unknown type name 'recno_t'
recno_t defscroll; /* Vi: ^D, ^U scroll information. */
^
In file included from /Users/larry/nvi2/cl/cl_funcs.c:32:
In file included from /Users/larry/nvi2/cl/../common/common.h:89:
/Users/larry/nvi2/cl/../common/exf.h:24:2: error: unknown type name 'recno_t'
recno_t c_lno; /* Cached line number. */
^
/Users/larry/nvi2/cl/../common/exf.h:25:2: error: unknown type name 'recno_t'
recno_t c_nlines; /* Cached lines in the file. */
^
/Users/larry/nvi2/cl/../common/exf.h:30:2: error: unknown type name 'recno_t'
recno_t l_high; /* Log last + 1 record number. */
^
/Users/larry/nvi2/cl/../common/exf.h:31:2: error: unknown type name 'recno_t'
recno_t l_cur; /* Log current record number. */
^
In file included from /Users/larry/nvi2/cl/cl_funcs.c:32:
In file included from /Users/larry/nvi2/cl/../common/common.h:93:
/Users/larry/nvi2/cl/../common/extern.h:6:21: warning: type specifier missing, defaults to 'int' [-Wimplicit-int]
int cut_line(SCR *, recno_t, size_t, size_t, CB *);
^
/Users/larry/nvi2/cl/../common/extern.h:35:20: warning: type specifier missing, defaults to 'int' [-Wimplicit-int]
int db_eget(SCR *, recno_t, CHAR_T **, size_t *, int *);
^
/Users/larry/nvi2/cl/../common/extern.h:36:19: warning: type specifier missing, defaults to 'int' [-Wimplicit-int]
int db_get(SCR *, recno_t, u_int32_t, CHAR_T **, size_t *);
^
/Users/larry/nvi2/cl/../common/extern.h:37:22: warning: type specifier missing, defaults to 'int' [-Wimplicit-int]
int db_delete(SCR *, recno_t);
^
/Users/larry/nvi2/cl/../common/extern.h:38:27: warning: type specifier missing, defaults to 'int' [-Wimplicit-int]
int db_append(SCR *, int, recno_t, CHAR_T *, size_t);
^
/Users/larry/nvi2/cl/../common/extern.h:39:22: warning: type specifier missing, defaults to 'int' [-Wimplicit-int]
int db_insert(SCR *, recno_t, CHAR_T *, size_t);
^
/Users/larry/nvi2/cl/../common/extern.h:40:19: warning: type specifier missing, defaults to 'int' [-Wimplicit-int]
int db_set(SCR *, recno_t, CHAR_T *, size_t);
^
/Users/larry/nvi2/cl/../common/extern.h:41:21: warning: type specifier missing, defaults to 'int' [-Wimplicit-int]
int db_exist(SCR *, recno_t);
^
fatal error: too many errors emitted, stopping now [-ferror-limit=]
12 warnings and 20 errors generated.
make[2]: *** [CMakeFiles/nvi.dir/Users/larry/nvi2/cl/cl_funcs.c.o] Error 1
make[1]: *** [CMakeFiles/nvi.dir/all] Error 2
make: *** [all] Error 2
[exited with status 2.]
The errors referring to recno_t
would appear to suggest that cmake isn't picking up the db.h
file that's in /usr/local/include
, or maybe I've got that wrong?
Should nvi2 build on OS X?
Some abort()
in the code base are not critical (the program can safely processed) but may still be reached. Print an internal error message alone with filename:lineno without termination the program, so that the users have better editing experience, and we can still be aware of the errors.
One thing that has always stopped me from using vi is a lack of syntax highlighting.
Is it possible to implement syntax highlighting while keeping the code and philosophy clean?
It seems the Makefile generated by CMake does not have an install
target. I believe install
commands need to be added to CMakeLists.txt
for this to work.
I don't get this one, recno_t
seems ok, right?
$ fgrep -r recno_t /usr/include/
/usr/include/libdb/db_185.h:typedef u_int32_t recno_t;
/usr/include/libdb/db.h:typedef u_int32_t db_recno_t; /* Record number type. */
/usr/include/libdb/db.h: int (*db_append_recno) __P((DB *, DBT *, db_recno_t));
/usr/include/libdb/db.h: int (*get_append_recno) __P((DB *, int (**)(DB *, DBT *, db_recno_t)));
/usr/include/libdb/db.h: int (*set_append_recno) __P((DB *, int (*)(DB *, DBT *, db_recno_t)));
/usr/include/libdb/db.h: int (*count) __P((DBC *, db_recno_t *, u_int32_t));
/usr/include/libdb/db.h: int (*c_count) __P((DBC *, db_recno_t *, u_int32_t));
Reproduction steps on Centos 8, install required libraries:
$ sudo yum config-manager --set-enabled powertools
$ sudo yum install cmake ninja-build ncurses-devel libbsd libbsd-devel libdb-devel
$ git clone https://github.com/lichray/nvi2
$ cd nvi2
$ cmake -G "Ninja Multi-Config" -B build
-- The C compiler identification is GNU 8.5.0
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Check for working C compiler: /usr/bin/cc - skipped
-- Detecting C compile features
-- Detecting C compile features - done
-- Performing Test USE_FCOLOR_DIAGNOSTICS
-- Performing Test USE_FCOLOR_DIAGNOSTICS - Failed
-- Looking for openpty
-- Looking for openpty - not found
-- Looking for __b64_ntop
-- Looking for __b64_ntop - not found
-- Looking for asprintf
-- Looking for asprintf - not found
-- Looking for iconv
-- Looking for iconv - found
-- Performing Test ICONV_TRADITIONAL
-- Performing Test ICONV_TRADITIONAL - Success
-- Looking for getprogname
-- Looking for getprogname - not found
-- Looking for strlcpy
-- Looking for strlcpy - not found
-- Found PkgConfig: /usr/bin/pkg-config (found version "1.4.2")
-- Checking for module 'libbsd-overlay'
-- Found libbsd-overlay, version 0.12.2
-- Looking for dbopen
-- Looking for dbopen - not found
-- Looking for include file libutil.h
-- Looking for include file libutil.h - not found
-- Looking for include file ncurses.h
-- Looking for include file ncurses.h - found
-- Looking for include file ncursesw/ncurses.h
-- Looking for include file ncursesw/ncurses.h - found
-- Looking for include file pty.h
-- Looking for include file pty.h - found
-- Looking for include file term.h
-- Looking for include file term.h - found
-- Performing Test HAVE_DIRENT_D_NAMLEN
-- Performing Test HAVE_DIRENT_D_NAMLEN - Failed
-- Performing Test HAVE_STRUCT_STAT_ST_MTIMESPEC
-- Performing Test HAVE_STRUCT_STAT_ST_MTIMESPEC - Failed
-- Performing Test HAVE_STRUCT_STAT_ST_MTIM
-- Performing Test HAVE_STRUCT_STAT_ST_MTIM - Success
-- Configuring done (0.9s)
-- Generating done (0.0s)
-- Build files have been written to: /home/job/nvi2/build
Then building emits lots of errors:
$ ninja -C build -f build-Release.ninja
ninja: Entering directory `build'
[1/123] Building C object CMakeFiles/regex.dir/Release/regex/regfree.c.o
[2/123] Building C object CMakeFiles/regex.dir/Release/regex/regerror.c.o
[3/123] Building C object CMakeFiles/regex.dir/Release/regex/regexec.c.o
[4/123] Building C object CMakeFiles/regex.dir/Release/regex/regcomp.c.o
[5/123] Linking C static library Release/libregex.a
[6/123] Generating cl/extern.h
[7/123] Generating ex/version.h
[8/123] Generating ex/ex_def.h
[9/123] Generating common/options_def.h
[10/123] Generating common/extern.h
[11/123] Generating ex/extern.h
[12/123] Generating vi/extern.h
[13/123] Building C object CMakeFiles/nvi.dir/Release/ex/ex_cmd.c.o
FAILED: CMakeFiles/nvi.dir/Release/ex/ex_cmd.c.o
/usr/bin/cc -DLIBBSD_OVERLAY -D_GNU_SOURCE -D_XOPEN_SOURCE_EXTENDED -D__REGEX_PRIVATE -DCMAKE_INTDIR=\"Release\" -I/home/job/nvi2/build -I/home/job/nvi2/regex -O3 -DNDEBUG -isystem /usr/include/bsd -Wuninitialized -Wno-dangling-else -Wstack-protector -fstack-protector -Wstrict-aliasing -fstrict-aliasing -MD -MT CMakeFiles/nvi.dir/Release/ex/ex_cmd.c.o -MF CMakeFiles/nvi.dir/Release/ex/ex_cmd.c.o.d -o CMakeFiles/nvi.dir/Release/ex/ex_cmd.c.o -c /home/job/nvi2/ex/ex_cmd.c
In file included from /home/job/nvi2/ex/../common/common.h:83,
from /home/job/nvi2/ex/ex_cmd.c:20:
/home/job/nvi2/ex/../common/cut.h:33:2: error: unknown type name ‘recno_t’
recno_t lno; /* 1-N: file line. */
^~~~~~~
In file included from /home/job/nvi2/ex/../common/common.h:86,
from /home/job/nvi2/ex/ex_cmd.c:20:
/home/job/nvi2/ex/../common/mark.h:24:2: error: unknown type name ‘recno_t’
recno_t lno; /* Line number. */
^~~~~~~
/home/job/nvi2/ex/../common/mark.h:30:2: error: unknown type name ‘recno_t’
recno_t lno; /* Line number. */
^~~~~~~
In file included from /home/job/nvi2/ex/../common/common.h:88,
from /home/job/nvi2/ex/ex_cmd.c:20:
/home/job/nvi2/ex/../common/../ex/ex.h:69:2: error: unknown type name ‘recno_t’
recno_t start, stop; /* Start/stop of the range. */
^~~~~~~
/home/job/nvi2/ex/../common/../ex/ex.h:77:2: error: unknown type name ‘recno_t’
recno_t if_lno; /* Associated line number. */
^~~~~~~
/home/job/nvi2/ex/../common/../ex/ex.h:94:2: error: unknown type name ‘recno_t’
recno_t range_lno; /* @/global range: set line number. */
^~~~~~~
/home/job/nvi2/ex/../common/../ex/ex.h:113:2: error: unknown type name ‘recno_t’
recno_t lineno; /* Command: line number. */
^~~~~~~
In file included from /home/job/nvi2/ex/../common/../ex/ex.h:231,
from /home/job/nvi2/ex/../common/common.h:88,
from /home/job/nvi2/ex/ex_cmd.c:20:
/home/job/nvi2/ex/../common/../ex/extern.h:44:32: error: unknown type name ‘recno_t’; did you mean ‘regex_t’?
int ex_g_insdel(SCR *, lnop_t, recno_t);
^~~~~~~
regex_t
/home/job/nvi2/ex/../common/../ex/extern.h:72:46: error: unknown type name ‘recno_t’; did you mean ‘regex_t’?
int ex_readfp(SCR *, char *, FILE *, MARK *, recno_t *, int);
^~~~~~~
regex_t
/home/job/nvi2/ex/../common/../ex/extern.h:78:22: error: unknown type name ‘recno_t’; did you mean ‘regex_t’?
int sscr_exec(SCR *, recno_t);
^~~~~~~
regex_t
/home/job/nvi2/ex/../common/../ex/extern.h:116:41: error: unknown type name ‘recno_t’; did you mean ‘regex_t’?
void ex_cinit(SCR *, EXCMD *, int, int, recno_t, recno_t, int);
^~~~~~~
regex_t
/home/job/nvi2/ex/../common/../ex/extern.h:116:50: error: unknown type name ‘recno_t’; did you mean ‘regex_t’?
void ex_cinit(SCR *, EXCMD *, int, int, recno_t, recno_t, int);
^~~~~~~
regex_t
In file included from /home/job/nvi2/ex/../common/common.h:89,
from /home/job/nvi2/ex/ex_cmd.c:20:
/home/job/nvi2/ex/../common/gs.h:26:2: error: unknown type name ‘recno_t’
recno_t lno; /* 1-N: file cursor line. */
^~~~~~~
/home/job/nvi2/ex/../common/gs.h:90:2: error: unknown type name ‘recno_t’
recno_t if_lno; /* Current associated line number. */
^~~~~~~
In file included from /home/job/nvi2/ex/../common/common.h:90,
from /home/job/nvi2/ex/ex_cmd.c:20:
/home/job/nvi2/ex/../common/screen.h:60:2: error: unknown type name ‘recno_t’
recno_t lno; /* 1-N: file line. */
^~~~~~~
/home/job/nvi2/ex/../common/screen.h:72:2: error: unknown type name ‘recno_t’
recno_t rptlchange; /* Ex/vi: last L_CHANGED lno. */
^~~~~~~
/home/job/nvi2/ex/../common/screen.h:73:2: error: unknown type name ‘recno_t’
recno_t rptlines[L_YANKED + 1];/* Ex/vi: lines changed by last op. */
^~~~~~~
/home/job/nvi2/ex/../common/screen.h:79:2: error: unknown type name ‘recno_t’
recno_t defscroll; /* Vi: ^D, ^U scroll information. */
^~~~~~~
In file included from /home/job/nvi2/ex/../common/common.h:91,
from /home/job/nvi2/ex/ex_cmd.c:20:
/home/job/nvi2/ex/../common/exf.h:22:2: error: unknown type name ‘recno_t’
recno_t c_lno; /* Cached line number. */
^~~~~~~
/home/job/nvi2/ex/../common/exf.h:23:2: error: unknown type name ‘recno_t’
recno_t c_nlines; /* Cached lines in the file. */
^~~~~~~
/home/job/nvi2/ex/../common/exf.h:28:2: error: unknown type name ‘recno_t’
recno_t l_high; /* Log last + 1 record number. */
^~~~~~~
/home/job/nvi2/ex/../common/exf.h:29:2: error: unknown type name ‘recno_t’
recno_t l_cur; /* Log current record number. */
^~~~~~~
In file included from /home/job/nvi2/ex/../common/common.h:95,
from /home/job/nvi2/ex/ex_cmd.c:20:
/home/job/nvi2/ex/../common/extern.h:6:21: error: unknown type name ‘recno_t’; did you mean ‘regex_t’?
int cut_line(SCR *, recno_t, size_t, size_t, CB *);
^~~~~~~
regex_t
/home/job/nvi2/ex/../common/extern.h:35:20: error: unknown type name ‘recno_t’; did you mean ‘regex_t’?
int db_eget(SCR *, recno_t, CHAR_T **, size_t *, int *);
^~~~~~~
regex_t
/home/job/nvi2/ex/../common/extern.h:36:19: error: unknown type name ‘recno_t’; did you mean ‘regex_t’?
int db_get(SCR *, recno_t, u_int32_t, CHAR_T **, size_t *);
^~~~~~~
regex_t
/home/job/nvi2/ex/../common/extern.h:37:22: error: unknown type name ‘recno_t’; did you mean ‘regex_t’?
int db_delete(SCR *, recno_t);
^~~~~~~
regex_t
/home/job/nvi2/ex/../common/extern.h:38:27: error: unknown type name ‘recno_t’; did you mean ‘regex_t’?
int db_append(SCR *, int, recno_t, CHAR_T *, size_t);
^~~~~~~
regex_t
/home/job/nvi2/ex/../common/extern.h:39:22: error: unknown type name ‘recno_t’; did you mean ‘regex_t’?
int db_insert(SCR *, recno_t, CHAR_T *, size_t);
^~~~~~~
regex_t
/home/job/nvi2/ex/../common/extern.h:40:19: error: unknown type name ‘recno_t’; did you mean ‘regex_t’?
int db_set(SCR *, recno_t, CHAR_T *, size_t);
^~~~~~~
regex_t
/home/job/nvi2/ex/../common/extern.h:41:21: error: unknown type name ‘recno_t’; did you mean ‘regex_t’?
int db_exist(SCR *, recno_t);
^~~~~~~
regex_t
/home/job/nvi2/ex/../common/extern.h:42:20: error: unknown type name ‘recno_t’; did you mean ‘regex_t’?
int db_last(SCR *, recno_t *);
^~~~~~~
regex_t
/home/job/nvi2/ex/../common/extern.h:43:20: error: unknown type name ‘recno_t’; did you mean ‘regex_t’?
int db_rget(SCR *, recno_t, char **, size_t *);
^~~~~~~
regex_t
/home/job/nvi2/ex/../common/extern.h:44:20: error: unknown type name ‘recno_t’; did you mean ‘regex_t’?
int db_rset(SCR *, recno_t, char *, size_t);
^~~~~~~
regex_t
/home/job/nvi2/ex/../common/extern.h:45:20: error: unknown type name ‘recno_t’; did you mean ‘regex_t’?
void db_err(SCR *, recno_t);
^~~~~~~
regex_t
/home/job/nvi2/ex/../common/extern.h:49:21: error: unknown type name ‘recno_t’; did you mean ‘regex_t’?
int log_line(SCR *, recno_t, u_int);
^~~~~~~
regex_t
/home/job/nvi2/ex/../common/extern.h:60:32: error: unknown type name ‘recno_t’; did you mean ‘regex_t’?
int mark_insdel(SCR *, lnop_t, recno_t);
^~~~~~~
regex_t
/home/job/nvi2/ex/../common/extern.h:65:25: error: unknown type name ‘recno_t’; did you mean ‘regex_t’?
void msgq_status(SCR *, recno_t, u_int);
^~~~~~~
regex_t
/home/job/nvi2/ex/../common/extern.h:121:21: error: unknown type name ‘recno_t’; did you mean ‘regex_t’?
int nonblank(SCR *, recno_t, size_t *);
^~~~~~~
regex_t
[14/123] Building C object CMakeFiles/nvi.dir/Release/common/options_f.c.o
FAILED: CMakeFiles/nvi.dir/Release/common/options_f.c.o
/usr/bin/cc -DLIBBSD_OVERLAY -D_GNU_SOURCE -D_XOPEN_SOURCE_EXTENDED -D__REGEX_PRIVATE -DCMAKE_INTDIR=\"Release\" -I/home/job/nvi2/build -I/home/job/nvi2/regex -O3 -DNDEBUG -isystem /usr/include/bsd -Wuninitialized -Wno-dangling-else -Wstack-protector -fstack-protector -Wstrict-aliasing -fstrict-aliasing -MD -MT CMakeFiles/nvi.dir/Release/common/options_f.c.o -MF CMakeFiles/nvi.dir/Release/common/options_f.c.o.d -o CMakeFiles/nvi.dir/Release/common/options_f.c.o -c /home/job/nvi2/common/options_f.c
In file included from /home/job/nvi2/common/common.h:83,
from /home/job/nvi2/common/options_f.c:25:
/home/job/nvi2/common/cut.h:33:2: error: unknown type name ‘recno_t’
recno_t lno; /* 1-N: file line. */
^~~~~~~
In file included from /home/job/nvi2/common/common.h:86,
from /home/job/nvi2/common/options_f.c:25:
/home/job/nvi2/common/mark.h:24:2: error: unknown type name ‘recno_t’
recno_t lno; /* Line number. */
^~~~~~~
/home/job/nvi2/common/mark.h:30:2: error: unknown type name ‘recno_t’
recno_t lno; /* Line number. */
^~~~~~~
In file included from /home/job/nvi2/common/common.h:88,
from /home/job/nvi2/common/options_f.c:25:
/home/job/nvi2/common/../ex/ex.h:69:2: error: unknown type name ‘recno_t’
recno_t start, stop; /* Start/stop of the range. */
^~~~~~~
/home/job/nvi2/common/../ex/ex.h:77:2: error: unknown type name ‘recno_t’
recno_t if_lno; /* Associated line number. */
^~~~~~~
/home/job/nvi2/common/../ex/ex.h:94:2: error: unknown type name ‘recno_t’
recno_t range_lno; /* @/global range: set line number. */
^~~~~~~
/home/job/nvi2/common/../ex/ex.h:113:2: error: unknown type name ‘recno_t’
recno_t lineno; /* Command: line number. */
^~~~~~~
In file included from /home/job/nvi2/common/../ex/ex.h:231,
from /home/job/nvi2/common/common.h:88,
from /home/job/nvi2/common/options_f.c:25:
/home/job/nvi2/common/../ex/extern.h:44:32: error: unknown type name ‘recno_t’; did you mean ‘regex_t’?
int ex_g_insdel(SCR *, lnop_t, recno_t);
^~~~~~~
regex_t
/home/job/nvi2/common/../ex/extern.h:72:46: error: unknown type name ‘recno_t’; did you mean ‘regex_t’?
int ex_readfp(SCR *, char *, FILE *, MARK *, recno_t *, int);
^~~~~~~
regex_t
/home/job/nvi2/common/../ex/extern.h:78:22: error: unknown type name ‘recno_t’; did you mean ‘regex_t’?
int sscr_exec(SCR *, recno_t);
^~~~~~~
regex_t
/home/job/nvi2/common/../ex/extern.h:116:41: error: unknown type name ‘recno_t’; did you mean ‘regex_t’?
void ex_cinit(SCR *, EXCMD *, int, int, recno_t, recno_t, int);
^~~~~~~
regex_t
/home/job/nvi2/common/../ex/extern.h:116:50: error: unknown type name ‘recno_t’; did you mean ‘regex_t’?
void ex_cinit(SCR *, EXCMD *, int, int, recno_t, recno_t, int);
^~~~~~~
regex_t
In file included from /home/job/nvi2/common/common.h:89,
from /home/job/nvi2/common/options_f.c:25:
/home/job/nvi2/common/gs.h:26:2: error: unknown type name ‘recno_t’
recno_t lno; /* 1-N: file cursor line. */
^~~~~~~
/home/job/nvi2/common/gs.h:90:2: error: unknown type name ‘recno_t’
recno_t if_lno; /* Current associated line number. */
^~~~~~~
In file included from /home/job/nvi2/common/common.h:90,
from /home/job/nvi2/common/options_f.c:25:
/home/job/nvi2/common/screen.h:60:2: error: unknown type name ‘recno_t’
recno_t lno; /* 1-N: file line. */
...
ninja: build stopped: subcommand failed.
In current nvi, ‘w’ is not that useful in Japanese text, because it considers a long sentence written without spaces as a single word.
In the old nvi-m17n, ‘w’ moved along katakana/hiragana/kanji boundaries (so, for instance, “本日は晴天なり” would be treated as words “本日” “は” “晴天” “なり”). This is also how Xterm handles word selection; see Xterm’s charclass.c. I’ve been told by a Japanese nvi user that this is behavior he misses from nvi-m17n.
It would be useful to break along character class boundaries like this.
It would be great to provide a release tarball for use in package managers.
Here is the procedure for using Github's download service to provide a tarball, assuming 46c9daf... is the commit to base the release on:
$ git tag -a v2.1.2 46c9daf96fc9f14497868ea752195773e17e2751
$ git push --tags
$ git archive -o /tmp/nvi-2.1.2.tar.gz --prefix=nvi-2.1.2/ 46c9daf96fc9f14497868ea752195773e17e2751
(Uploading the tarball manually rather than using Github's auto-generated tarballs might seem strange. But the auto-generated tarballs are bad for two reasons: they have ambiguous filenames ("v.2.1.2.tar.gz" instead of "nvi-2.1.2.tar.gz"), and they don't have stable checksums--sometimes Github upgrades their underlying tar, gzip, or git installs in a way that changes the resulting tarballs, and when this happens packagers have to update all checksums of all files generated by Github. Better to provide a manual copy with a stable checksum.)
To reproduce:
:Vi^MQq^M
and Down-Arrow
will exhibit the problem.
This bug is present since at least nvi 1.79. I'll provide a patch adapted from nvi 1.81 and OpenVi shortly.
v2.2.0 was tagged over three years ago. Since then, there have been several bugfixes, including crash fixes. That seems like enough reason to justify a new release.
$ printf "1\n\n" > foo.txt
$ nvi -c2 foo.txt
/1
Doesn’t print “Search wrapped” for the /1
or n
if done from the last line in this example.
$ printf "1\na\n" > foo.txt
$ nvi -c2 foo.txt
/1
Same results for /1
and all subsequent n
done from the last line.
$ printf "1\nab\n" > foo.txt
$ nvi -c2 foo.txt
Same results for \1
and all subsequent n
done from the last character of the last line.
Dumb questions, but I am going in circles with internet searches.
I am trying a sample build on Debian systems, but I am unfamiliar with cmake.
I am used to normal makefiles, make clean install, etc.
Is there a recommended Linux platform to build on?
A list of build dependencies?
A list of cmake flags / settings that are needed?
The error logs are not very helpful either.
-- Configuring incomplete, errors occurred!
See also ".../nvi2-linux/CMakeFiles/CMakeOutput.log".
See also ".../nvi2-linux/CMakeFiles/CMakeError.log".
$ cmake --version
cmake version 3.10.2
I thought it might be worth a shot to ask.
The instructions in the wiki seem outdated as well, i.e. references to "cmake -i" which no longer seems to be supported.
Thanks for any advice you might have.
I would much rather use nvi over slow, bloated vim implementations.
But the versions shipping in most Linux distros are 1.81.6 circa 2007 at best.
Including several quirks and bugs, as you may know.
To reproduce:
$ cat file
enum
$ printf '%s\n' 'g/enum/i\' '\' '.' '%p' | nvi -e file
Expected output:
enum
Actual output:
enum
The correct behavior is observed in ed
and classic vi/ex (tested on OpenIndiana 2024.04).
nvi2 doesn't compile on musl-libc under alpine linux. There are several issue you run into when trying to compile it on a musl based system:
sys/queue.h
isn't in POSIX and thus not in musl (maybe ship that file manually?).bitstring.h
isn't in musl (is it even available in glibc?) I know that it is available in libbsd
but the include needs to be <bsd/bitstring.h>
then.<sys/types.h>
without including that header file.I don't know if you are interested in musl support (I hope you are) but the nvi version written by Keith Bostic did run and compile fine on musl.
Here is the buildlog for version 2.1.3
:
$ cmake -DCMAKE_INSTALL_PREFIX=/usr -DCMAKE_BUILD_TYPE=Release -DUSE_ICONV:Bool=False
-- The C compiler identification is GNU 5.2.0
-- Check for working C compiler: /usr/bin/cc
-- Check for working C compiler: /usr/bin/cc -- works
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Detecting C compile features
-- Detecting C compile features - done
-- Looking for openpty
-- Looking for openpty - found
-- Looking for __b64_ntop
-- Looking for __b64_ntop - not found
-- Looking for include file libutil.h
-- Looking for include file libutil.h - not found
-- Looking for include file ncurses.h
-- Looking for include file ncurses.h - found
-- Looking for include file term.h
-- Looking for include file term.h - found
-- Configuring done
-- Generating done
-- Build files have been written to: /home/soeren/code/aports/testing/nvi2/src/nvi2-2.1.3/build
$ make
Scanning dependencies of target regex
[ 1%] Building C object CMakeFiles/regex.dir/home/soeren/code/aports/testing/nvi2/src/nvi2-2.1.3/regex/regcomp.c.o
[ 2%] Building C object CMakeFiles/regex.dir/home/soeren/code/aports/testing/nvi2/src/nvi2-2.1.3/regex/regerror.c.o
[ 3%] Building C object CMakeFiles/regex.dir/home/soeren/code/aports/testing/nvi2/src/nvi2-2.1.3/regex/regexec.c.o
[ 4%] Building C object CMakeFiles/regex.dir/home/soeren/code/aports/testing/nvi2/src/nvi2-2.1.3/regex/regfree.c.o
[ 5%] Linking C static library libregex.a
[ 5%] Built target regex
[ 6%] Generating /home/soeren/code/aports/testing/nvi2/src/nvi2-2.1.3/ex/version.h
[ 6%] Generating /home/soeren/code/aports/testing/nvi2/src/nvi2-2.1.3/cl/extern.h
[ 7%] Generating /home/soeren/code/aports/testing/nvi2/src/nvi2-2.1.3/common/extern.h
[ 8%] Generating /home/soeren/code/aports/testing/nvi2/src/nvi2-2.1.3/ex/extern.h
[ 9%] Generating /home/soeren/code/aports/testing/nvi2/src/nvi2-2.1.3/vi/extern.h
[ 10%] Generating /home/soeren/code/aports/testing/nvi2/src/nvi2-2.1.3/common/options_def.h
[ 10%] Generating /home/soeren/code/aports/testing/nvi2/src/nvi2-2.1.3/ex/ex_def.h
Scanning dependencies of target nvi
[ 11%] Building C object CMakeFiles/nvi.dir/home/soeren/code/aports/testing/nvi2/src/nvi2-2.1.3/cl/cl_funcs.c.o
/home/soeren/code/aports/testing/nvi2/src/nvi2-2.1.3/cl/cl_funcs.c:17:23: fatal error: sys/queue.h: No such file or directory
compilation terminated.
CMakeFiles/nvi.dir/build.make:90: recipe for target 'CMakeFiles/nvi.dir/home/soeren/code/aports/testing/nvi2/src/nvi2-2.1.3/cl/cl_funcs.c.o' failed
make[2]: *** [CMakeFiles/nvi.dir/home/soeren/code/aports/testing/nvi2/src/nvi2-2.1.3/cl/cl_funcs.c.o] Error 1
CMakeFiles/Makefile2:67: recipe for target 'CMakeFiles/nvi.dir/all' failed
make[1]: *** [CMakeFiles/nvi.dir/all] Error 2
Makefile:83: recipe for target 'all' failed
make: *** [all] Error 2
Fixing issue 1. and 2. is of cause trivial, the question is if any other issue show up afterwards and if you are interested in general to provide support for musl.
I'm looking for:
The approximate matching may also be nice to have.
Hello,
I would like to volunteer to provide Turkish localisation for nvi2. Before I start working on it, I just wanted to check if it'd be acceptable/applicable.
Thanks!
Hello,
First, thank you for developing and maintaining the nvi2 software.
I'm a DragonFly BSD developer. Nvi2 is part of the base system as well as the initrd(7) rescue system in DragonFly BSD. The initrd rescue system is a collection of statically linked utilities. We've included nvi2 in it, but nvi2 cannot really work because it requires the terminfo library. See also the BUGS section of FreeBSD's rescue(8).
So I'm openning this issue to ask: whether or not it is possible to make nvi2 work without depending on terminfo/termcap library? If not, would it be hard to make it work, e.g., by embedding the dumb/ansi term information in the program? I can help work on the patch if you like. Thank you.
Regards,
Aaron
This took me a while to track down:
3.0.2: nvi2
builds normally
3.1.3: error,
-- Build files have been written to: /Users/marc/builds/nvi2.alt/build
Scanning dependencies of target headers
make[2]: *** No rule to make target `/Users/marc/builds/nvi2.alt/cl/extern.h', needed by `CMakeFiles/headers'. Stop.
make[1]: *** [CMakeFiles/headers.dir/all] Error 2
make: *** [all] Error 2
3.2.1: same error
Issue: In 3.1.3 and 3.2.1, extern.h
headers aren't generated before running the main build rules (headers
custom target).
nvi2 wouldn't install because of missing db.h -the workarounds from 2020 may be integrated but don't seem to work, if you have homebrew installed on ARM the paths are /opt/homebrew not /usr/local based.
I added db18 from pkgsrc and modified CMake link state to bring it in. This is the runtime outcome:
bash-3.2# ./work/nvi2-2.2.0/build/nvi
Berkeley DB: DB 1.85's recno bfname field is not supported.
ex/vi: Error: /tmp/vi.fAnOpr94Ir: Invalid argument
bash-3.2#
If I scroll onto a line containing only U+200B ZERO WIDTH SPACE, this happens:
Error: move: l(1 + 0) c(18446744073709551615 + 0)
Is this a bug in nvi, or in OpenBSD's locale support?
Hello. I like nvi2 and I like ability to make my own maps with shell integration. It allows me to doing cool stuff, like
" open current word in man
map ;m wb"zyw:^[C!man^V ^["zp^M
" fzf open files
map ;o :^[:!ls -R ^V| fzf >> %^M:edit^M^MIEdit ^[^M^W:bg^M
But I be needed to use unprintable special characters, if I want to use enter, or escape. So my maps become unreadable and unmaintainable. In big brother we can do something like that:
map ;t itest1<Enter>test2<Enter>test3<Esc>
I looked at source code and now I have working prototype of patch with this stuff. But before I will make boring work (documentation, new option and code cleaning), I want to ask you, do you see things like this in nvi? Will you accept my PR, or it to much for nvi?
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.