:find – where have you been all my life?

Over the last fourteen years of using vim, the rate at which I discover features and commands probably slowed a lot after the first six to eight years. As knowledge of awesomeness expanded, and business reasons limit my lurking in #vim irc, the the intake has been kinda slow. It didn’t really take long to learn enough vi to be highly editing effective, and some years of using vim all the fricken time, will probably teach anyone most of the important stuff.

Today, I discovered a new-old thing. Or had one of those “Where have you been all my life?” moments.

I often find myself copying a path; usually done via tmux’s copy/paste features, as I’m a keyboard whore, and not every terminal I rely on lets you use a mouse so readily for that. And then pasting it into a vim command to open a file, be it :e[dit], :tabe[dit], :sp[lit], or :vsp[lit], or even just to go do `vim somefile’.

Today, I was doing a fair bit of find commands to go look up a file, because when you have a solid state drive and some people like dozens of folders in nesting, sometimes that’s faster than remembering enough for tab completion.

Then I had a thought, “Hey, isn’t there a :find for looking up files? There’s gotta be a way to open those results in a buffer.” And of course there is!

Much to my disappointment, :find foo doesn’t really search many places. The default path on *nix is something like ., /usr/include, and the heck a trailing coma means (path=.,/usr/include,,). Which is great for something like :find sysexits.h but not so much for crawling a directory structure. But there’s a solution!

    :set path+=**
:find foo
-> suddenly qux/ham/spam/eggs/and/yippee/ki/yay/foo opens in the current buffer.

There’s a fair number of vim things that I’ve learned over the years, and don’t often need. On an occasion they teach me good things when I am smart enough to go look for them again.

Some random numbers

If I run a split screen on my 23” at a usable font size, I arrive at approx 119×52 characters of display.

Comparably, if I SSH into my machine with a font size easy on the peepers for the 11” screen, the results are a very respectable 109×32 characters display. Which is probably the Shelly app’s default, or a notch or two above.

Running iVim locally, with a default font that’s hard on the peepers unless using the external monitor: 149×47 characters.

Generally, I aim for about 80×35~45 characters as a terminal. Going around 160 is when I start consider :vsplit windows viable instead of relying on regular :split windows. Maybe I’m weird but I tend to like having a source file | header file combo in my vim session, when I’m afforded a big ass editing surface.

Thinking about these numbers, I kind of hope that Apple fixes the brokeness for keyboard/mouse support. I can use my keyboard, or I can use my mouse, but the moment that both are connected, iPadOS 13.2.3 decides that keyboard I/O should become like packet flow over a smoke signals modem. Which makes me less thrilled to dock my iPad until OS 13.2.4 or 13.3 happens, and cross my fingers that I won’t be stuck waiting until iPadOS 14.

I suppose that I could try pairing another Bluetooth mouse to see if for some reason, it simply hates my Logitech mouse, but I don’t imagine that I’d be that lucky with how much of a buggy mess iOS 13 has been.

Supplemental to last, a nifty thing as well—the per-app directory things in the Files app virtualizes the Documents directory associated with an app’s private-ish data container; or at least iVim makes it appears as such.

E.g. placing a file in iVim/Documents makes it appear in {container}/Documents when exploring it with netrw.

Likewise, while I can’t find any way to make Files express the concept of Unix hidden (.)files, the Files app does show a count that includes the .vim / .viminfo entries that come up when browsing through iVim itself.

This is kind of nice IMHO. If iOS just exports the thing somehow to a trusted Files app rather than making a separate directory outside the per-application containers, that makes the application directories in Files potentially a lot more useful for shuffling data around via the file manager. On the downside, I suppose, could mean Files would get a huge bullseye painted on its forehead for anyone wanting to find a way around some of the file system security.

By contrast, Android is a bit more liberal. The per-app area  (e.g. /data/…) is generally a total no-no to any other application, and apps are given explicit support for the “Shared” storage area (e.g. /sdcard) and a separate directory of their own located beneath it (e.g. /sdcard/Android/…)

Well, I might be a sorta happy camper. Looks like iVim is a decent port of Vi IMproved to iOS. From what I can tell, seems like a rather old (7.4) version, compiled as Big with external scripting and various mice/gui things disabled.

Limitations seem to be principally iOS imposed ones, such as Extreme Sudden App Kill Syndrome and overly restricted file permissions. So in effect, it’s about as good as you can hope for on anything more fruity than a Mac.

On a related note, I can also say that iPadOS doesn’t do key repeat. E.g. holding j doesn’t move the cursor in iVim, nor does it insert a bunch of j’s into Safari. But the repeat stuff works fine when combined with a modifier like doing and keystrokes, which makes me happy since that’s an action I use more freqently than holding the vi arrows (hjkl), etc.

Mating Vi IMproved with Visual C++, part I

Maybe it’s because it is an Integrated Development Environment, but Visual C++ seems to be a little lacking in its handling of external editors (at least in the express edition I have avail). It seems the best way to get MSVC to work with Vi IMproved for editing files, is to right click on a file in the solution explorer docklet, and click “Open with”. From there one can specify a program to open the file with and force it as the default editor; the down side is the bloody thing seems to reject the concept of command line arguments.

As such, I created a new win32 application in the IDE, and stripped the fundamental code down to the following

#define GVIM_EXE    _T("P:/Editors/Vim/vim-personal/gvim.exe")
#define GVIM_ARGS _T("--servername"), _T("MSVC"), _T("--remote-tab-silent")

int APIENTRY
_tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPTSTR lpCmdLine, int nCmdShow)
{
UNREFERENCED_PARAMETER(hPrevInstance);
UNREFERENCED_PARAMETER(hInstance);
UNREFERENCED_PARAMETER(nCmdShow);

_texecl(GVIM_EXE, _T("gvim"), GVIM_ARGS, lpCmdLine, NULL);

return 0;
}

Which means I get one instance of Vim running and double clicking files in the solution explorer, will open a new tab in the GVim window; gotta love an editor with a client-server feature hehe.

I have Michael Graz’s visual_studio.vim installed along with the required python for windows extensions. The plugin loads and appears to be exactly the *first* vim plugin that I can actually find a purpose for using! Except for one small problem…. the plugin can’t seem to chatter with the running instance of Visual C++ 2008 Express Edition!

Of course, I could likely jerry rig vim’s :make command to invoke vcbuild for me without much trouble.

Heh, and just for the heck of it, I wonder if a similar plugin could be written for other IDEs, like Code::Blocks, XCode, and KDevelop?

Building vim with support for Python and Perl on Windows

Previously:

install a suitable version of Visual Studio / Visual C++
install a suitable version of Python
install a suitable version of Perl
open a Visual Studio Command Prompt

I have VC Express 9.0, ActivePerl 5.10.0, and Python 2.6.2 installed from Python.org’s installer.

Check out the VIM source code, you can find directions here. I suggest using CVS or SVN to make the patching life easier. Precompiled binaries of CVS and SVN are available for Windows, and it is possible to build them yourself of course ;).

I use CVS and wish to keep the tree along side my regular vim:

> cd /d P:editorsvim
> cvs -z3 -d:pserver:anonymous@vim.cvs.sf.net:/cvsroot/vim checkout -Nd vim7-cvs-src vim7
> cd vim7-cvs-srcsrc

You should know read the Make_mvc.mak makefile to find the options you are interested in using. I’ll leave the viewing the file from the command line to a Windows users intelligence (hints: more, edit, notepad, wordpad, or gvim would be useful). We have to tell nmake.exe to use this file and our options, for asses who use Visual Studio all day but don’t remember nmake: we pass it VAR=value pairs.

> nmake /F Make_mvc.mak CPUNR=i686 FEATURES=HUGE GUI=yes OLE=yes CSCOPE=yes CTAGS=ctags POSTSCRIPT=yes PYTHON=P:DevelLanguagesPython2.6 PYTHON_VER=26 PERL=P:DevelLanguagesPerl PERL_VER=510

Obviously if you want same options, adjust the paths like a good little geek.

At least on my system, MSVCs compiler refuses to build the vimrun.exe, install.exe, uninstal.exe, and xxd/xxd.exe targets (and programs). As such, I build gvim and the gvimext.dll – the targets are in the makefile. if one wants to build a vim execuitable under a diffirent name, I suggest ‘nmake /e VIM=foo /f … OPTS=… foo.exe’ to create foo.exe (default is gvim).

As such we need a place to put vim so we can actually use it.


> MKDIR ....vim-personal
> FOR %F IN (*.dll *.exe) DO XCOPY /Y %F ....vim-personal
> XCOPY /Y P:DevelLanguagesPerlbinperl510.dll ....vim-personal
> XCOPY /I /E /Y ..runtime* ....vim-personal

and one can borrow the lost vimrun and diff files from a working install. If one also juggled the names so that vim-personal became vim72, one could also borrow the install.exe file most likely…

In doing all of this, I’ve written a batch script to use in automating the thing, which is not as good as my vimbuild shell script but still works lol. When I get some time I’ll make my script also update the spell files and what nots (hint: see spellreadme.txt)

Thanks Wiz… lol

After a few other commits, I’ve finally buckled down and made do_getopt() a simple helper, previously it did parsing for @ARGV via the Getopt::Long module, and twiddle %Options accordingly; now it takes an array ref and a hash to do the job. The wonderful thing? Now both tpsh [options] and the built in `set [options]` command work with half a line of duplicated code 🙂

In prepping my code for commit, I wanted to take one last look at do_getopt(), so I went for a quick jump over with the vi/vim :tag command. Wiz IM’d me, so he ended up getting the :ta command instead of vim haha! After alt+tabbing back to the editor, I tried something different just for the heck of it, :ta do_ and guess what!? Vims ex mode completion works on tags as well…. this is so going to spoil me lol. ex/vi lacked command completion, history, and editing; but vim added them. One of these days, I need a refresher on the improved tag commands, my muscle memory is pretty vi compatible until we get into tab completion, :split windows, and multiple tabs lol.

So thanks to Wiz, I’ve just found a lovely Vi IMproved feature that I never dreamed existed xD

Fun with vi, nvi, and vim

Some time ago, I installed the old version of vi ported as part of the heirloom project, noted as Traditional Vi. I tucked it into ~/code/C/src/old-vi and put a symlink named ‘ovi’ in my $PATH. During initial testing, I quickly concluded that the nvi builds on modern BSD (the systems vi) are considerably more extended then what the traditional vi offers. Things that I noticed most missing, were that ‘~/’ in file names was not expanded to the value of ${HOME}/ like in the shell (nvi / vim expand ~/), and the (crappy) split window support and a proper implementation of . and ^R (nvi makes ^R behave like .). A little playful testing also showed several settings missing (mostly expected), and no :exusage or :viusage commands. (Useful in nvi/nex on occasion, to see just what is available without consulting a reference or vim :help.) Two things I’ve learned tonight, old vi and nvi both support abbreviations, and control+^ is down right handy for switching buffers (vi, nvi, vim; probably every vi clone ever made). I thought abbrivations would have been an Elvis invention that made its way into vim, but I guess it was there since the 1980s, hehe. I also noted that ovi/nvi react differently to showmode (I prefer ovi’s).

Out of curosity, I fed into vi my nvi configuration file, since it appeared to be ignoring my ~/.exrc. Only had to remove the matchtime / ruler settings, and two of my mappings: gg and ZQ. gg being a vim’isms for 1G (go to first line in file) and ZQ being a very logical vim’ism for :q!^M much like vi used ZZ for 😡 .After that, vi accepted it without problem. The errors about the mappings interestingly said, “To dangerous to map that”, but nvi doesn’t give a darn. Fair enough for gg, but I’ve yet to figure the ZQ one yet.

Traditonal Vi

~
~
~
~
~
~
~
:set all
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
noexrc redraw noterse
flash remap timeout
hardtabs=8 report=5 ttytype=screen
noignorecase scroll=11 warn
nolisp sections=NHSHH HUnhsh window=23
nolist shell=/usr/local/bin/zsh wrapscan
magic shiftwidth=8 wrapmargin=0
mesg noshowmatch nowriteany
[Hit return to continue]

FreeBSDs build of nvi, when invoked as vi or nvi:


+=+=+=+=+=+=+=+
noaltwerase noextended matchtime=3 report=5 term="screen"
noautoindent filec="" mesg ruler noterse
autoprint flash nomodeline scroll=11 notildeop
noautowrite nogtagsmode noprint="" nosearchincr timeout
backup="" hardtabs=0 nonumber nosecure nottywerase
nobeautify noiclower nooctal shiftwidth=8 noverbose
cdpath=":" ignorecase open showmatch warn
cedit="" keytime=6 optimize showmode window=23
columns=80 noleftright path="" sidescroll=16 nowindowname
nocomment lines=24 print="" noslowopen wraplen=0
noedcompatible nolisp prompt nosourceany wrapmargin=0
escapetime=6 nolist noreadonly tabstop=8 wrapscan
noerrorbells lock noredraw taglength=0 nowriteany
noexrc magic remap tags="tags"
directory="/tmp/"
msgcat="/usr/share/vi/catalog/"
paragraphs="IPLPPPQPP LIpplpipbp"
recdir="/var/tmp/vi.recover"
sections="NHSHH HUnhsh"
shell="/usr/local/bin/zsh"
shellmeta="~{[*?$`'""
Press any key to continue [: to enter more ex commands]:

