I have been using Emacs since 2001, any only really learned Vim in
2007. Of course, I did quick admin edit tasks with it before, but in
2007 I had a small job where I had to develop on machines across the
ocean, with only vim
installed. As latency was high (and mosh
didn’t exist yet), efficient use of Vim was essential. After the
summer of 2007, I was fairly familiar with Vim. I still use Emacs for
my main editing and programming tasks, but on remote machines and for
small edit tasks I primarily use Vim.
I always found reading
other
people’s
.vimrc
(and analyses)
interesting, so today I’ll share mine.
Well, I actually have two .vimrc
, a “big” one (233 lines) and a minimal one.
Why do you need a .vimrc
at all? Well, since Vim 8, a defaults.vim
is loaded else with some annoying settings (such as enabling mouse and
colors), so you have two options:
Run Vim as vi
, but then you are in compatible mode which disables
some useful things.
Create a .vimrc
—even if it’s empty—to start vim in
non-compatible mode.
But then I can also can fetch my minimal one and set some defaults I prefer.
My minimal .vimrc
is only 64 bytes long and does 80% of the job, so
let’s dissect it:
set nocp bs=2 cot= hid is ru sm t_te= t_ti= vb wim=longest,list
As you can see, it only sets a few things in a single set
command:
nocp
: nocompatible
; disable Vi compatible mode and enable a bunch of
features. This is superfluous if you save the file as .vimrc
,
but not if you want to try it with vim -u .vimrc.minimal
.
bs=2
: backspace=indent,eol,start
; allow backspace to delete the autoindent,
linebreaks or the start of insert mode. This is just convenient sometimes.
cot=
: completeopt=
; this disables the popup menu for, e.g.,
^X^F
(filename completion). I never want popups to hide the text
in my buffer.
hid
: hidden
; this allows having open buffers that are not
displayed, and really should be the default.
is
: incsearch
; search as you type, pretty convenient.
ru
: ruler
; show the current line number.
sm
: showmatch
; quickly jump to the matching open bracket
when typing the closing bracket.
t_te= t_ti=
; unset the terminfo sequences that usually (de-)activate
the alternate screen—I want the screen contents to stay after editing.
vb
: visualbell
: flash the display instead of beeping.
wim=longest,list
: wildmode=longest,list
:
In command-line mode,
complete the longest common string, then list alternatives.
This is the default in bash
/readline
and how I configured my zsh
.
So, in summary: 5 options enable features, 5 options disable annoying defaults. All in all, I think Vim has pretty good defaults.
NP: Pearl Jam—Buckle Up
For quite some time—as my research will show, March 2016—, I have
been annoyed by a directory named --help
showing up in my home
directory (and sometimes in others).
It’s just an empty, innocent directory with a weird name.
Removed by a simple run of rmdir ./--help
.
Yet, it would turn up again.
Sometimes soon, sometimes it took a few weeks.
I had no idea where it came from.
Obviously, a simple mkdir --help
just print’s the mkdir
help:
Usage: mkdir [OPTION]... DIRECTORY...
Create the DIRECTORY(ies), if they do not already exist.
...
I thought, maybe some program was called once with --help
but
didn’t understand it, yet stored it somewhere and would create it when
run again. I suspected many things, especially applications I don’t use that
often, like Gimp or Transmission. I grepped all dotfiles in $HOME
for --help
. To no avail.
I decided I had to track this down.
My first thought was to use
fatrace
,
which logs all file accesses. But fatrace
doesn’t register
directory creation (the fanotify
API does, I think).
I didn’t know what to do, and left the problem alone for some time.
The --help
directory kept reappearing.
Some time later, I read a book on eBPF, and decided I can log all mkdir(2) calls with it, globally. (I also think I tried this with SystemTap before, but I’m not sure anymore.)
I wrote a bpftrace
script called mkdirsnoop
, a variant of opensnoop
.
It would print all mkdir(2) calls and what program ran it, system wide.
I ran it a lot, but not consistently.
Yesterday, it finally triggered! I tweeted:
I’m really flipping the table.
For months, I’ve been trying to figure out what occasionally creates “–help” folders in my $HOME. I have no idea why it happens.
I wrote a bpftrace script to find the culprit.
Today it triggered.
It says, it’s mkdir(1).
(╯°□しろいしかく°)╯( ┻━┻
If it was mkdir(1), it must have been created by a script. Gimp and Transmission were acquitted of charge.
Julien Kirch proposed to put a different mkdir
into my $PATH
,
which I think was a smart idea. I wrote this:
#!/bin/sh
printf '%s\n' "mkdir called from $$ at $(date)" >> /tmp/mkdirlog
pstree -sap $$ >> /tmp/mkdirlog
exec /usr/bin/mkdir "$@"
Very quickly, the script triggered, and I saw:
runit,1
`-sh,30996 -c urxvt
`-urxvt,30997
`-zsh,30998
`-zsh,31055
`-mkdir,31058 /home/leah/bin/mkdir --help
`-pstree,31060 -sap 31058
So it was actually zsh
calling mkdir --help
.
(Or a zsh
script.)
But there was no directory --help
.
Because calling mkdir --help
does not create a directory,
instead printing the help.
Jannis Harder told me that the zsh completion for mkdir
would run
mkdir --help
(to see if it’s the GNU variant), which I could verify.
But it didn’t explain the --help
directory.
However, I had something to track down now.
Using my extrace, I would
log all runs of mkdir
with a --help
argument, and at some point
I found:
mkdir -p -- --help
Mysterious. I grepped my dotfiles again and found the unsuspicious
function mkcd
:
# mkcd -- mkdir and cd at once
mkcd() { mkdir -p -- "1ドル" && cd -- "1ドル" }
This is a helper function I use a lot. But I don’t call it with
--help
of course, and then wonder for 4 years why I do that.
Well I don’t. But zsh
does, because I also had:
compdef mkcd=mkdir
This was a quick shortcut to complete mkdir
’s arguments (only
directories) also for mkcd
. I added it in 2013. Even before I added
the -p
flag in 2016.
Quickly, I verified that mkcd <TAB>
would create a --help
directory. But only if the completion wasn’t loaded already,
e.g. when I didn’t run mkdir <TAB>
before. This explains why
the directory only appeared sporadically.
I quickly rewrote the completion:
_mkcd() { _path_files -/ }
compdef _mkcd mkcd
And another mystery of my setup has been solved. Case closed.
NP: Pearl Jam—Take The Long Way