leah blogs: May 2020

11may2020 · A minimal .vimrc

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

02may2020 · The case of the mysterious --help directory

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

Copyright © 2004–2022