And doing :set all in Vi Improved (VIM) is so huge, it requires a pager! Hahaha.

Generally I will use vim whenever it is made available, in fact I usually compile my own binaries for it via shell script. But I have spent enough time using nvi, that dipping into ed, ex, vi / nvi don’t bother me. When I invoke vi, I expect a fairly traditional vi; when I invoke vim, I expect vim with vi compatiblity mode turned off (e.g. as if invoked as vim -U NONE -u NONE -N), or vim to behave ‘as expected’ when my own vimrc file is around.

My ~/.vimrc is over 1000 lines, but if you strip blanks and comments it is closer to 600. The only customizations that I actually depend on however, is mapping ‘;’ to ‘:’. Although certain vi users find that to be ludicrous, I use :ex commands much more frequently then I need to repeat the f, F, t, and T commands in the same direction. So being able to say ; when : is needed, is a massive life safer on my fingers, because it removes the need to hold shift. In fact, unless I want to go to a specific letter in a word, I usually employ :/ and 😕 to search for the word, rather then a linewise [count]f[character] motion, so the loss of a standard ‘;’ is fairly low for me.

I find vim much more comfortable then other vi’s, because I spend an imense amount of time in a text editor. I often [ab]use vims :sp[lit] command to have multiple edit-windows open, or to edit the 2 different parts of the same file without using marks or tags to jump about. The gq operator in vim is also a thing I love, because I can quickly reformat text without having to invoke an external program like fmt(1) all the time. Vi Improved also has better tag based commands. The ability to auto complete :ex commands and file/directory names helps me greatly; nvi’s cedit extension for editing :ex comand history sucks in comparason. The ability to :e . and use vim to peruse the current files in a directory is also nice when dealing with some peoples projects, although :!ls | less would work too, I’m not fond of the hit enter prompt at the end (nvi also ditches the colours in my ls output, while ovi retains them). The ability to use code folding and quickly configure settings based on file type is also quite nifty, since I often use zM to fold everything in large files, take a look and zO things that /look/ like it is what I am looking for. I almost never use ^O to make a single normal mode command from insert mode (vi/nvi don’t seem to support it), but it is nice when combined with other control+ commands in vims insert mode.

