OpenVi: Portable OpenBSD vi for Unix systems
github.com
github.com
The 1.8 branch of the Nvi editor, as well as the Nvi2 fork have mulitbyte support.
I could be mistaken but I believe both of these multibyte implementations descend from the late itojun's (http://www.itojun.org/itojun.html) Nvi-m17n project (archived at https://cgit.freebsd.org/ports/tree/editors/nvi-m17n/files). A paper was presented at USENIX99 (http://www.usenix.org/events/usenix99/full_papers/hagino/hag...) describing the work, which was actually developed as part of the KAME project.
One point of using BSD is (so the BSD people say) to have an operating system where everything comes from the same team - kernel and userland, unlike Linux where kernel and userland comes from dozens if not hundreds of different origins. But if you start to use arbitrary ports in BSD your OS is not much better than Linux in that regard
For a host I did primary development on, I’d install vim (visual mode and then syntax highlighting was so nice).
But we managed config centrally with idempotent scripts that handled the differences (like no getent on HP-UX). We did have to install ksh88 or a clone everywhere to get a stable consistent shell. GNU was flaky on so many platforms then.
Vi was always there for those WTF scenarios, less as a primary programming editor. And it is so nice on slow connections, where repainting the whole screen for every keystroke sucked.
It really annoyed me when Linuxes dropped the basic vi everywhere in favor of nano. I’d be fine with nano as a default for accessibility, but at least have some vi in my path.
Our standard images include it, but I always forget when I’m testing/debugging locally with Vagrant or a Docker image.
Vi is always a little weird. I don’t think any 2 people use it the same. Everyone has their own go-to set of commands. Pairing with grey beards influenced me so much.
I actually started with emacs in college, but real life with 1,000s of servers forced the change. I don’t have the muscle memory for it anymore and have no desire to go back.
Nowadays my local neovim config is almost VSCode. But I still like VSCode-ish in vi more than vi-ish in VSCode. I tried, but inevitably do something that VSCode’s vim plug-in doesn’t support.
I do use go more and more for complex stuff, but often am forced back to shell due to old kernels still out there which hurts my soul.
Don’t nearly all distros still have something (usually nvi or vim) in /usr/bin/vi out of the box?
For vim, `set compatible` or `set cp` is close, but still not traditional vi by any means.
A multibyte variant of the traditional vi is maintained at https://github.com/n-t-roff/heirloom-ex-vi/.
Nvi (now on version 1.8x) is also maintained - https://repo.or.cz/nvi.git
Nvi2 is yet another fork of Nvi, https://github.com/lichray/nvi2
Despite the very similar names, all of these editors have a variety of different features, and are structured very differently.
Nvi has a concept of a front-end and a back-end (which uses the BDB database). OpenVi uses the OpenBSD version of Berkeley DB which derives from 1.85. Nvi (1.8x) provides a minimal version of code also derived from that release intended from use with Nvi, and (IIRC) also provides support for using Db3/4/5. Similar situation for Nvi2.
Nvi 1.8 has been structured where a third library layer has been added, which doesn't exist in OpenBSD's vi or OpenVi. There is scripting support (Tcl, Perl, etc.) and GUI code in the other various forks ... all of these support various different options as well.
I should probably make a matrix of these, but you can get an idea by looking at the settable options implemented in each of the variants (as they historically include a comment to document from where the option originated):
OpenVi: https://github.com/johnsonjh/OpenVi/blob/22c2a7022e31d91e09e...
OpenBSD vi: https://github.com/openbsd/src/blob/master/usr.bin/vi/common...
Nvi2: https://github.com/lichray/nvi2/blob/5fcdc13656500a8c5b4c073...
Nvi1: https://repo.or.cz/nvi.git/blob/HEAD:/common/options.c#l52
Or maybe Arabic so the characters flow into each other
Improvements are in order, and should be made, but the mere inability to visually render multibyte characters is not always a showstopper.
Or once the Arabic exceeds 50% the alignment of the buffer flips? :)
Just a decade ago, it was almost a meme that the Emacs and Vi factions fought over which editor is better. I imagine that those that truly bought into the Vi ecosystem/fandom use it in preference to other available options.
The other 1% is Eclipse or VSCode ... and I have VSCode setup to use the embedding functionality of NeoVim.
It is. If it weren't, I would not use this editor.
The documentation has been updated to explain the rationale - see https://github.com/johnsonjh/OpenVi#why
In the 25 years since the "fork", OpenBSD vi has diverged significantly from Nvi1 (as Nvi2 has diverged from Nvi1 as well).
It has grown much smaller and more compact - one might argue more focused.
Much of the code has been simplified and many features removed, rather than added. Still, it has adopted features and taken some fixes back from Nvi1/Nvi2 versions and other variants, such as adopting support for expandtab from NetBSD's variant.
You can get a good idea of the history of this particular fork by reviewing the ChangeLog at https://raw.githubusercontent.com/johnsonjh/OpenVi/master/Ch... where the OpenBSD changes begin in 1997.
I've added details to the README to hopefully explain why it exists: https://github.com/johnsonjh/OpenVi#why
The OpenVi ChangeLog at https://raw.githubusercontent.com/johnsonjh/OpenVi/master/Ch... includes all the history going back to 1993's Nvi 0.93. Nvi 1.79 was released in 1996, which is the version OpenBSD's vi was derived from.
The ChangeLog entries are only a summary of the full commit messages - the complete details are in OpenBSD's CVS tree, and viewable a bit easier via GitHub (https://github.com/openbsd/src/commits/master/usr.bin/vi)
Changes to the (OpenVi bundled) OpenBSD regular expression engine are not included in the legacy ChangeLog, but you can see that development in the CVS tree or via GitHub as well (https://github.com/openbsd/src/commits/master/lib/libc/regex).
OpenVi also utilizes the OpenBSD version of Berkely DB (https://github.com/openbsd/src/commits/master/lib/libc/db).
Having learned vi across eight-ish different unices at once my muscle memory is very minimalist so I tend to use ex-vi preferentially, simply because everything else adds features I don't use that I can accidentally activate with a typo and break myself out of flow figuring out wtf just happened.
I can absolutely imagine that for somebody who tends to use OpenBSD on their own machines, being able to have the exact same editor elsewhere could be really quite handy for much the same reasons.
https://github.com/hughbarney/pEmacs
Stripped -Os build using link-time GC on Linux x86_64 glibc:
30 KB pe*
Compare to portable mg: 132 KB mg*
OpenVi is ... 278 KB bin/vi*
An even smaller vi implementation is Xvi. 56 KB src/xvi*
This would be an 'ersatz' vi since it is not built on top of a real ex-mode.Even tinier ersatz-vi clones exist (`levee`, `s`, `VIrus`) but these are not complete implementations.
The parent project on SourceForge hasn't had any activity for 15 years, nor a release in 17+ years, and contains various known bugs, all of which are fixed in Carsten Kunze's project.
Naturally I've accumulated a few local patches over the years so I'll have to figure out which of them are obsoleted by the improvements in that version and which of them I want to port first ;)
(thanks very much for sharing that this exists though, I shall be digging in when I have available tuits)
I suspect that once I untangle my somewhat hacky version of that the remainder of my patches will apply just fine but there'll still be at least a bit of mental effort involved.
Probably nothing that interesting - the malloc stuff was the big change and n-t-roff already did a much better job of it than I did.
But if there's anything in the remaining stack once I've backed it out that seems useful I'll be sure to PR it - even if it doesn't make it in to mainline it seems as good a way to memorialise the patch for other people's use as anything else.
(the repo is currently private because gritter had politely requested nobody make it work on windows and one of my patches worked around a cygwin bug - given the advent of WSL I doubt anybody would want that one anyway so I expect to let it be lost to time along with the half-arsed malloc code)
This may lead to a more secure editor for untrusted files, but it depends on how careful the other editors are. (I haven't examined them at that level.)
(I assume that people who are interested in features already know where to find (Neo)Vim.)
This basically is nvi, unless I'm very wrong.
The assumption has to be that OpenBSD added something to their version of nvi, which would "justify" porting it back to non-OpenBSD systems. What those feature are I don't know. It might just be a fun exercise adding the portability back.
The OpenBSD version forked at Nvi 1.79 around 1996-1997 and has been developed in the OpenBSD base system for 25 years now, and has diverged greatly from Nvi. Nvi2 has also diverged significantly from both "upstream" Nvi and OpenBSD vi.
The OpenBSD release has significantly trimmed features and maintains a different structure than the others as the philosophy completely different. There is no Perl / Tcl / pluggable scripting engine support or alternate graphical user interfaces or similar.
There are significant differences in the lower level code for signal handling, options, etc.
While the core functionality of these editors are all largely the same, and they all share common heritage from Bostic's Nvi, there are trivial and non-trivial differences between all of these editors that are almost too numerous to summarize.
Reviewing the ChangeLog (https://raw.githubusercontent.com/johnsonjh/OpenVi/master/Ch...) since Nvi 1.79 to present should give you an idea of what's going on with this particular version.
OpenVi is derived from OpenBSD vi, which derives from nvi version 1.79, released in 1996. There has been 25+ years of independent development as part of the OpenBSD base system and has diverged greatly in that time, with the development going in a different direction.
Nvi1, currently on version 1.8x, is maintained at https://repo.or.cz/nvi.git - I believe the latest version of this editor does have multibyte support, but this is not the OpenVi/OpenBSD version of the editor.
Nvi2 shares heritage as well but also, quite far removed from the original code, is actively maintained at https://github.com/lichray/nvi2 and also includes multibyte support.
(IIRC) the multibyte support in both Nvi1 and Nvi2 derives from nvi-m17n, developed as part of the KAME project by the late itojun - http://www.itojun.org/itojun.html ... the last update to nvi-m17n was about 3 years ago, and is available at https://cgit.freebsd.org/ports/tree/editors/nvi-m17n/files
Currently, optimizing for size using link-time garbage collection with GCC 11.2 on an x86_64 glibc Linux system gives a good idea of the changes over time and the different direction these editors have taken. OpenVi is also simplified in structure and does not have the three levels of abstraction of Nvi 1.8x - there is no library interface layer.
For OpenVi, the compiled binary is 280K, and for Nvi1 (nvi-1.81.6-45-g864873d3) the compiled binary is 528K (36K for vi, 528K for libvi).
OpenVi has a single configuration standard with no dependencies beyond curses.
Nvi1 has many options beyond trace/debug ("widechar" "gtk" "motif" "threads" "perl" "tcl" "db3/4" "internal-re") - so at least 255 different build variations are possible.
(I've not yet built Nvi2 myself on Linux so I can't provide an really fair comparison yet, but I will, and I'll summarize the data in an FAQ section of the README)
Nvi1 (https://repo.or.cz/nvi.git) looks like:
36K vi
24K vi-ipc
108K vi-motif
492K libvi.so.0.0.0
660K total
OpenVi does not - it's a single monolithic binary: 280K bin/vi
(Note that I was using the defaults here, I'm sure that it's possible to trim down Nvi 1.8x further, but I'm comparing the default compilations, optimized for size (GCC, -Os, -fdata-sections, -ffunction-sections, link-time GC enabled), but Nvi 1.8x is a much more complicated program, and has a different feature set, and different supported options.But, these are all different editors at this point. A lot happens in 25 years.
On features, most people would be fine with a vi clone with utf8 support.
Nv1 [nvi-1.81.6-45-g864873d3 (2022-02-21)]:
noaltwerase nocomment noignorecase nomodeline noreadonly noshowmode nottywerase
noautoindent noedcompatible keytime=6 msgcat="./" noredraw sidescroll=16 noverbose
autoprint escapetime=1 noleftright noprint="" remap noslowopen warn
noautowrite noerrorbells lines=24 nonumber report=5 nosourceany window=23
backup="" noexrc nolisp nooctal noruler tabstop=8 nowindowname
nobeautify noextended nolist open scroll=11 taglength=0 wraplen=0
cdpath=":" filec="" lock optimize nosearchincr tags="tags" wrapmargin=0
cedit="" flash magic path="" nosecure noterse wrapscan
columns=117 hardtabs=0 matchtime=7 print="" shiftwidth=8 notildeop nowriteany
nocombined noiclower mesg prompt noshowmatch timeout
directory="/tmp"
fileencoding="UTF-8"
inputencoding="UTF-8"
paragraphs="IPLPPPQPP LIpplpipbp"
recdir="/var/tmp/vi.recover"
sections="NHSHH HUnhsh"
shell="/bin/zsh"
shellmeta="~{[*?$`'"\"
term="screen-256color"
OpenVi [7.0.13-dev (OpenVi) 02/20/2022]: noaltwerase nocomment noiclower mesg report=5 taglength=0 nowindowname
noautoindent noedcompatible noignorecase noprint="" noruler tags="tags" wraplen=0
autoprint escapetime=2 noimctrl nonumber scroll=11 noterse wrapmargin=0
noautowrite noerrorbells keytime=6 nooctal nosearchincr notildeop wrapscan
backup="" noexpandtab noleftright open nosecure timeout nowriteany
nobeautify noexrc lines=23 path="" shiftwidth=8 nottywerase
nobserase noextended nolist print="" noshowmatch noverbose
cdpath=":" filec=" " lock prompt noshowmode novisibletab
cedit="" noflash magic noreadonly sidescroll=16 warn
columns=117 hardtabs=0 matchtime=7 remap tabstop=8 window=22
imkey="/?aioAIO"
paragraphs="IPLPPPQPP LIpplpipbpBlBdPpLpIt"
recdir="/var/tmp/vi.recover"
sections="NHSHH HUnhshShSs"
shell="/bin/zsh"
shellmeta="~{[*?$`'"\"
term="screen-256color"
OpenBSD vi [7.0-current]: noaltwerase escapetime=1 noleftright path="" noshowmatch warn
noautoindent noerrorbells lines=36 print="" noshowmode window=35
autoprint noexpandtab nolist prompt sidescroll=16 nowindowname
noautowrite noexrc lock noreadonly tabstop=8 wraplen=0
backup="" noextended magic remap taglength=0 wrapmargin=0
nobeautify filec=" " matchtime=7 report=5 tags="tags" wrapscan
cdpath=":" noflash mesg noruler noterse nowriteany
cedit="" hardtabs=0 noprint="" scroll=17 notildeop
columns=108 noiclower nonumber nosearchincr timeout
nocomment noignorecase nooctal nosecure nottywerase
noedcompatible keytime=6 open shiftwidth=8 noverbose
paragraphs="IPLPPPQPP LIpplpipbpBlBdPpLpIt"
recdir="/tmp/vi.recover"
sections="NHSHH HUnhshShSs"
shell="/usr/local/bin/zsh"
shellmeta="~{[\*?$`'"\"
term="screen-256color"
Traditional vi [n-t-roff Heirloom vi (01/14/2017)]: noautoindent nomodelines noshowmode
autoprint nonumber noslowopen
noautowrite open nosourceany
nobeautify nooptimize tabstop=8
directory=/var/tmp paragraphs=IPLPPPQPP LIpplpipbp taglength=0
noedcompatible prompt tags=tags /usr/lib/tags
noerrorbells noreadonly term=screen-256color
noexrc redraw noterse
flash remap timeout
hardtabs=8 report=5 ttytype=screen-256color
noignorecase scroll=17 warn
nolisp sections=NHSHH HUnhsh window=35
nolist shell=/usr/bin/zsh wrapscan
magic shiftwidth=8 wrapmargin=0
mesg noshowmatch nowriteanyhttps://www.openbsd.org/papers/eurobsdcon2016-utf8.pdf and http://www.usenix.org/events/usenix99/full_papers/hagino/hag...
Nvi2 (and Nvi1) are excellent editors, but I wouldn't want to copy the Nvi2 implementation directly. This has been talked about elsewhere*
* https://misc.openbsd.narkive.com/9NHoQv8L/nvi-and-unicode#po...
Still it's unclear why.
OpenBSD's vi (and OpenVi) differ distinctly from both Nvi (https://repo.or.cz/nvi.git) and Nvi2 (https://github.com/lichray/nvi2) in terms of features and support, having diverged 25 years previously, where the OpenBSD/OpenVi branch has embraced minimalism and simplicity.
For a quick and non-scientific comparison, C source lines of code (as counted by tokei) for the various distributions of the Nvi-derived editors:
Nvi - 62,315 SLOC
Nvi2 - 32,408 SLOC
OpenVi - 40,065 SLOC
And looking ONLY at the core editor functionality and bundled regular expression engines:
Nvi - 35,874 SLOC
Nvi2 - 32,019 SLOC
OpenVi - 31,678 SLOC
(In school, early 90's, there was a large vile following on VMS, which is where I mostly used it. I don't recall why it was preferred to Vim on VMS, however. Perhaps we didn't have Vim easily available or installed. But I digress.)
I have searched for this some time ago but all 'hints' guided me towards vim(1) :set nowrap option.
I checked now the vi(1) [nvi] man page on FreeBSD and it indeed has leftright option.
% man vi | grep -A 1 leftright
leftright [off]
vi only. Do left-right scrolling.
But I never interpreted that as 'nowrap' equivalent.Thanks again and have a great life.