I’m also partial to vim’s undo style that repeatidly pressing ‘u’ in normal mode, repeatidly undo’s things while ^R redos what was undone. Traditional vi, nvi, and vim with u in the vi compatiblity options all have semi-incompatible usage paterns. The Vi Improved way uses u as noted above, when set to use a more Vi compatible way, vim uses u to undo and ^R to redo. Because vim has unlimited undo/redos, this means we would press u to undo the last change, then ^R to ‘redo’ the previous commands, and a following u will undo will undo the last redo (undo redo redo undo; rather then undo undo undo redo). Nvi allows using the ‘.’ as a synonym for ^R which is convenient since ‘.’ means repeat last change command. While traditional vi seems to lack multiple levels of undo/redo period and end of quote.

vim style multi undo:

dddddd      -- delete the next 3 lines as 3 separate changes (3dj would be a single change)
uuu -- undo last 3 changes (i.e. undeletes those 3 lines)
^R^R^R -- redo last 3 undos (i.e. re-delete those 3 lines)

nvi style multi undo:

dddddd      -- delete the next 3 lines as 3 separate changes (3dj would be a single change)
u -- undo last change (undelete last line)
^R^R -- redo last 2 undos (i.e. undelete the previous 2 lines)

vi style undo:

dddddd      -- delete the next 3 lines as 3 separate changes (3dj would be a single change)
u -- undo last change (undelete last line)
u -- redo last undo (redelete last line)

(i.e. vi style undo just toggles between undoing the last change and undoing the last undo, and ^R is subverted to allow multiple undos/redos in vim/nvi)

I’ve been using the vim style multi-undo for years, but have been wanting to adjust myself to the nvi style for ages. The only problem is, if I have to undo then do redo’s, I prefer using ‘.’ instead of ^R, haha! It seems to me, that technically nether vim using ^R for redo, nor nvi extending . for redo is purely vi compatible; but I personally feel extending . for the purpose, rather then clobbering ^R is a more logical solution. Although I can’t really think of a reason to use classic vi’s ^R instead of ^L on a modern terminal (read CRT or emualtor based terminal). The nvi style of multi-undo/redo also makes more sense to me, although most software users have been heavily conditioned by most programs to expect ^Z to undo the previous change up until the programs built in limit on undos.

Vim provides extensive mapping, syntax highlighting, build system integrations, and buffer options compared to traditional vi’s, but I don’t actually depend on it. Although most programmers I know, will cut your head clean off if you don’t give them syntax highlighting (lol), I don’t use Syntax highlighting…. I used to like using the astronaut and elflord colour schemes in vim; because I found them good for visually dumping syntax into my head. I.e. you can quickly tell what is what kind of syntactical element. But ever since I had to spend hours hashing out new PHP and SQL in a colourless remote terminal, I started to find the syntax highlighting to be distracting :. The only times I actually use colours in vim anymore, are for directory listings, with other peoples HTML, and in my .vimrc file; when coding, I use no syntax highlighting what so ever.

If you can look at the horse-shit filled tangles of (broken) HTML, (idiotic) SQL, (kindergartener like) PHP, and occasional JS that are so horribly intermixed and mutilated, that some past [SAS] webmasters dared to call it code, and come to reading it without syntax highlighting…. you can live without syntax highlighting anywhere!!!

getting bored

#!/bin/sh
#
# usage: vimbuild [tag]
#
# fetch indicated release tag of vim, compile, and test it.
# Requires the Concurrent Versions System (cvs) or Subversion (svn) client,
# and a suitable make tool.
#
# environment:
#
# $TMPDIR will be used as a staging area if defined, else /tmp is used.
#
# exit status: non zero on failure, zero on success.
#

PATH="/bin:/usr/bin:$PATH"

WORKDIR=${TMPDIR:-/tmp}
VTAG=${1:-vim}
CONFIGURE_ARGS="--enable-perlinterp --enable-pythoninterp --enable-tclinterp --enable-rubyinterp --enable-cscope --enable-fontset --enable-gui=gtk2 --disable-gtktest"

mkdir -p $WORKDIR || exit 1
cd $WORKDIR

# fetch latest vim
if [ -x "`which cvs`" ]; then
echo using cvs
cvs -z3 -d:pserver:anonymous@vim.cvs.sf.net:/cvsroot/vim checkout $VTAG
elif [ -x "`which svn`" ]; then
echo using svn
svn checkout https://vim.svn.sourceforge.net/svnroot/vim/branches/${VTAG}
else
echo 'error, could not find a cvs or svn binary in $PATH!'
exit 1
fi

cd $VTAG
./configure $CONFIGURE_ARGS

#
# set the make command
#
uname | grep -i linux > /dev/null
if [ $? -eq 0 ]; then
NCPU=$(expr `cat /proc/cpuinfo | grep processor | wc -l` * 4)
MAKE="make -j${NCPU}"
else
# assume GNU make is gmake, like on *BSD
if [ ! -x "`which gmake`" ]; then
echo "Warning, GNU make not found!"
echo "This will probably make a GTK gui build fail..."
MAKE=make
else
uname | grep -i bsd > /dev/null
if [ $? ]; then
# check number of cpu via BSD sysctl
NCPU=$(expr `sysctl hw.ncpu | awk '{ print $2 }'` * 4)
MAKE="gmake -j${NCPU}"
else
MAKE=gmake
fi
fi
fi

# now build and test it
$MAKE
if [ -x ./src/vim ]; then
./src/vim --version > /dev/null
if [ $? -eq 0 ]; then
echo "I think the Vi IMproved build was a success"
else
echo "I think the Vi IMproved build was a failure"
echo "Do you wish to test it manually?"
read REP
echo $REP | grep -i y && exec ./src/vim
# NO RETURN on yes
fi
fi

cat << EOF
run: `echo $MAKE | awk '{ print $1 }'` install
as root to finish installing vim
EOF

exit 0

I wonder, if I’ll ever bother to use it lol

Hey, it actually worked lol.

Uploaded it to my server, tweaked the configure args and bingo — freshly updated via

$ vimbuild vim7

$ su – root
# cd /tmp/vim7 && make install

Just for the heck of it, I’ve made the script adapt $CONFIGURE_ARGS based on what it finds installed, hehe.